From 45ab7611a329062c690c14d36e2874b25660cbb3 Mon Sep 17 00:00:00 2001 From: xtremxpert Date: Wed, 22 Jan 2025 10:11:03 -0500 Subject: [PATCH] need just fix rendering --- .../models/ir_attachment.py | 187 ++++-------------- 1 file changed, 43 insertions(+), 144 deletions(-) diff --git a/msg_attachments_to_mail_message/models/ir_attachment.py b/msg_attachments_to_mail_message/models/ir_attachment.py index 159807e..38e9556 100644 --- a/msg_attachments_to_mail_message/models/ir_attachment.py +++ b/msg_attachments_to_mail_message/models/ir_attachment.py @@ -50,7 +50,7 @@ class IrAttachment(models.Model): return ' '.join(str(value).split()) def process_msg_as_email(self): - """Convert MSG file to standard email format and process it using Odoo's mail module.""" + """Convert MSG file to RFC822 email format and process it using Odoo's mail module.""" self.ensure_one() _logger.info('Starting MSG processing for file: %s (model: %s, res_id: %s)', self.name, self.res_model, self.res_id) @@ -60,16 +60,6 @@ class IrAttachment(models.Model): self._notify_error('Invalid File', _('The selected file is not a valid MSG file')) return False - - if not self.datas: - try: - # Try to reload data from filestore - self.datas = self.datas - except Exception as e: - _logger.error('Failed to read file %s from filestore: %s', self.name, str(e)) - self._notify_error('File Access Error', - _('The MSG file could not be read from the filestore. The file may have been moved or deleted.')) - return False try: # Read the MSG file @@ -81,86 +71,58 @@ class IrAttachment(models.Model): # Convert MSG to email format email_msg = EmailMessage() + + # Add headers email_msg['Subject'] = self._clean_header_value(msg_file.subject) or _("No Subject") email_msg['From'] = self._clean_header_value(msg_file.sender) email_msg['To'] = self._clean_header_value(msg_file.to) email_msg['Cc'] = self._clean_header_value(msg_file.cc) - email_msg['Date'] = msg_file.date.strftime('%a, %d %b %Y %H:%M:%S %z') if msg_file.date else '' - email_msg['References'] = self._clean_header_value(msg_file.header.get('References', '')) - email_msg['In-Reply-To'] = self._clean_header_value(msg_file.header.get('In-Reply-To', '')) - email_msg['Message-ID'] = self._clean_header_value(msg_file.header.get('Message-Id', '')) + email_msg['Date'] = msg_file.date.strftime('%a, %d %b %Y %H:%M:%S %z') if msg_file.date else formatdate(localtime=True) - # Add X-Headers to force message association - if self.res_model and self.res_id: - email_msg['X-Odoo-Objects'] = f'{self.res_model}-{self.res_id}' + # Add original MSG headers if present + for header in ['Message-ID', 'In-Reply-To', 'References']: + if header.lower() in msg_file.header: + email_msg[header] = self._clean_header_value(msg_file.header[header.lower()]) # Set the body if msg_file.body: _logger.info('Processing message body') - # Convert [cid:xxx] to proper HTML img tags body = msg_file.body + # Convert [cid:xxx] to proper HTML img tags if needed cid_pattern = r'\[cid:([^\]]+)\]' body = re.sub(cid_pattern, r'', body) - # Nettoyer le HTML si nécessaire + # Clean HTML if needed if ' cid = attachment.content_id.strip('<>') headers['Content-ID'] = f'<{cid}>' - - # Create Odoo attachment for all attachments, not just those with CID - try: - odoo_attachment = self.env['ir.attachment'].create({ - 'name': filename or 'unknown.bin', - 'datas': base64.b64encode(attachment.data), - 'mimetype': attachment.mimetype or 'application/octet-stream', - 'res_model': self.res_model, - 'res_id': self.res_id, - }) - _logger.info('Created Odoo attachment: %s (ID: %s)', - odoo_attachment.name, odoo_attachment.id) - - attachment_ids.append(odoo_attachment.id) - if headers.get('Content-ID'): - attachment_mapping[cid] = odoo_attachment.id - except Exception as e: - _logger.error('Failed to create attachment %s: %s', filename, str(e)) email_msg.add_attachment( attachment.data, maintype=maintype, subtype=subtype, - filename=filename or 'unknown.bin', + filename=filename, headers=headers ) @@ -168,7 +130,7 @@ class IrAttachment(models.Model): thread_model = self.env[self.res_model] if self.res_model else self.env['mail.thread'] _logger.info('Using thread model: %s', thread_model._name) - # Forcer le contexte pour la création du message + # Set context for message creation context = { 'default_model': self.res_model, 'default_res_id': self.res_id, @@ -178,93 +140,30 @@ class IrAttachment(models.Model): 'mail_create_force_model': self.res_model, 'mail_thread_quote': False, } - _logger.info('Setting context for message creation: %s', context) - thread_model = thread_model.with_context(**context) - # Créer directement le message si nous avons un modèle et un ID - if self.res_model and self.res_id: - _logger.info('Creating message directly for model %s with ID %s', - self.res_model, self.res_id) - # Trouver l'auteur du message - author_id = False - if msg_file.sender: - email_normalized = email_normalize(msg_file.sender) - _logger.info('Looking for partner with email: %s', email_normalized) - partner = self.env['res.partner'].sudo().search([ - ('email_normalized', '=', email_normalized) - ], limit=1) - if partner: - author_id = partner.id - _logger.info('Found partner: %s (ID: %s)', partner.name, partner.id) - else: - _logger.info('No partner found for email %s', email_normalized) - - # Créer le message directement - try: - vals = { - 'subject': msg_file.subject or _("No Subject"), - 'body': body if msg_file.body else '', - 'email_from': msg_file.sender, - 'author_id': author_id, - 'message_type': 'email', - 'model': self.res_model, - 'res_id': self.res_id, - 'attachment_ids': [(6, 0, attachment_ids)], - } - _logger.info('Creating mail.message with values: %s', vals) - message = self.env['mail.message'].create(vals) - _logger.info('Created message successfully: ID %s', message.id) - - # Marquer le fichier MSG comme traité - self.write({ - 'description': _('Processed as email on %s') % fields.Datetime.now(), - 'msg_processed': True, - 'mail_message_id': message.id, - }) - _logger.info('MSG file marked as processed') - - return message.id - except Exception as e: - _logger.error('Failed to create message: %s', str(e), exc_info=True) - raise - else: - _logger.info('No model/ID available, falling back to message_process') - # Si nous n'avons pas de modèle/ID, utiliser message_process - thread_id = thread_model.message_process( - model=self.res_model, - message=email_msg.as_bytes(), - custom_values={ - 'res_id': self.res_id, - 'model': self.res_model, - 'msg_attachment_id': self.id, - }, - thread_id=self.res_id - ) - - if thread_id: - _logger.info('Message processed successfully, thread_id: %s', thread_id) - # Trouver le message créé - message = self.env['mail.message'].search([ - ('model', '=', self.res_model), - ('res_id', '=', thread_id) - ], order='id desc', limit=1) - - if message: - _logger.info('Found created message: ID %s', message.id) - else: - _logger.warning('No message found after processing') - - # Marquer le fichier MSG comme traité - self.write({ - 'description': _('Processed as email on %s') % fields.Datetime.now(), - 'msg_processed': True, - 'mail_message_id': message.id if message else False, - }) - _logger.info('MSG file marked as processed') - else: - _logger.error('message_process failed to create thread_id') - + # Process the email using Odoo's standard message_process + thread_id = thread_model.with_context(**context).message_process( + model=self.res_model, + message=email_msg.as_bytes(), + custom_values={ + 'res_id': self.res_id, + 'model': self.res_model, + 'msg_attachment_id': self.id, + }, + thread_id=self.res_id + ) + + if thread_id: + _logger.info('Message processed successfully, thread_id: %s', thread_id) + # Mark MSG as processed + self.write({ + 'description': _('Processed as email on %s') % fields.Datetime.now(), + 'msg_processed': True, + }) return thread_id + else: + _logger.error('message_process failed to create thread_id') + return False except Exception as e: _logger.error('Error processing MSG file %s: %s', self.name, str(e), exc_info=True)