import odoorpc
import base64
import os
from datetime import datetime
class OdooAttachmentDownloader:
def __init__(self, host, port, database, username, password):
self.host = host
self.port = port
self.database = database
self.username = username
self.password = password
self.odoo = None
def connect(self):
"""连接到Odoo服务器"""
try:
self.odoo = odoorpc.ODOO(self.host, port=self.port)
self.odoo.login(self.database, self.username, self.password)
print("成功连接到Odoo服务器")
return True
except Exception as e:
print(f"连接失败: {e}")
return False
def download_attachments_by_record(self, model_name, record_id, save_dir="./attachments"):
"""
下载指定单据的所有附件
Args:
model_name: 模型名称,如 'sale.order', 'account.move'
record_id: 记录ID
save_dir: 保存目录
"""
if not self.odoo:
print("请先连接到Odoo服务器")
return []
os.makedirs(save_dir, exist_ok=True)
try:
Attachment = self.odoo.env['ir.attachment']
attachment_ids = Attachment.search([
('res_model', '=', model_name),
('res_id', '=', record_id)
])
if not attachment_ids:
print(f"未找到模型 {model_name} 记录 {record_id} 的附件")
return []
attachments = Attachment.read(attachment_ids, ['name', 'datas', 'mimetype', 'create_date'])
downloaded_files = []
for attachment in attachments:
if attachment.get('datas'):
file_data = base64.b64decode(attachment['datas'])
file_name = attachment['name']
save_path = os.path.join(save_dir, file_name)
counter = 1
while os.path.exists(save_path):
name, ext = os.path.splitext(file_name)
save_path = os.path.join(save_dir, f"{name}_{counter}{ext}")
counter += 1
with open(save_path, 'wb') as f:
f.write(file_data)
file_info = {
'file_path': save_path,
'file_name': os.path.basename(save_path),
'original_name': file_name,
'mime_type': attachment.get('mimetype', ''),
'create_date': attachment.get('create_date', ''),
'size': len(file_data)
}
downloaded_files.append(file_info)
print(f"✓ 已下载: {file_info['file_name']} ({file_info['size']} bytes)")
else:
print(f"⚠ 附件 {attachment['name']} 无数据内容")
print(f"\n总共下载了 {len(downloaded_files)} 个文件到目录: {save_dir}")
return downloaded_files
except Exception as e:
print(f"下载附件时出错: {e}")
return []
def main():
downloader = OdooAttachmentDownloader(
host='10.86.113.88',
port=8069,
database='odoo17',
username='admin',
password='123123sdt'
)
if downloader.connect():
files = downloader.download_attachments_by_record(
model_name='cbd.huohao.price.form.head',
record_id=659,
save_dir='./downloaded_attachments'
)
for file in files:
print(f"文件: {file['file_name']}, 大小: {file['size']} bytes")
if __name__ == "__main__":
main()