diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py index 54bf2a93225..28a9c66baa5 100644 --- a/addons/mail/mail_followers.py +++ b/addons/mail/mail_followers.py @@ -105,7 +105,9 @@ class mail_notification(osv.Model): if towrite.get('subject', False): towrite['subject'] = msg.name_get(cr, uid, [msg.id], context=context)[0][1] towrite['message_id'] = msg.id - self.pool.get('mail.mail').create(cr, uid, towrite, context=context) + mail_message_obj = self.pool.get('mail.mail') + newid = mail_message_obj.create(cr, uid, towrite, context=context) + mail_message_obj.send(cr, uid, [newid], context=context) return True diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index cfc4946a94f..cae27e99a55 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -50,94 +50,6 @@ class mail_mail(osv.Model): 'content_subtype': 'plain', } - # FP Note: should we use a dict instead ? - def schedule_with_attach(self, cr, uid, email_from, email_to, subject, body, model=False, type='email', - email_cc=None, reply_to=False, partner_ids=None, attachments=None, - message_id=False, references=False, res_id=False, content_subtype='plain', - headers=None, mail_server_id=False, auto_delete=False, context=None): - """ Schedule sending a new email message, to be sent the next time the - mail scheduler runs, or the next time :meth:`process_email_queue` is - called explicitly. - - :param string email_from: sender email address - :param list email_to: list of recipient addresses (to be joined with commas) - :param string subject: email subject (no pre-encoding/quoting necessary) - :param string body: email body, according to the ``content_subtype`` - (by default, plaintext). If html content_subtype is used, the - message will be automatically converted to plaintext and wrapped - in multipart/alternative. - :param list email_cc: optional list of string values for CC header - (to be joined with commas) - :param string model: optional model name of the document this mail - is related to (this will also be used to generate a tracking id, - used to match any response related to the same document) - :param int res_id: optional resource identifier this mail is related - to (this will also be used to generate a tracking id, used to - match any response related to the same document) - :param string reply_to: optional value of Reply-To header - :param partner_ids: destination partner_ids - :param string content_subtype: optional mime content_subtype for - the text body (usually 'plain' or 'html'), must match the format - of the ``body`` parameter. Default is 'plain', making the content - part of the mail "text/plain". - :param dict attachments: map of filename to filecontents, where - filecontents is a string containing the bytes of the attachment - :param dict headers: optional map of headers to set on the outgoing - mail (may override the other headers, including Subject, - Reply-To, Message-Id, etc.) - :param int mail_server_id: optional id of the preferred outgoing - mail server for this mail - :param bool auto_delete: optional flag to turn on auto-deletion of - the message after it has been successfully sent (default to False) - """ - if context is None: - context = {} - if attachments is None: - attachments = {} - if partner_ids is None: - partner_ids = [] - attachment_obj = self.pool.get('ir.attachment') - for param in (email_to, email_cc): - if param and not isinstance(param, list): - param = [param] - partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id - msg_vals = { - 'subject': subject, - 'date': fields.datetime.now(), - 'author_id': partner_id, - 'model': model, - 'res_id': res_id, - 'type': type, - 'body': body if content_subtype != 'html' else False, - 'body_html': body if content_subtype == 'html' else False, - 'email_from': email_from, - 'email_to': email_to and ','.join(email_to) or '', - 'email_cc': email_cc and ','.join(email_cc) or '', - 'partner_ids': partner_ids, - 'reply_to': reply_to, - 'message_id': message_id, - 'references': references, - 'content_subtype': content_subtype, - 'headers': headers, # serialize the dict on the fly - 'mail_server_id': mail_server_id, - 'state': 'outgoing', - 'auto_delete': auto_delete - } - email_msg_id = self.create(cr, uid, msg_vals, context) - msg = self.browse(cr, uid, email_msg_id, context) - for fname, fcontent in attachments.iteritems(): - attachment_data = { - 'name': fname, - 'datas_fname': fname, - 'datas': fcontent and fcontent.encode('base64'), - 'res_model': 'mail.message', - 'res_id': msg.mail_message_id.id, - } - # FP Note: what's this ??? - # if context.has_key('default_type'): - # del context['default_type'] - return email_msg_id - def mark_outgoing(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state':'outgoing'}, context=context) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 544ebf20a8e..d9dfc4a474e 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -552,7 +552,7 @@ class mail_thread(osv.Model): fcontent = fcontent.encode('utf-8') data_attach = { 'name': fname, - 'datas': base64.b64encode(str(fcontent)), + 'datas': fcontent, 'datas_fname': fname, 'description': _('email attachment'), } diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 072e68748a1..7e33e4152f0 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -254,6 +254,7 @@ class mail_compose_message(osv.TransientModel): ''' if context is None: context = {} + # composition wizard options email_mode = context.get('email_mode') formatting = context.get('formatting') @@ -264,70 +265,32 @@ class mail_compose_message(osv.TransientModel): # attachments attachment = {} for attach in mail_wiz.attachment_ids: - attachment[attach.datas_fname] = attach.datas and attach.datas.decode('base64') + attachment[attach.datas_fname] = attach.datas and attach.datas or False # default values, according to the wizard options subject = mail_wiz.subject if formatting else False - content_subtype = 'html' if formatting else 'plain' - type = 'email' if email_mode else 'comment' - state = 'outgoing' if email_mode else False partner_ids = [partner.id for partner in mail_wiz.dest_partner_ids] - references = None - headers = {} body = mail_wiz.body_html if content_subtype == 'html' else mail_wiz.body + active_model_pool = self.pool.get(active_model) + # get model, active_ids, and check if model is openchatter-enabled if mass_mail_mode and context.get('active_ids') and context.get('active_model'): active_ids = context['active_ids'] active_model = context['active_model'] elif mass_mail_mode: active_model = mail_wiz.model - active_model_pool = self.pool.get(active_model) active_ids = active_model_pool.search(cr, uid, ast.literal_eval(mail_wiz.filter_id.domain), context=ast.literal_eval(mail_wiz.filter_id.context)) else: active_model = mail_wiz.model active_ids = [mail_wiz.res_id] - active_model_pool = self.pool.get(active_model) - mail_thread_enabled = hasattr(active_model_pool, 'message_append') - if context.get('mail.compose.message.mode') == 'mass_mail': - # Mass mailing: must render the template patterns - for active_id in active_ids: - rendered_subject = self.render_template(cr, uid, subject, active_model, active_id) - rendered_body_html = self.render_template(cr, uid, mail_wiz.body_html, active_model, active_id) - rendered_body = self.render_template(cr, uid, mail_wiz.body, active_model, active_id) - email_from = self.render_template(cr, uid, mail_wiz.email_from, active_model, active_id) - email_to = self.render_template(cr, uid, mail_wiz.email_to, active_model, active_id) - email_cc = self.render_template(cr, uid, mail_wiz.email_cc, active_model, active_id) - reply_to = self.render_template(cr, uid, mail_wiz.reply_to, active_model, active_id) - - # in mass-mailing mode we only schedule the mail for sending, it will be - # processed as soon as the mail scheduler runs. - if mail_thread_enabled: - active_model_pool.message_append(cr, uid, [active_id], rendered_subject, rendered_body, rendered_body_html, - type=type, content_subtype=content_subtype, state=state, partner_ids=partner_ids, - email_from=email_from, email_to=email_to, email_cc=email_cc, - reply_to=reply_to, references=references, attachments=attachment, headers=headers, context=context) - else: - mail_message_obj.schedule_with_attach(cr, uid, email_from, mail_tools_to_email(email_to), subject, rendered_body, - model=mail_wiz.model, email_cc=mail_tools_to_email(email_cc), reply_to=reply_to, - attachments=attachment, references=references, res_id=active_id, partner_ids=partner_ids, - content_subtype=mail_wiz.content_subtype, headers=headers, context=context) - else: - # normal mode - no mass-mailing - if mail_thread_enabled: - msg_ids = active_model_pool.message_append(cr, uid, active_ids, subject, mail_wiz.body, mail_wiz.body_html, - type=type, content_subtype=content_subtype, state=state, partner_ids=partner_ids, - email_from=mail_wiz.email_from, email_to=mail_wiz.email_to, email_cc=mail_wiz.email_cc, - reply_to=mail_wiz.reply_to, references=references, attachments=attachment, headers=headers, context=context) - else: - msg_ids = [mail_message_obj.schedule_with_attach(cr, uid, mail_wiz.email_from, mail_tools_to_email(mail_wiz.email_to), subject, mail_wiz.body, - type=type, model=mail_wiz.model, email_cc=mail_tools_to_email(mail_wiz.email_cc), reply_to=mail_wiz.reply_to, - attachments=attachment, references=references, res_id=int(mail_wiz.res_id), partner_ids=partner_ids, - content_subtype=mail_wiz.content_subtype, headers=headers, context=context)] - # in normal mode, we send the email immediately, as the user expects us to (delay should be sufficiently small) - if type == 'email': - mail_message_obj.send(cr, uid, msg_ids, context=context) + for active_id in active_ids: + if context.get('mail.compose.message.mode') == 'mass_mail': + subject = self.render_template(cr, uid, subject, active_model, active_id) + body = self.render_template(cr, uid, mail_wiz.body_html, active_model, active_id) + active_model_pool.message_append(cr, uid, active_id, body, subject, 'comment', + attachments=attachments, context=context) return {'type': 'ir.actions.act_window_close'}