Thibault Delavallée (OpenERP) has proposed merging
lp:~openerp-dev/openobject-addons/trunk-message_read-tde into
lp:openobject-addons.
Requested reviews:
OpenERP Core Team (openerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-message_read-tde/+merge/125476
--
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-message_read-tde/+merge/125476
Your team OpenERP R&D Team is subscribed to branch
lp:~openerp-dev/openobject-addons/trunk-message_read-tde.
=== modified file 'mail/mail_message.py'
--- mail/mail_message.py 2012-09-18 15:05:44 +0000
+++ mail/mail_message.py 2012-09-20 13:04:20 +0000
@@ -172,6 +172,7 @@
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)
has_voted = False
vote_ids = self.pool.get('res.users').name_get(cr, uid, [user.id for user in msg.vote_user_ids], context=context)
for vote in vote_ids:
@@ -196,11 +197,29 @@
'author_user_id': author_user_id,
'partner_ids': partner_ids,
'child_ids': [],
+ 'child_nbr': child_nbr,
'vote_user_ids': vote_ids,
'has_voted': has_voted
}
- def message_read_tree_flatten(self, cr, uid, messages, current_level, level, context=None):
+ def message_read_tree_get_expandable(self, cr, uid, parent_message, last_message, domain=[], current_level=0, level=0, context=None):
+ """ . """
+ base_domain = [('id', '<', last_message['id'])]
+ if parent_message and current_level < level:
+ base_domain += [('parent_id', '=', parent_message['id'])]
+ elif parent_message:
+ base_domain += [('id', 'child_of', parent_message['id'])]
+ if domain:
+ base_domain += domain
+ extension = { 'type': 'expandable',
+ 'domain': base_domain,
+ 'thread_level': current_level,
+ 'context': context,
+ 'id': -1,
+ }
+ return extension
+
+ 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': [...] },],
@@ -219,28 +238,44 @@
child_ids = msg_dict.pop('child_ids', [])
msg_dict['child_ids'] = []
return [msg_dict] + child_ids
- # return sorted([msg_dict] + child_ids, key=itemgetter('id'), reverse=True)
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['child_ids'], current_level + 1, level, 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
else:
- return_list = []
- for message in messages:
- for flat_message in _flatten(message):
- return_list.append(flat_message)
- return sorted(return_list, key=itemgetter(context.get('sort_key', 'id')), reverse=context.get('sort_reverse', True))
-
- 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 fetch the matching records.
- After having fetched the records provided by IDs, it will fetch the
- parents to have well-formed threads.
+ 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 == 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, 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.
+ After having fetch messages, their parents will be added to obtain
+ well formed threads.
+
+ :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 parent_id: if parent_id reached, stop searching for
+ further parents
:return list: list of trees of messages
"""
limit = limit or self._message_read_limit
@@ -249,39 +284,28 @@
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 thread_level and msg.parent_id:
- while msg.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': thread_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, result, 0, thread_level, context=context)
+ result = self.message_read_tree_flatten(cr, uid, None, result, domain, level, context=context)
return result
#------------------------------------------------------
=== modified file 'mail/res_partner.py'
--- mail/res_partner.py 2012-08-30 08:51:57 +0000
+++ mail/res_partner.py 2012-09-20 13:04:20 +0000
@@ -41,5 +41,4 @@
'notification_email_send': lambda *args: 'comment'
}
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== modified file 'mail/static/src/js/mail.js'
--- mail/static/src/js/mail.js 2012-09-18 15:05:44 +0000
+++ mail/static/src/js/mail.js 2012-09-20 13:04:20 +0000
@@ -34,6 +34,27 @@
/**
* ------------------------------------------------------------
+ * Sidebar
+ * ------------------------------------------------------------
+ *
+ * Override of sidebar do_attachment_new method, to catch attachments added
+ * through the sidebar and show them in the Chatter composition form.
+ */
+
+ // session.web.Sidebar = session.web.Sidebar.extend({
+ // do_attachment_new: function(attachment) {
+ // this._super(attachment);
+ // var message_ids = this.getParent().fields.message_ids || undefined;
+ // if (! message_ids) { return; }
+ // var compose_message_widget = message_ids.thread.compose_message_widget;
+ // if (! compose_message_widget) { return; }
+ // compose_message_widget.attachments.push(attachment);
+ // compose_message_widget.display_attachments();
+ // },
+ // });
+
+ /**
+ * ------------------------------------------------------------
* ChatterUtils
* ------------------------------------------------------------
*
@@ -445,7 +466,7 @@
return this.message_display(this.options.message_data);
}
message_ids = initial_mode && this.options.message_ids != null && this.options.message_ids || false;
- return this.ds_message.call('message_read', [message_ids, fetch_domain, this.options.thread_level, undefined, fetch_context]
+ return this.ds_message.call('message_read', [message_ids, fetch_domain, this.options.thread_level, fetch_context]
).then(this.proxy('message_display'));
},
=== modified file 'mail/tests/test_mail.py'
--- mail/tests/test_mail.py 2012-09-18 15:05:17 +0000
+++ mail/tests/test_mail.py 2012-09-20 13:04:20 +0000
@@ -502,13 +502,13 @@
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
def _compare_structures(struct1, struct2, n=0):
- # print '%scompare structure' % ('\t' * n)
+ 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)
+ print '%send compare' % ('\t' * n)
# ----------------------------------------
# CASE1: Flattening test
@@ -516,24 +516,25 @@
# 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': 4, 'child_ids': [
- {'id': 10, 'child_ids': []},
- {'id': 5, 'child_ids': []},
- ]},
- {'id': 3, '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_nbr': 2, 'child_ids': [
+ {'id': 10, 'child_nbr': 0, 'child_ids': []},
+ {'id': 5, 'child_nbr': 0, 'child_ids': []},
+ ]},
+ {'id': 3, 'child_nbr': 0, 'child_ids': []},
]},
]
# Test: completely flat
- new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 0)
+ 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
tree_test = [{'id': 2, 'child_ids': [
@@ -545,10 +546,10 @@
{'id': 4, 'child_ids': []}, {'id': 3, 'child_ids': []},
]},
]
- new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 1)
+ 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, copy.deepcopy(tree), 0, 2)
+ new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 2)
_compare_structures(new_tree, tree)
# ----------------------------------------
_______________________________________________
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