diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 3a1417b2dba..3927ba639aa 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -173,6 +173,46 @@ class mail_message(osv.Model): 'child_ids': [], } + def message_read_tree_flatten(self, cr, uid, messages, current_level, level, context=None): + """ Given a tree with several roots of following structure : + [ + {'id': 1, 'child_ids':[ + {'id': 11, 'child_ids': [...] }, + ] }, + {...} + ] + Flatten it to have a maximum number of level, with 0 being + completely flat. + Perform the flattening at leafs if above the maximum depth, then get + back in the tree. + """ + def _flatten(msg_dict): + """ from {'id': x, 'child_ids': [{child1}, {child2}]} + get [{'id': x, 'child_ids': []}, {child1}, {child2}] + """ + child_ids = msg_dict.pop('child_ids', []) + msg_dict['child_ids'] = [] + return [msg_dict] + child_ids + # Depth-first flattening + for message in messages: + message['child_ids'] = self.message_read_tree_flatten(cr, uid, message['child_ids'], current_level+1, level, context=context) + # Flatten if above maximum depth + if current_level < level: + return messages + new_list = [] + for x in range(0, len(messages)): + flatenned = _flatten(messages[x]) + for flat in flatenned: + new_list.append(flat) + messages = new_list + return messages + + def _debug_print_tree(self, tree, prefix=''): + for elem in tree: + print '%s%s (%s childs: %s)' % (prefix, elem['id'], len(elem['child_ids']), [xelem['id'] for xelem in elem['child_ids']]) + if elem['child_ids']: + self._debug_print_tree(elem['child_ids'], prefix+'--') + def message_read(self, cr, uid, ids=False, domain=[], thread_level=0, limit=None, context=None): """ If IDS are provided, fetch these records, otherwise use the domain to @@ -219,6 +259,11 @@ class mail_message(osv.Model): 'thread_level': thread_level # should be improve accodting to level of records }) break + + # Flatten the result + if thread_level > 0: + result = self.message_read_tree_flatten(cr, uid, result, 0, thread_level, context=context) + return result diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 4a228d4d9ca..01d17c39ebb 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -322,41 +322,66 @@ class test_mail(common.TransactionCase): cr, uid = self.cr, self.uid group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + # Test message_read_tree_flatten that flattens a thread according to a given thread_level + import copy + tree = [ + {'id': 1, 'child_ids':[ + {'id': 3, 'child_ids': [] }, + {'id': 4, 'child_ids': [ + {'id': 5, 'child_ids': []}, + {'id': 12, 'child_ids': []}, + ] }, + {'id': 8, 'child_ids': [ + {'id': 10, 'child_ids': []}, + ] }, + ] }, + {'id': 2, 'child_ids': [ + {'id': 7, 'child_ids': [ + {'id': 9, 'child_ids': []}, + ] }, + ] }, + {'id': 6, 'child_ids': [ + {'id': 11, 'child_ids': [] }, + ] }, + ] + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 0) + # self.mail_message._debug_print_tree(new_tree) + # print '-------------------' + self.assertTrue(len(new_tree) == 12, 'Flattening wrongly produced') + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 1) + # self.mail_message._debug_print_tree(new_tree) + # print '-------------------' + self.assertTrue(len(new_tree) == 3 and len(new_tree[0]['child_ids']) == 6 and len(new_tree[1]['child_ids']) == 2 and len(new_tree[2]['child_ids']) == 1, + 'Flattening wrongly produced') + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 2) + # self.mail_message._debug_print_tree(new_tree) + # print '-------------------' + self.assertTrue(len(new_tree) == 3 and len(new_tree[0]['child_ids']) == 3 and len(new_tree[0]['child_ids'][1]) == 2, + 'Flattening wrongly produced') + # Add a few messages to pigs group msgid1 = group_pigs.message_post(body='My Body', subject='1', parent_id=False) msgid2 = group_pigs.message_post(body='My Body', subject='1-1', parent_id=msgid1) msgid3 = group_pigs.message_post(body='My Body', subject='1-2', parent_id=msgid1) msgid4 = group_pigs.message_post(body='My Body', subject='2', parent_id=False) msgid5 = group_pigs.message_post(body='My Body', subject='1-1-1', parent_id=msgid2) - # msgid6 = group_pigs.message_post(body='My Body', subject='2-1', parent_id=msgid4) - # msgid7 = group_pigs.message_post(body='My Body', subject='1-3', parent_id=msgid1) - # msgid8 = group_pigs.message_post(body='My Body', subject='1-3-1', parent_id=msgid7) + msgid6 = group_pigs.message_post(body='My Body', subject='2-1', parent_id=msgid4) # First try: read flat - # first_try_ids = [msgid8, msgid7, msgid6, msgid5, msgid4, msgid3, msgid2, msgid1] - # res = self.mail_message.message_read(cr, uid, ids=False, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], thread_level=0) + first_try_ids = [msgid6, msgid5, msgid4, msgid3, msgid2, msgid1] + tree = self.mail_message.message_read(cr, uid, ids=False, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], thread_level=0) + self.assertTrue(all(elem['id'] in first_try_ids for elem in tree) and len(tree) == 6, + 'Incorrect structure and/or number of childs in purely flat message_read') # Second try: read with thread_level 1 - res = self.mail_message.message_read(cr, uid, ids=False, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], thread_level=1) - # print '----' - # self.mail_message._debug_print_tree(res) - # print '----' + tree = self.mail_message.message_read(cr, uid, ids=False, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], thread_level=1) + # self.mail_message._debug_print_tree(tree) + self.assertTrue(len(tree) == 2 and len(tree[1]['child_ids']) == 3, 'Incorrect number of child in message_read') - self.assertTrue(len(res) == 2, 'Incorrect number of child in message_read') - self.assertTrue(len(res[0]['child_ids']) == 2, 'Incorrect number of child in message_read') - self.assertTrue(len(res[0]['child_ids'][0]['child_ids']) == 1, 'Incorrect number of child in message_read') - # trees = self.mail_message.message_read_tree_flatten_main(cr, uid, res, thread_level=0) - # print '----' - # self.mail_message._debug_print_tree(trees) - # print '----' - - res = self.mail_message.message_read(cr, uid, ids=False, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], thread_level=1) - # trees = self.mail_message.message_read_tree_flatten_main(cr, uid, res, thread_level=1) - # print '----' - # self.mail_message._debug_print_tree(trees) - # print '----' - - self.assertTrue(len(res) == 3, 'Incorrect number of child in message_read') + # Third try: read with thread_level 2 + tree = self.mail_message.message_read(cr, uid, ids=False, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], thread_level=2) + # self.mail_message._debug_print_tree(tree) + self.assertTrue(len(tree) == 2 and len(tree[1]['child_ids']) == 2 and len(tree[1]['child_ids'][0]['child_ids']) == 1, 'Incorrect number of child in message_read') def test_40_needaction(self): """ Tests for mail.message needaction. """