diff --git a/msg_attachments_to_mail_message/models/ir_attachment.py b/msg_attachments_to_mail_message/models/ir_attachment.py index 7bfc927..1dad193 100644 --- a/msg_attachments_to_mail_message/models/ir_attachment.py +++ b/msg_attachments_to_mail_message/models/ir_attachment.py @@ -1,21 +1,28 @@ +"""This module extends ir.attachment model to handle MSG file attachments. + +It provides functionality to convert MSG files (Outlook messages) to EML format +and process them as regular email messages in Odoo. This includes extracting +attachments, handling headers, and creating proper mail.message records. +""" + from odoo import models, api, fields from odoo.tools import html_sanitize -import extract_msg import base64 import logging from odoo.tools.translate import _ -from email.message import EmailMessage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.mime.base import MIMEBase from email import encoders -import lxml.html import re from odoo.tools import email_normalize, email_split from io import BytesIO +import extract_msg + _logger = logging.getLogger(__name__) + _msg_import_logger = logging.getLogger("msg.import") handler = logging.FileHandler("/var/log/odoo/msg_import.log") formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") @@ -23,7 +30,6 @@ handler.setFormatter(formatter) _msg_import_logger.addHandler(handler) _msg_import_logger.setLevel(logging.ERROR) - class IrAttachment(models.Model): _inherit = "ir.attachment" @@ -40,7 +46,7 @@ class IrAttachment(models.Model): self.ensure_one() # Check if it's an MSG file - is_msg = self.mimetype == "application/vnd.ms-outlook" or ( + is_msg = self.with_context().sudo().mimetype in ['application/vnd.ms-outlook', 'application/x-ole-storage'] or ( self.name and self.name.lower().endswith(".msg") ) @@ -51,15 +57,18 @@ class IrAttachment(models.Model): max_size = int( self.env["ir.config_parameter"] .sudo() - .get_param("msg_attachments.max_file_size", "25") + .get_param("msg_attachments.max_file_size") or 25 ) file_size_mb = ( len(self.datas) * 3 / 4 / 1024 / 1024 ) # Convert from base64 to MB if file_size_mb > max_size: + log_errors = self.env['ir.config_parameter'].sudo().get_param('msg_attachments.log_msg_error', 'False').lower() == 'true' + log_file = self.env['ir.config_parameter'].sudo().get_param('msg_attachments.log_file_path') error_msg = f"File size error for {self.name}: File size ({file_size_mb:.2f} MB) exceeds maximum allowed size ({max_size} MB)" - _msg_import_logger.error(error_msg) + if log_errors and log_file: + _msg_import_logger.error(error_msg) self._notify_error( "File Size Error", _("The MSG file is too large. Maximum allowed size is %s MB") @@ -164,7 +173,7 @@ class IrAttachment(models.Model): from_partner = None elif len(from_partners) > 1: if current_partner: - # Chercher parmi les contacts liés à la compagnie de l'objet courant + # Search among contacts linked to the current object's company company = current_partner.commercial_partner_id company_contacts = from_partners.filtered( lambda p: p.commercial_partner_id == company @@ -252,6 +261,56 @@ class IrAttachment(models.Model): if msg_file.body: body = msg_file.body + # Check if metadata should be included + show_metadata = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("msg_attachments.format_metadata", "True") + .lower() + == "true" + ) + + if show_metadata: + # Format the metadata section + metadata_html = f""" +
| From: | +{html_sanitize(msg_file.sender or "")} | +
| Date: | +{msg_file.date.strftime("%Y-%m-%d %H:%M:%S") if msg_file.date else "Unknown"} | +
| To: | +{html_sanitize(msg_file.to or "")} | +
| CC: | +{html_sanitize(msg_file.cc)} | +
| Message-ID: | +{html_sanitize(msg_file.header["message-id"])} | +