From dfa14420d212911bb5f87af19231a848c59cab07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 11 Sep 2012 14:01:17 +0200 Subject: [PATCH] [WIP] mail_message: continued work on message_read and expandables. bzr revid: tde@openerp.com-20120911120117-xeeercvglfwq3c9e --- addons/mail/mail_message.py | 69 +++++++++++++++---------------- addons/mail/static/src/js/mail.js | 2 +- addons/mail/tests/test_mail.py | 37 +++++++++-------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 90ccc8a2f24..230199569f4 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -147,6 +147,7 @@ class mail_message(osv.Model): def _message_dict_get(self, cr, uid, msg, context=None): """ Return a dict representation of the message browse record. """ + child_nbr = len(msg.child_ids) attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)] author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0] author_user_id = self.pool.get('res.users').name_get(cr, uid, [msg.author_id.user_ids[0].id], context=context)[0] @@ -165,6 +166,7 @@ class mail_message(osv.Model): 'author_user_id': author_user_id, 'partner_ids': partner_ids, 'child_ids': [], + 'child_nbr': child_nbr, } def message_read_tree_get_expandable(self, cr, uid, parent_message, last_message, domain=[], current_level=0, level=0, context=None): @@ -173,7 +175,7 @@ class mail_message(osv.Model): if parent_message and current_level < level: base_domain += [('parent_id', '=', parent_message['id'])] elif parent_message: - base_domain += [('id', 'child_od', parent_message['id'])] + base_domain += [('id', 'child_of', parent_message['id'])] if domain: base_domain += domain extension = { 'type': 'expandable', @@ -184,7 +186,7 @@ class mail_message(osv.Model): } return extension - def message_read_tree_flatten(self, cr, uid, parent_message, messages, current_level, level, domain=[], context=None): + def message_read_tree_flatten(self, cr, uid, parent_message, messages, domain=[], level=0, current_level=0, context=None, limit=None): """ Given a tree with several roots of following structure : [ {'id': 1, 'child_ids': [ {'id': 11, 'child_ids': [...] },], @@ -204,11 +206,14 @@ class mail_message(osv.Model): msg_dict['child_ids'] = [] return [msg_dict] + child_ids context = context or {} + limit = limit or self._message_read_limit # Depth-first flattening for message in messages: if message.get('type') == 'expandable': continue - message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], current_level + 1, level, domain, context=context) + message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], domain, level, current_level + 1, context=context) + for child in message['child_ids']: + message['child_nbr'] += child['child_nbr'] # Flatten if above maximum depth if current_level < level: return_list = messages @@ -216,12 +221,17 @@ class mail_message(osv.Model): return_list = [flat_message for message in messages for flat_message in _flatten(message)] # Add expandable return_list = sorted(return_list, key=itemgetter(context.get('sort_key', 'id')), reverse=context.get('sort_reverse', True)) - if current_level <= level: + if current_level == 0: + expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, [], current_level, level, context=context) + if len(return_list) >= limit: + print 'we need an expandable here' + print 'expandable', expandable + elif current_level <= level: expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, [], current_level, level, context=context) print 'expandable', expandable return return_list - def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, limit=None, tree_parent_id=False): + def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, limit=None, parent_id=False): """ Read messages from mail.message, and get back a structured tree of messages to be displayed as discussion threads. If IDs is set, fetch these records. Otherwise use the domain to fetch messages. @@ -231,7 +241,7 @@ class mail_message(osv.Model): :param domain: optional domain for searching ids :param level: level of threads to display, 0 being flat :param limit: number of messages to fetch - :param tree_parent_id: if parent_id reached, stop searching for + :param parent_id: if parent_id reached, stop searching for further parents :return list: list of trees of messages """ @@ -241,39 +251,28 @@ class mail_message(osv.Model): ids = self.search(cr, uid, domain, context=context, limit=limit) messages = self.browse(cr, uid, ids, context=context) + # key: ID, value: record + tree = {} result = [] - tree = {} # key: ID, value: record for msg in messages: - if len(result) < (limit - 1): - record = self._message_dict_get(cr, uid, msg, context=context) - if level and msg.parent_id: - while msg.parent_id != tree_parent_id: - if msg.parent_id.id in tree: - record_parent = tree[msg.parent_id.id] - else: - record_parent = self._message_dict_get(cr, uid, msg.parent_id, context=context) - if msg.parent_id.parent_id: - tree[msg.parent_id.id] = record_parent - if record['id'] not in [x['id'] for x in record_parent['child_ids']]: - record_parent['child_ids'].append(record) - record = record_parent - msg = msg.parent_id - if msg.id not in tree: - result.append(record) - tree[msg.id] = record - else: - result.append({ - 'type': 'expandable', - 'domain': [('id', '<=', msg.id)] + domain, - 'context': context, - 'thread_level': level, # should be improve accodting to level of records - 'id': -1, - }) - break + record = self._message_dict_get(cr, uid, msg, context=context) + while msg.parent_id and msg.parent_id.id != parent_id: + if msg.parent_id.id in tree: + record_parent = tree[msg.parent_id.id] + else: + record_parent = self._message_dict_get(cr, uid, msg.parent_id, context=context) + if msg.parent_id.parent_id: + tree[msg.parent_id.id] = record_parent + if record['id'] not in [x['id'] for x in record_parent['child_ids']]: + record_parent['child_ids'].append(record) + record = record_parent + msg = msg.parent_id + if msg.id not in tree: + result.append(record) + tree[msg.id] = record # Flatten the result - if thread_level > 0: - result = self.message_read_tree_flatten(cr, uid, None, result, 0, thread_level, domain, context=context) + result = self.message_read_tree_flatten(cr, uid, None, result, domain, level, context=context) return result #------------------------------------------------------ diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index c02b81d0c4f..651a2642cc4 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -455,7 +455,7 @@ openerp.mail = function(session) { return this.message_display(this.options.message_data); } return this.ds_message.call('message_read', - [(initial_mode && this.options.message_ids) || false, fetch_domain, this.options.thread_level, undefined, fetch_context] + [(initial_mode && this.options.message_ids) || false, fetch_domain, this.options.thread_level, fetch_context] ).then(this.proxy('message_display')); }, diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 1f65c38f755..053e5697207 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -29,7 +29,7 @@ Received: by mail1.openerp.com (Postfix, from userid 10002) From: Sylvie Lelitre Subject: {subject} MIME-Version: 1.0 -Content-Type: multipart/alternative; +Content-Type: multipart/alternative; boundary="----=_Part_4200734_24778174.1344608186754" Date: Fri, 10 Aug 2012 14:16:26 +0000 Message-ID: <1198923581.41972151344608186760.JavaMail@agrolait.com> @@ -52,9 +52,9 @@ Content-Transfer-Encoding: quoted-printable =20 =20 - +

Please call me as soon as possible this afternoon!

- +

--
Sylvie

@@ -153,7 +153,7 @@ class test_mail(common.TransactionCase): test_msg_id = '' mail_text = MAIL_TEMPLATE_PLAINTEXT.format(to='groups@example.com', subject='frogs', extra='', msg_id=test_msg_id) self.mail_thread.message_process(cr, uid, None, mail_text) - new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id','=',test_msg_id)])[0]) + new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0]) self.assertEqual(new_mail.body, '\n

\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
\n', 'plaintext mail incorrectly parsed') @@ -458,11 +458,12 @@ class test_mail(common.TransactionCase): # It will be updated as soon as we have fixed specs ! cr, uid = self.cr, self.uid group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + def _compare_structures(struct1, struct2, n=0): print '%scompare structure' % ('\t' * n) self.assertEqual(len(struct1), len(struct2), 'message_read structure number of childs incorrect') for x in range(len(struct1)): - print '%s' % ('\t' * n), struct1[x]['id'], struct2[x]['id'], struct1[x].get('subject') or '' + print '%s' % ('\t' * n), struct1[x]['id'], struct1[x]['child_nbr'], struct2[x]['id'], struct2[x]['child_nbr'], struct1[x].get('subject') or '' self.assertEqual(struct1[x]['id'], struct2[x]['id'], 'message_read failure %s' % struct1[x].get('subject')) _compare_structures(struct1[x]['child_ids'], struct2[x]['child_ids'], n + 1) print '%send compare' % ('\t' * n) @@ -473,24 +474,24 @@ class test_mail(common.TransactionCase): # Create dummy message structure import copy - tree = [{'id': 2, 'child_ids': [ - {'id': 6, 'child_ids': [ - {'id': 8, 'child_ids': []}, + tree = [{'id': 2, 'child_nbr': 1, 'child_ids': [ + {'id': 6, 'child_nbr': 1, 'child_ids': [ + {'id': 8, 'child_nbr': 0, 'child_ids': []}, ]}, ]}, - {'id': 1, 'child_ids':[ - {'id': 7, 'child_ids': [ - {'id': 9, 'child_ids': []}, + {'id': 1, 'child_nbr': 3, 'child_ids':[ + {'id': 7, 'child_nbr': 1, 'child_ids': [ + {'id': 9, 'child_nbr': 0, 'child_ids': []}, ]}, - {'id': 4, 'child_ids': [ - {'id': 10, 'child_ids': []}, - {'id': 5, 'child_ids': []}, + {'id': 4, 'child_nbr': 2, 'child_ids': [ + {'id': 10, 'child_nbr': 0, 'child_ids': []}, + {'id': 5, 'child_nbr': 0, 'child_ids': []}, ]}, - {'id': 3, 'child_ids': []}, + {'id': 3, 'child_nbr': 0, 'child_ids': []}, ]}, ] # Test: completely flat - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 0, [('type', 'in', 'borderlands')]) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 0) _compare_structures(new_tree, new_tree) self.assertEqual(len(new_tree), 10, 'message_read_tree_flatten wrong in flat') # Test: 1 thread level @@ -503,10 +504,10 @@ class test_mail(common.TransactionCase): {'id': 4, 'child_ids': []}, {'id': 3, 'child_ids': []}, ]}, ] - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 1, [('type', 'in', 'borderlands')]) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 1) _compare_structures(new_tree, tree_test) # Test: 2 thread levels - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 2, [('type', 'in', 'borderlands')]) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 2) _compare_structures(new_tree, tree) # ----------------------------------------