[FIX] mail: read ir.config_parameter with SUPERUSER_ID
[odoo/odoo.git] / addons / mail / mail_message.py
index e3a1ae9..a2d3828 100644 (file)
@@ -25,6 +25,7 @@ import re
 from openerp import tools
 
 from email.header import decode_header
+from email.utils import formataddr
 from openerp import SUPERUSER_ID
 from openerp.osv import osv, orm, fields
 from openerp.tools import html_email_clean
@@ -77,7 +78,8 @@ class mail_message(osv.Model):
 
     def default_get(self, cr, uid, fields, context=None):
         # protection for `default_type` values leaking from menu action context (e.g. for invoices)
-        if context and context.get('default_type') and context.get('default_type') not in self._columns['type'].selection:
+        if context and context.get('default_type') and context.get('default_type') not in [
+                val[0] for val in self._columns['type'].selection]:
             context = dict(context, default_type=None)
         return super(mail_message, self).default_get(cr, uid, fields, context=context)
 
@@ -100,7 +102,7 @@ class mail_message(osv.Model):
     def _get_to_read(self, cr, uid, ids, name, arg, context=None):
         """ Compute if the message is unread by the current user. """
         res = dict((id, False) for id in ids)
-        partner_id = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+        partner_id = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
         notif_obj = self.pool.get('mail.notification')
         notif_ids = notif_obj.search(cr, uid, [
             ('partner_id', 'in', [partner_id]),
@@ -119,7 +121,7 @@ class mail_message(osv.Model):
     def _get_starred(self, cr, uid, ids, name, arg, context=None):
         """ Compute if the message is unread by the current user. """
         res = dict((id, False) for id in ids)
-        partner_id = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+        partner_id = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
         notif_obj = self.pool.get('mail.notification')
         notif_ids = notif_obj.search(cr, uid, [
             ('partner_id', 'in', [partner_id]),
@@ -201,10 +203,10 @@ class mail_message(osv.Model):
 
     def _get_default_from(self, cr, uid, context=None):
         this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
-        if this.alias_domain:
-            return '%s <%s@%s>' % (this.name, this.alias_name, this.alias_domain)
+        if this.alias_name and this.alias_domain:
+            return formataddr((this.name, '%s@%s' % (this.alias_name, this.alias_domain)))
         elif this.email:
-            return '%s <%s>' % (this.name, this.email)
+            return formataddr((this.name, this.email))
         raise osv.except_osv(_('Invalid Action!'), _("Unable to send email, please configure the sender's email address or alias."))
 
     def _get_default_author(self, cr, uid, context=None):
@@ -212,7 +214,7 @@ class mail_message(osv.Model):
 
     _defaults = {
         'type': 'email',
-        'date': fields.datetime.now(),
+        'date': fields.datetime.now,
         'author_id': lambda self, cr, uid, ctx=None: self._get_default_author(cr, uid, ctx),
         'body': '',
         'email_from': lambda self, cr, uid, ctx=None: self._get_default_from(cr, uid, ctx),
@@ -266,7 +268,7 @@ class mail_message(osv.Model):
             :return number of message mark as read
         """
         notification_obj = self.pool.get('mail.notification')
-        user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+        user_pid = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
         domain = [('partner_id', '=', user_pid), ('message_id', 'in', msg_ids)]
         if not create_missing:
             domain += [('read', '=', not read)]
@@ -294,7 +296,7 @@ class mail_message(osv.Model):
                 (i.e. when acting on displayed messages not notified)
         """
         notification_obj = self.pool.get('mail.notification')
-        user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
+        user_pid = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
         domain = [('partner_id', '=', user_pid), ('message_id', 'in', msg_ids)]
         if not create_missing:
             domain += [('starred', '=', not starred)]
@@ -332,7 +334,7 @@ class mail_message(osv.Model):
         """
         res_partner_obj = self.pool.get('res.partner')
         ir_attachment_obj = self.pool.get('ir.attachment')
-        pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=None)['partner_id'][0]
+        pid = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
 
         # 1. Aggregate partners (author_id and partner_ids) and attachments
         partner_ids = set()
@@ -351,8 +353,13 @@ class mail_message(osv.Model):
         partner_tree = dict((partner[0], partner) for partner in partners)
 
         # 2. Attachments as SUPERUSER, because could receive msg and attachments for doc uid cannot see
-        attachments = ir_attachment_obj.read(cr, SUPERUSER_ID, list(attachment_ids), ['id', 'datas_fname', 'name'], context=context)
-        attachments_tree = dict((attachment['id'], {'id': attachment['id'], 'filename': attachment['datas_fname'], 'name': attachment['name']}) for attachment in attachments)
+        attachments = ir_attachment_obj.read(cr, SUPERUSER_ID, list(attachment_ids), ['id', 'datas_fname', 'name', 'file_type_icon'], context=context)
+        attachments_tree = dict((attachment['id'], {
+            'id': attachment['id'],
+            'filename': attachment['datas_fname'],
+            'name': attachment['name'],
+            'file_type_icon': attachment['file_type_icon'],
+        }) for attachment in attachments)
 
         # 3. Update message dictionaries
         for message_dict in messages:
@@ -378,6 +385,7 @@ class mail_message(osv.Model):
                 'author_id': author,
                 'partner_ids': partner_ids,
                 'attachment_ids': attachment_ids,
+                'user_pid': pid
                 })
         return True
 
@@ -647,7 +655,6 @@ class mail_message(osv.Model):
         elif not ids:
             return ids
 
-        # pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'])['partner_id'][0]
         pid = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
         author_ids, partner_ids, allowed_ids = set([]), set([]), set([])
         model_ids = {}
@@ -698,8 +705,9 @@ class mail_message(osv.Model):
             """
             model_record_ids = {}
             for id in msg_ids:
-                if msg_val[id]['model'] and msg_val[id]['res_id']:
-                    model_record_ids.setdefault(msg_val[id]['model'], dict()).setdefault(msg_val[id]['res_id'], set()).add(msg_val[id]['res_id'])
+                vals = msg_val.get(id, {})
+                if vals.get('model') and vals.get('res_id'):
+                    model_record_ids.setdefault(vals['model'], set()).add(vals['res_id'])
             return model_record_ids
 
         if uid == SUPERUSER_ID:
@@ -711,7 +719,7 @@ class mail_message(osv.Model):
         partner_id = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=None).partner_id.id
 
         # Read mail_message.ids to have their values
-        message_values = dict.fromkeys(ids)
+        message_values = dict.fromkeys(ids, {})
         cr.execute('SELECT DISTINCT id, model, res_id, author_id, parent_id FROM "%s" WHERE id = ANY (%%s)' % self._table, (ids,))
         for id, rmod, rid, author_id, parent_id in cr.fetchall():
             message_values[id] = {'model': rmod, 'res_id': rid, 'author_id': author_id, 'parent_id': parent_id}
@@ -745,10 +753,10 @@ class mail_message(osv.Model):
             ], context=context)
             notified_ids = [notification.message_id.id for notification in not_obj.browse(cr, SUPERUSER_ID, not_ids, context=context)]
         elif operation == 'create':
-            for doc_model, doc_dict in model_record_ids.items():
+            for doc_model, doc_ids in model_record_ids.items():
                 fol_ids = fol_obj.search(cr, SUPERUSER_ID, [
                     ('res_model', '=', doc_model),
-                    ('res_id', 'in', list(doc_dict.keys())),
+                    ('res_id', 'in', list(doc_ids)),
                     ('partner_id', '=', partner_id),
                     ], context=context)
                 fol_mids = [follower.res_id for follower in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context)]
@@ -759,9 +767,9 @@ class mail_message(osv.Model):
         other_ids = other_ids.difference(set(notified_ids))
         model_record_ids = _generate_model_record_ids(message_values, other_ids)
         document_related_ids = []
-        for model, doc_dict in model_record_ids.items():
+        for model, doc_ids in model_record_ids.items():
             model_obj = self.pool[model]
-            mids = model_obj.exists(cr, uid, doc_dict.keys())
+            mids = model_obj.exists(cr, uid, list(doc_ids))
             if hasattr(model_obj, 'check_mail_message_access'):
                 model_obj.check_mail_message_access(cr, uid, mids, operation, context=context)
             else:
@@ -784,7 +792,7 @@ class mail_message(osv.Model):
         email_reply_to = None
 
         ir_config_parameter = self.pool.get("ir.config_parameter")
-        catchall_domain = ir_config_parameter.get_param(cr, uid, "mail.catchall.domain", context=context)
+        catchall_domain = ir_config_parameter.get_param(cr, SUPERUSER_ID, "mail.catchall.domain", context=context)
 
         # model, res_id, email_from: comes from values OR related message
         model, res_id, email_from = values.get('model'), values.get('res_id'), values.get('email_from')
@@ -794,7 +802,7 @@ class mail_message(osv.Model):
             email_reply_to = self.pool[model].message_get_reply_to(cr, uid, [res_id], context=context)[0]
         # no alias reply_to -> catchall alias
         if not email_reply_to and catchall_domain:
-            catchall_alias = ir_config_parameter.get_param(cr, uid, "mail.catchall.alias", context=context)
+            catchall_alias = ir_config_parameter.get_param(cr, SUPERUSER_ID, "mail.catchall.alias", context=context)
             if catchall_alias:
                 email_reply_to = '%s@%s' % (catchall_alias, catchall_domain)
         # still no reply_to -> reply_to will be the email_from
@@ -808,20 +816,17 @@ class mail_message(osv.Model):
                 email_reply_to = emails[0]
             document_name = self.pool[model].name_get(cr, SUPERUSER_ID, [res_id], context=context)[0]
             if document_name:
-                # sanitize document name
-                sanitized_doc_name = re.sub(r'[^\w+.]+', '-', document_name[1])
                 # generate reply to
-                email_reply_to = _('"Followers of %s" <%s>') % (sanitized_doc_name, email_reply_to)
+                email_reply_to = formataddr((_('Followers of %s') % document_name[1], email_reply_to))
 
         return email_reply_to
 
     def _get_message_id(self, cr, uid, values, context=None):
-        message_id = None
-        if not values.get('message_id') and values.get('reply_to'):
+        if values.get('reply_to'):
             message_id = tools.generate_tracking_message_id('reply_to')
-        elif not values.get('message_id') and values.get('res_id') and values.get('model'):
+        elif values.get('res_id') and values.get('model'):
             message_id = tools.generate_tracking_message_id('%(res_id)s-%(model)s' % values)
-        elif not values.get('message_id'):
+        else:
             message_id = tools.generate_tracking_message_id('private')
         return message_id
 
@@ -830,11 +835,11 @@ class mail_message(osv.Model):
             context = {}
         default_starred = context.pop('default_starred', False)
 
-        if not values.get('email_from'):  # needed to compute reply_to
+        if 'email_from' not in values:  # needed to compute reply_to
             values['email_from'] = self._get_default_from(cr, uid, context=context)
-        if not values.get('message_id'):
+        if 'message_id' not in values:
             values['message_id'] = self._get_message_id(cr, uid, values, context=context)
-        if not values.get('reply_to'):
+        if 'reply_to' not in values:
             values['reply_to'] = self._get_reply_to(cr, uid, values, context=context)
 
         newid = super(mail_message, self).create(cr, uid, values, context)
@@ -970,9 +975,11 @@ class mail_message(osv.Model):
                 cr, SUPERUSER_ID, [
                     ('res_model', '=', message.model),
                     ('res_id', '=', message.res_id),
-                    ('subtype_ids', 'in', message.subtype_id.id)
                 ], context=context)
-            partners_to_notify |= set(fo.partner_id.id for fo in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context))
+            partners_to_notify |= set(
+                fo.partner_id.id for fo in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context)
+                if message.subtype_id.id in [st.id for st in fo.subtype_ids]
+            )
         # remove me from notified partners, unless the message is written on my own wall
         if message.subtype_id and message.author_id and message.model == "res.partner" and message.res_id == message.author_id.id:
             partners_to_notify |= set([message.author_id.id])