Пример #1
0
    def message_forward(self,
                        cr,
                        uid,
                        model,
                        thread_ids,
                        msg,
                        email_error=False,
                        context=None):
        """Sends an email to all people following the given threads.
           The emails are forwarded immediately, not queued for sending,
           and not archived.

        :param str model: thread model
        :param list thread_ids: ids of the thread records
        :param msg: email.message.Message object to forward
        :param email_error: optional email address to notify in case
                            of any delivery error during the forward.
        :return: True
        """
        model_pool = self.pool.get(model)
        smtp_server_obj = self.pool.get('ir.mail_server')
        for res in model_pool.browse(cr, uid, thread_ids, context=context):
            if hasattr(model_pool, 'message_thread_followers'):
                followers = model_pool.message_thread_followers(
                    cr, uid, [res.id])[res.id]
            else:
                followers = self.message_thread_followers(cr, uid,
                                                          [res.id])[res.id]
            message_followers_emails = to_email(','.join(
                filter(None, followers)))
            message_recipients = to_email(','.join(
                filter(None, [
                    decode(msg['From']),
                    decode(msg['To']),
                    decode(msg['Cc'])
                ])))
            forward_to = [
                i for i in message_followers_emails
                if (i and (i not in message_recipients))
            ]
            if forward_to:
                # TODO: we need an interface for this for all types of objects, not just leads
                if hasattr(res, 'section_id'):
                    del msg['Reply-To']
                    msg['Reply-To'] = res.section_id.reply_to

                smtp_from, = to_email(msg['From'])
                del msg['From'], msg['To'], msg['Cc'], msg['Message-Id']
                msg['From'] = smtp_from
                msg['To'] = ", ".join(forward_to)
                msg['Message-Id'] = tools.generate_tracking_message_id(res.id)
                if not smtp_server_obj.send_email(cr, uid,
                                                  msg) and email_error:
                    subj = msg['Subject']
                    del msg['Subject'], msg['To'], msg['Cc']
                    msg['Subject'] = _('[OpenERP-Forward-Failed] %s') % subj
                    msg['To'] = email_error
                    smtp_server_obj.send_email(cr, uid, msg)
        return True
Пример #2
0
 def _message_find_user_id(self, cr, uid, message, context=None):
     from_local_part = tools.email_split(decode(message.get('From')))[0]
     # FP Note: canonification required, the minimu: .lower()
     user_ids = self.pool.get('res.users').search(cr, uid, ['|',
         ('login', '=', from_local_part),
         ('email', '=', from_local_part)], context=context)
     return user_ids[0] if user_ids else uid
Пример #3
0
    def message_forward(self, cr, uid, model, thread_ids, msg, email_error=False, context=None):
        """Sends an email to all people following the given threads.
           The emails are forwarded immediately, not queued for sending,
           and not archived.

        :param str model: thread model
        :param list thread_ids: ids of the thread records
        :param msg: email.message.Message object to forward
        :param email_error: optional email address to notify in case
                            of any delivery error during the forward.
        :return: True
        """
        model_pool = self.pool.get(model)
        smtp_server_obj = self.pool.get('ir.mail_server')
        for res in model_pool.browse(cr, uid, thread_ids, context=context):
            if hasattr(model_pool, 'message_thread_followers'):
                followers = model_pool.message_thread_followers(cr, uid, [res.id])[res.id]
            else:
                followers = self.message_thread_followers(cr, uid, [res.id])[res.id]
            message_followers_emails = to_email(','.join(filter(None, followers)))
            message_recipients = to_email(','.join(filter(None,
                                                                       [decode(msg['From']),
                                                                        decode(msg['To']),
                                                                        decode(msg['Cc'])])))
            forward_to = [i for i in message_followers_emails if (i and (i not in message_recipients))]
            if forward_to:
                # TODO: we need an interface for this for all types of objects, not just leads
                if hasattr(res, 'section_id'):
                    del msg['Reply-To']
                    msg['Reply-To'] = res.section_id.reply_to

                smtp_from, = to_email(msg['From'])
                del msg['From'], msg['To'], msg['Cc'], msg['Message-Id']
                msg['From'] = smtp_from
                msg['To'] =  ", ".join(forward_to)
                msg['Message-Id'] = tools.generate_tracking_message_id(res.id)
                if not smtp_server_obj.send_email(cr, uid, msg) and email_error:
                    subj = msg['Subject']
                    del msg['Subject'], msg['To'], msg['Cc']
                    msg['Subject'] = _('[OpenERP-Forward-Failed] %s') % subj
                    msg['To'] = email_error
                    smtp_server_obj.send_email(cr, uid, msg)
        return True
Пример #4
0
    def message_parse(self, cr, uid, message, save_original=False, context=None):
        """Parses a string or email.message.Message representing an
           RFC-2822 email, and returns a generic dict holding the
           message details.

           :param message: the message to parse
           :type message: email.message.Message | string | unicode
           :param bool save_original: whether the returned dict
               should include an ``original`` attachment containing
               the source of the message
           :rtype: dict
           :return: A dict with the following structure, where each
                    field may not be present if missing in original
                    message::

                    { 'message_id': msg_id,
                      'subject': subject,
                      'from': from,
                      'to': to,
                      'cc': cc,
                      'body': unified_body,
                      'attachments': [('file1', 'bytes'),
                                      ('file2', 'bytes')}
                    }
        """
        msg_dict = {}
        if not isinstance(message, Message):
            if isinstance(message, unicode):
                # Warning: message_from_string doesn't always work correctly on unicode,
                # we must use utf-8 strings here :-(
                message = message.encode('utf-8')
            message = email.message_from_string(message)

        message_id = message['message-id']
        if not message_id:
            # Very unusual situation, be we should be fault-tolerant here
            message_id = "<%s@localhost>" % time.time()
            _logger.debug('Parsing Message without message-id, generating a random one: %s', message_id)
        msg_dict['message_id'] = message_id

        if 'Subject' in message:
            msg_dict['subject'] = decode(message.get('Subject'))

        # Envelope fields not stored in  mail.message but made available for message_new()
        msg_dict['from'] = decode(message.get('from'))
        msg_dict['to'] = decode(message.get('to'))
        msg_dict['cc'] = decode(message.get('cc'))

        if 'From' in message:
            author_ids = self._message_find_partners(cr, uid, message, ['From'], context=context)
            if author_ids:
                msg_dict['author_id'] = author_ids[0]
        partner_ids = self._message_find_partners(cr, uid, message, ['From', 'To', 'Cc'], context=context)
        msg_dict['partner_ids'] = partner_ids

        if 'Date' in message:
            date_hdr = decode(message.get('Date'))
            # convert from email timezone to server timezone
            date_server_datetime = dateutil.parser.parse(date_hdr).astimezone(pytz.timezone(tools.get_server_timezone()))
            date_server_datetime_str = date_server_datetime.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
            msg_dict['date'] = date_server_datetime_str

        if 'In-Reply-To' in message:
            parent_ids = self.pool.get('mail.message').search(cr, uid, [('message_id', '=', decode(message['In-Reply-To']))])
            if parent_ids:
                msg_dict['parent_id'] = parent_ids[0]

        if 'References' in message and 'parent_id' not in msg_dict:
            parent_ids = self.pool.get('mail.message').search(cr, uid, [('message_id', 'in',
                                                                         [x.strip() for x in decode(message['References']).split()])])
            if parent_ids:
                msg_dict['parent_id'] = parent_ids[0]

        msg_dict['body'], msg_dict['attachments'] = self._message_extract_payload(message)
        return msg_dict
Пример #5
0
 def _message_find_partners(self, cr, uid, message, header_fields=['From'], context=None):
     """ Find partners related to some header fields of the message. """
     s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)])
     return [partner_id for email in tools.email_split(s)
             for partner_id in self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)]