Thibault Delavallée (OpenERP) has proposed merging 
lp:~openerp-dev/openobject-addons/trunk-openchatter-3-5-tde into 
lp:openobject-addons.

Requested reviews:
  OpenERP Core Team (openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-openchatter-3-5-tde/+merge/117577

OpenChatter 3.5: share / portal
===============================

Purpose
- Share/Invite flow cleaning and integration with chatter
- Add attachments to chatter
-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-openchatter-3-5-tde/+merge/117577
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-addons/trunk-openchatter-3-5-tde.
=== modified file 'mail/data/mail_group_data.xml'
--- mail/data/mail_group_data.xml	2012-07-29 15:16:11 +0000
+++ mail/data/mail_group_data.xml	2012-08-01 08:03:19 +0000
@@ -21,7 +21,7 @@
             <value>Welcome to OpenERP!</value>
             <value>Your homepage is a summary of messages you received and key information about documents you follow.
 
-The top menu bar contains all applications you installed. You can use this &lt;i&gt;Settings&lt;/i&gt; menu to intall more applications, activate others features or give access to new users.
+The top menu bar contains all applications you installed. You can use this &lt;i&gt;Settings&lt;/i&gt; menu to install more applications, activate others features or give access to new users.
 
 To setup your preferences (name, email signature, avatar), click on the top right corner.</value>
         </function>

=== modified file 'mail/mail_message.py'
--- mail/mail_message.py	2012-07-20 12:57:29 +0000
+++ mail/mail_message.py	2012-08-01 08:03:19 +0000
@@ -93,6 +93,9 @@
         return result
 
     def name_get(self, cr, uid, ids, context=None):
+        # name_get may received int id instead of an id list
+        if isinstance(ids, (int, long)):
+            ids = [ids]
         res = []
         for message in self.browse(cr, uid, ids, context=context):
             name = ''

=== modified file 'mail/mail_thread.py'
--- mail/mail_thread.py	2012-07-25 09:44:50 +0000
+++ mail/mail_thread.py	2012-08-01 08:03:19 +0000
@@ -140,81 +140,57 @@
     # mail.message wrappers and tools
     #------------------------------------------------------
 
-    def message_create(self, cr, uid, thread_id, vals, context=None):
+    def message_create(self, cr, uid, thread_record, vals, context=None):
         """ OpenChatter: wrapper of mail.message create method
            - creates the mail.message
-           - automatically subscribe the message writer
+           - automatically subscribe the writer to the thread if any
            - push the message to subscribed users
+           - send emails to subscribed users that should receive an email
+             confirmation
+
+            :param thread_record: a browse_record object on the thread to which
+                the new message will be attached. It set to None, the message
+                is not attached to any thread.
+            :param vals: dictionary of values for the message to be created that
+                will be given to the mail.message create method.
         """
-        if context is None:
-            context = {}
-        
+        # protection against calls with id or ids instead of browse records
+        if isinstance(thread_record, (int, long)):
+            thread_record = self.pool.get(self._name).browse(cr, uid, thread_record, context=context)
+        elif isinstance(thread_record, (list)):
+            if all(isinstance(thread_id, (int, long)) for thread_id in thread_record):
+                thread_record = self.pool.get(self._name).browse(cr, uid, thread_record[0], context=context)
+            else:
+                thread_record = thread_record[0]
+
         message_obj = self.pool.get('mail.message')
         notification_obj = self.pool.get('mail.notification')
         body = vals.get('body_html', '') if vals.get('content_subtype') == 'html' else vals.get('body_text', '')
         
-        # automatically subscribe the writer of the message
-        if vals['user_id']:
-            self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context)
-        
+        # message attached to a thread: subscribe the writer if any, set as 
+        # unread if the writer is not the document responsible
+        if thread_record:
+            if vals['user_id']:
+                self.message_subscribe(cr, uid, [thread_record.id], [vals['user_id']], context=context)
+            self.message_create_set_unread(cr, uid, [thread_record.id], context=context)
+
         # create message
         msg_id = message_obj.create(cr, uid, vals, context=context)
-        
-        # Set as unread if writer is not the document responsible
-        self.message_create_set_unread(cr, uid, [thread_id], context=context)
-        
+
         # special: if install mode, do not push demo data
-        if context.get('install_mode', False):
+        if context and context.get('install_mode'):
             return msg_id
-        
+        message = message_obj.browse(cr, uid, msg_id, context=context)
+
         # get users that will get a notification pushed
-        user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context)
+        user_to_push_ids = self.message_notification_get_user_ids(cr, uid, thread_record, message, context=context)
         for id in user_to_push_ids:
             notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context)
         
         # create the email to send
-        email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context)
+        email_id = self.message_notification_send_email(cr, uid, thread_record, message, user_to_push_ids, context=context)
         
         return msg_id
-    
-    def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None):
-        subscription_obj = self.pool.get('mail.subscription')
-        # get body
-        body = new_msg_vals.get('body_html', '') if new_msg_vals.get('content_subtype') == 'html' else new_msg_vals.get('body_text', '')
-        
-        # get subscribers
-        notif_user_ids = self.message_get_subscribers(cr, uid, thread_ids, context=context)
-        
-        # add users requested via parsing message (@login)
-        notif_user_ids += self.message_parse_users(cr, uid, body, context=context)
-        
-        # add users requested to perform an action (need_action mechanism)
-        if hasattr(self, 'get_needaction_user_ids'):
-            user_ids_dict = self.get_needaction_user_ids(cr, uid, thread_ids, context=context)
-            for id, user_ids in user_ids_dict.iteritems():
-                notif_user_ids += user_ids
-        
-        # add users notified of the parent messages (because: if parent message contains @login, login must receive the replies)
-        if new_msg_vals.get('parent_id'):
-            notif_obj = self.pool.get('mail.notification')
-            parent_notif_ids = notif_obj.search(cr, uid, [('message_id', '=', new_msg_vals.get('parent_id'))], context=context)
-            parent_notifs = notif_obj.read(cr, uid, parent_notif_ids, context=context)
-            notif_user_ids += [parent_notif['user_id'][0] for parent_notif in parent_notifs]
-
-        # remove duplicate entries
-        notif_user_ids = list(set(notif_user_ids))
-        return notif_user_ids
-
-    def message_parse_users(self, cr, uid, string, context=None):
-        """Parse message content
-           - if find @login -(^|\s)@((\w|@|\.)*)-: returns the related ids
-             this supports login that are emails (such as @[email protected])
-        """
-        regex = re.compile('(^|\s)@((\w|@|\.)*)')
-        login_lst = [item[1] for item in regex.findall(string)]
-        if not login_lst: return []
-        user_ids = self.pool.get('res.users').search(cr, uid, [('login', 'in', login_lst)], context=context)
-        return user_ids
 
     #------------------------------------------------------
     # Generic message api
@@ -361,7 +337,7 @@
                     'reply_to': reply_to,
                     'original': original, })
 
-            new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context=context))
+            new_msg_ids.append(self.message_create(cr, uid, thread, data, context=context))
         return new_msg_ids
 
     def message_append_dict(self, cr, uid, ids, msg_dict, context=None):
@@ -498,33 +474,36 @@
         message_ids = self.message_search(cr, uid, ids, fetch_ancestors, ancestor_ids,
             limit, offset, domain, context=context)
         messages = self.pool.get('mail.message').read(cr, uid, message_ids, context=context)
-
-        """ Retrieve all attachments names """
+        # format attachments for Chatter
+        self.message_read_format_attachments(cr, uid, messages, context=context)
+        # set the threads as read
+        self.message_check_and_set_read(cr, uid, ids, context=context)
+        # sort and return the messages
+        messages = sorted(messages, key=lambda d: (-d['id']))
+        return messages
+
+    def message_read_format_attachments(self, cr, uid, messages, context=None):
+        """ Format attachment of messages to display in Chatter.
+
+            :param messages: list of read results (value dictionaries) on
+                mail.messages records
+        """
+        # use empty string as a placeholder
         map_id_to_name = dict((attachment_id, '') for message in messages for attachment_id in message['attachment_ids'])
-        map_id_to_name = {}
-        for msg in messages:
-            for attach_id in msg["attachment_ids"]:
-                map_id_to_name[attach_id] = '' # use empty string as a placeholder
 
-        ids = map_id_to_name.keys()
-        names = self.pool.get('ir.attachment').name_get(cr, uid, ids, context=context)
+        attachment_ids = map_id_to_name.keys()
+        names = self.pool.get('ir.attachment').name_get(cr, uid, attachment_ids, context=context)
         
         # convert the list of tuples into a dictionnary
         for name in names: 
             map_id_to_name[name[0]] = name[1]
         
         # give corresponding ids and names to each message
-        for msg in messages:
-            msg["attachments"] = []
-            
-            for attach_id in msg["attachment_ids"]:
-                msg["attachments"].append({'id': attach_id, 'name': map_id_to_name[attach_id]})
-        
-        # Set the threads as read
-        self.message_check_and_set_read(cr, uid, ids, context=context)
-        # Sort and return the messages
-        messages = sorted(messages, key=lambda d: (-d['id']))
-        return messages
+        for message in messages:
+            message["attachments"] = []
+            for attach_id in message["attachment_ids"]:
+                message["attachments"].append({'id': attach_id, 'name': map_id_to_name[attach_id]})
+        return True
 
     def message_get_pushed_messages(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None,
                             limit=100, offset=0, msg_search_domain=[], context=None):
@@ -557,8 +536,10 @@
         # get messages
         msg_ids = msg_obj.search(cr, uid, [('id', 'in', msg_ids)], context=context)
         if (fetch_ancestors): msg_ids = self._message_search_ancestor_ids(cr, uid, ids, msg_ids, ancestor_ids, context=context)
-        msgs = msg_obj.read(cr, uid, msg_ids, context=context)
-        return msgs
+        messages = msg_obj.read(cr, uid, msg_ids, context=context)
+        # format attachments for Chatter
+        self.message_read_format_attachments(cr, uid, messages, context=context)
+        return messages
 
     #------------------------------------------------------
     # Mail gateway
@@ -905,7 +886,49 @@
     # Notification API
     #------------------------------------------------------
 
-    def message_create_notify_by_email(self, cr, uid, new_msg_values, user_to_notify_ids, context=None):
+    def message_notification_get_user_ids(self, cr, uid, thread_record, message, context=None):
+        """ OpenChatter tools method. This method returns the user_ids that have
+            receive a mail.notification to push a message to their wall.
+
+            :param thread_record: a browse_record object on the thread to which
+                the new message will be attached. It set to None, the message
+                is not attached to any thread.
+            :param message: a browse record object on the newly created message
+        """
+        subscription_obj = self.pool.get('mail.subscription')
+        # get subscribers
+        notif_user_ids = self.message_get_subscribers(cr, uid, [thread_record.id], context=context)
+        # add users requested via parsing message (@login)
+        body = message.body_html if message.content_subtype == 'html' else message.body_text
+        notif_user_ids += self.message_notification_parse_users(cr, uid, body, context=context)
+        # add users requested to perform an action (need_action mechanism)
+        if hasattr(self, 'get_needaction_user_ids'):
+            user_ids_dict = self.get_needaction_user_ids(cr, uid, [thread_record.id], context=context)
+            for id, user_ids in user_ids_dict.iteritems():
+                notif_user_ids += user_ids
+        # add users notified of the parent messages (because: if parent message contains @login, login must receive the replies)
+        if message.parent_id:
+            notif_obj = self.pool.get('mail.notification')
+            parent_notif_ids = notif_obj.search(cr, uid, [('message_id', '=', message.parent_id.id)], context=context)
+            parent_notifs = notif_obj.read(cr, uid, parent_notif_ids, ['user_id'], context=context)
+            notif_user_ids += [parent_notif['user_id'][0] for parent_notif in parent_notifs]
+
+        # remove duplicate entries
+        notif_user_ids = list(set(notif_user_ids))
+        return notif_user_ids
+
+    def message_notification_parse_users(self, cr, uid, string, context=None):
+        """ Parse message content
+            - if find @login -(^|\s)@((\w|@|\.)*)-: returns the related ids
+                this supports login that are emails (such as @[email protected])
+        """
+        regex = re.compile('(^|\s)@((\w|@|\.)*)')
+        login_lst = [item[1] for item in regex.findall(string)]
+        if not login_lst: return []
+        user_ids = self.pool.get('res.users').search(cr, uid, [('login', 'in', login_lst)], context=context)
+        return user_ids
+
+    def message_notification_send_email(self, cr, uid, thread_record, message, user_ids, context=None):
         """ When creating a new message and pushing notifications, emails
             must be send if users have chosen to receive notifications
             by email via the notification_email_pref field.
@@ -917,26 +940,27 @@
             - never: never receive notifications
             Note that an user should never receive notifications for messages
             he has created.
-            
-            :param new_msg_values: dictionary of message values, those that
-                                   are given to the create method
-            :param user_to_notify_ids: list of user_ids, user that will
-                                       receive a notification on their Wall
+
+            :param thread_record: a browse_record object on the thread to which
+                the new message will be attached. It set to None, the message
+                is not attached to any thread.
+            :param message: a browse record object on the newly created message
+            :param user_ids: list of user_ids, user that will receive a
+                notification on their Wall
         """
         message_obj = self.pool.get('mail.message')
         res_users_obj = self.pool.get('res.users')
-        body = new_msg_values.get('body_html', '') if new_msg_values.get('content_subtype') == 'html' else new_msg_values.get('body_text', '')
-        
+
         # remove message writer
-        if user_to_notify_ids.count(new_msg_values.get('user_id')) > 0:
-            user_to_notify_ids.remove(new_msg_values.get('user_id'))
+        if user_ids.count(message.user_id.id) > 0:
+            user_ids.remove(message.user_id.id)
         
         # get user_ids directly asked
-        user_to_push_from_parse_ids = self.message_parse_users(cr, uid, body, context=context)
-        
+        body = message.body_html if message.content_subtype == 'html' else message.body_text
+        user_to_push_from_parse_ids = self.message_notification_parse_users(cr, uid, body, context=context)
         # try to find an email_to
         email_to = ''
-        for user in res_users_obj.browse(cr, uid, user_to_notify_ids, context=context):
+        for user in res_users_obj.browse(cr, uid, user_ids, context=context):
             if not user.notification_email_pref == 'all' and \
                 not (user.notification_email_pref == 'to_me' and user.id in user_to_push_from_parse_ids):
                 continue
@@ -950,38 +974,60 @@
             return
         
         # try to find an email_from
-        current_user = res_users_obj.browse(cr, uid, [uid], context=context)[0]
-        email_from = new_msg_values.get('email_from')
+        user_writer = res_users_obj.browse(cr, uid, [uid], context=context)[0]
+        email_from = message.email_from
         if not email_from:
-            email_from = current_user.user_email
+            email_from = user_writer.user_email
         
-        # get email content, create it (with mail_message.create)
-        email_values = self.message_create_notify_get_email_dict(cr, uid, new_msg_values, email_from, email_to, context)
+        # get email content, create it using directly mail_message.create
+        email_values = self.message_notification_get_email_dict(cr, uid, thread_record, message, user_writer, email_from, email_to, context=context)
         email_id = message_obj.create(cr, uid, email_values, context=context)
         return email_id
     
-    def message_create_notify_get_email_dict(self, cr, uid, new_msg_values, email_from, email_to, context=None):
-        values = dict(new_msg_values)
-        
-        body_html = new_msg_values.get('body_html', '')
+    def message_notification_get_email_dict(self, cr, uid, thread_record, message, user_writer, email_from, email_to, context=None):
+        """ Create the dictionary of values for the notification email to
+            send.
+
+            :param thread_record: a browse_record object on the thread to which
+                the new message will be attached. It set to None, the message
+                is not attached to any thread.
+            :param user_writer: a browse_record object on the message writer. It
+                will be used to display some data in the footer of the send
+                emails.
+            :param email_from: email_from of the send notification email
+            :param email_to: list of emails that will receive the notification
+                emails, formatted like 'r@r, r@r, r@r'
+        """
+        footer_dict_values = {
+            'company_name': user_writer.company_id.name,
+            'record_name': message.record_name,
+        }
+        # update html body
+        body_html = message.body_html
         if body_html:
-            body_html += '\n\n----------\nThis email was send automatically by OpenERP, because you have subscribed to a document.'
-        body_text = new_msg_values.get('body_text', '')
+            body_html += '''
+<div>
+    <p>This email was send automatically by %(company_name)s, because you are subscribed to %(record_name)s.</p>
+</div>''' % footer_dict_values
+        # update text body
+        body_text = message.body_text
         if body_text:
-            body_text += '\n\n----------\nThis email was send automatically by OpenERP, because you have subscribed to a document.'
-        values.update({
+            body_text += '''----------
+This email was send automatically by %(company_name)s, because you are subscribed to %(record_name)s.''' % footer_dict_values
+        # create email values
+        values = {
+            'subject': 'Notification for %s: %s' % (message.record_name, message.subject),
+            'body_html': body_html,
+            'body_text': body_text,
             'type': 'email',
             'state': 'outgoing',
+            'content_subtype': message.content_subtype,
             'email_from': email_from,
             'email_to': email_to,
-            'subject': 'New message',
-            'content_subtype': new_msg_values.get('content_subtype', 'plain'),
-            'body_html': body_html,
-            'body_text': body_text,
             'auto_delete': True,
             'res_model': '',
             'res_id': False,
-        })
+        }
         return values
 
     def message_remove_pushed_notifications(self, cr, uid, ids, msg_ids, remove_childs=True, context=None):

=== modified file 'mail/res_users.py'
--- mail/res_users.py	2012-07-20 13:29:04 +0000
+++ mail/res_users.py	2012-08-01 08:03:19 +0000
@@ -33,9 +33,8 @@
     
     _columns = {
         'notification_email_pref': fields.selection([
-            ('all', 'All feeds'),
-            ('comments', 'Only comments'),
-            ('to_me', 'Only when sent directly to me'),
+            ('all', 'All Feeds'),
+            ('to_me', 'Only send directly to me'),
             ('none', 'Never')
             ], 'Receive Feeds by Email', required=True,
             help="Choose in which case you want to receive an email when you "\
@@ -64,8 +63,14 @@
         self.message_subscribe(cr, uid, [user_id], [user_id], context=context)
         # create a welcome message
         company_name = user.company_id.name if user.company_id else 'the company'
-        message = _('%s has joined %s! Welcome in OpenERP !') % (user.name, company_name)
-        self.message_append_note(cr, uid, [user_id], subject='Welcom to OpenERP', body=message, type='comment', context=context)
+        message = '''%s has joined %s! Welcome in OpenERP !
+
+Your homepage is a summary of messages you received and key information about documents you follow.
+
+The top menu bar contains all applications you installed. You can use this <i>Settings</i> menu to install more applications, activate others features or give access to new users.
+
+To setup your preferences (name, email signature, avatar), click on the top right corner.''' % (user.name, company_name)
+        self.message_append_note(cr, uid, [user_id], subject='Welcome to OpenERP', body=message, type='comment', content_subtype='html', context=context)
         return user_id
 
     def message_search_get_domain(self, cr, uid, ids, context=None):

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to