[FIX] [CLEAN] mail_thread: misc cleanup (comments, vars, typo). Fixed subscriber API. It now handles a read_back key in context to return the new value of the field. The purpose is to use it in mail_followers widget, that behaves asynchronously compared to the form_view, and that need updated values after subscribing a user. Updated mail_followers widget, cleaned its code. Updated mail_group with wrappers on message_subscriber_users, because it was setting user_ids as context.

bzr revid: tde@openerp.com-20120904133648-plsziijac64lw4de
This commit is contained in:
Thibault Delavallée 2012-09-04 15:36:48 +02:00
parent d6ddb23a4e
commit fd2a413969
7 changed files with 55 additions and 61 deletions

View File

@ -44,10 +44,6 @@ class mail_group(osv.Model):
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
def _get_default_image(self, cr, uid, context=None):
image_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
_columns = {
'description': fields.text('Description'),
'menu_id': fields.many2one('ir.ui.menu', string='Related Menu', required=True, ondelete="cascade"),
@ -89,6 +85,10 @@ class mail_group(osv.Model):
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
return ref and ref[1] or False
def _get_default_image(self, cr, uid, context=None):
image_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
def _get_menu_parent(self, cr, uid, context=None):
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'mail_group_root')
return ref and ref[1] or False
@ -156,3 +156,12 @@ class mail_group(osv.Model):
self._subscribe_users(cr, uid, ids, vals.get('group_ids'), context=context)
return result
def action_follow(self, cr, uid, ids, context=None):
""" Wrapper because message_subscribe_users take a user_ids=None
that receive the context without the wrapper. """
return self.message_subscribe_users(cr, uid, ids, context=context)
def action_unfollow(self, cr, uid, ids, context=None):
""" Wrapper because message_unsubscribe_users take a user_ids=None
that receive the context without the wrapper. """
return self.message_unsubscribe_users(cr, uid, ids, context=context)

View File

@ -33,8 +33,8 @@
<h4><a type="open"><field name="name"/></a></h4>
<ul>
<li><t t-raw="record.message_summary.raw_value"/></li>
<li t-if="! record.message_is_follower.raw_value"><a name="message_subscribe_users" string="Join" type="object" class="oe_group_join">Not following</a></li>
<li t-if="record.message_is_follower.raw_value"><a name="message_unsubscribe_users" string="Leave" type="object" class="oe_group_leave">Following</a></li>
<li t-if="! record.message_is_follower.raw_value"><a name="action_follow" string="Join" type="object" class="oe_group_join">Not following</a></li>
<li t-if="record.message_is_follower.raw_value"><a name="action_unfollow" string="Leave" type="object" class="oe_group_leave">Following</a></li>
</ul>
</div>
</div>
@ -81,7 +81,6 @@
</group>
</sheet>
<div class="oe_chatter">
<field name="message_is_follower" invisible="1"/>
<field name="message_ids" widget="mail_thread"
options='{"thread_level": 1}'/>
<field name="message_follower_ids" widget="mail_followers"/>

View File

@ -135,7 +135,7 @@ class mail_message(osv.Model):
_defaults = {
'type': 'email',
'date': lambda *a: fields.datetime.now(),
'author_id': lambda s,cr,uid,ctx={}: s._get_default_author(cr, uid, ctx),
'author_id': lambda self,cr,uid,ctx: self._get_default_author(cr, uid, ctx),
'body': '',
}

View File

@ -158,17 +158,16 @@ class mail_thread(osv.AbstractModel):
'mail_followers', 'res_id', 'partner_id',
reference_column='res_model', string='Followers'),
'message_comment_ids': fields.one2many('mail.message', 'res_id',
domain=lambda self: [('model','=',self._name),('type','in',('comment','email'))],
string='Related Messages',
help="All messages related to the current document."),
domain=lambda self: [('model', '=', self._name), ('type', 'in', ('comment', 'email'))],
string='Comments and emails',
help="Comments and emails"),
'message_ids': fields.one2many('mail.message', 'res_id',
domain=lambda self: [('model','=',self._name)],
string='Related Messages',
help="All messages related to the current document."),
string='Messages',
help="Messages and communication history"),
'message_unread': fields.function(_get_message_data, fnct_search=_search_unread,
string='Has Unread Messages', type='boolean',
help="When checked, new messages require your attention.",
multi="_get_message_data"),
type='boolean', string='Unread Messages', multi="_get_message_data",
help="If checked new messages require your attention."),
'message_summary': fields.function(_get_message_data, method=True,
type='text', string='Summary', multi="_get_message_data",
help="Holds the Chatter summary (number of messages, ...). "\
@ -181,7 +180,7 @@ class mail_thread(osv.AbstractModel):
#------------------------------------------------------
def create(self, cr, uid, vals, context=None):
""" Override of create to subscribe the current user. """
""" Override to subscribe the current user. """
thread_id = super(mail_thread, self).create(cr, uid, vals, context=context)
self.message_subscribe_users(cr, uid, [thread_id], [uid], context=context)
return thread_id
@ -215,11 +214,8 @@ class mail_thread(osv.AbstractModel):
def _message_find_partners(self, cr, uid, message, header_fields=['From'], context=None):
""" Find partners related to some header fields of the message. """
s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)])
mails = tools.email_split(s)
result = []
for email in mails:
result += self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)
return result
return [partner_id for email in tools.email_split(s)
for partner_id in self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)]
def _message_find_user_id(self, cr, uid, message, context=None):
from_local_part = tools.email_split(decode(message.get('From')))[0]
@ -551,16 +547,16 @@ class mail_thread(osv.AbstractModel):
#------------------------------------------------------
def log(self, cr, uid, id, message, secondary=False, context=None):
_logger.warning("log() is deprecated. As this module inherit from \
mail.thread, the message will be managed by this \
module instead of by the res.log mechanism. Please \
use the mail.thread OpenChatter API instead of the \
now deprecated res.log.")
_logger.warning("log() is deprecated. As this module inherit from "\
"mail.thread, the message will be managed by this "\
"module instead of by the res.log mechanism. Please "\
"use mail_thread.message_post() instead of the "\
"now deprecated res.log.")
self.message_post(cr, uid, [id], message, context=context)
def message_post(self, cr, uid, thread_id, body='', subject=False,
msg_type='notification', parent_id=False, attachments=None, context=None, **kwargs):
""" Post a new message in an existing message thread, returning the new
type='notification', parent_id=False, attachments=None, context=None, **kwargs):
""" Post a new message in an existing thread, returning the new
mail.message ID. Extra keyword arguments will be used as default
column values for the new mail.message record.
@ -568,7 +564,7 @@ class mail_thread(osv.AbstractModel):
:param str body: body of the message, usually raw HTML that will
be sanitized
:param str subject: optional subject
:param str msg_type: mail_message.type
:param str type: mail_message.type
:param int parent_id: optional ID of parent message in this thread
:param tuple(str,str) attachments: list of attachment tuples in the form
``(name,content)``, where content is NOT base64 encoded
@ -601,7 +597,7 @@ class mail_thread(osv.AbstractModel):
'res_id': thread_id or False,
'body': body,
'subject': subject,
'type': msg_type,
'type': type,
'parent_id': parent_id,
'attachment_ids': attachment_ids,
})
@ -615,40 +611,37 @@ class mail_thread(osv.AbstractModel):
def message_subscribe_users(self, cr, uid, ids, user_ids=None, context=None):
""" Wrapper on message_subscribe, using users. If user_ids is not
provided, subscribe uid instead. """
# isinstance: because using message_subscribe_users called in a view set the context as user_ids
if not user_ids or isinstance(user_ids, dict): user_ids = [uid]
if not user_ids: user_ids = [uid]
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
return self.message_subscribe(cr, uid, ids, partner_ids, context=context)
def message_subscribe(self, cr, uid, ids, partner_ids, context=None):
""" Add partners to the records followers.
:param partner_ids: a list of partner_ids to subscribe
:param return: new value of followers, for Chatter
:param return: new value of followers if read_back key in context
"""
self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
# TDE: temp, must check followers widget
if context and context.get('read_back'):
return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
return []
# return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None):
""" Wrapper on message_subscribe, using users. If user_ids is not
provided, unsubscribe uid instead. """
# isinstance: because using message_subscribe_users called in a view set the context as user_ids
if not user_ids or isinstance(user_ids, dict): user_ids = [uid]
if not user_ids: user_ids = [uid]
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
""" Remove partners from the records followers.
:param partner_ids: a list of partner_ids to unsubscribe
:param return: new value of followers, for Chatter
:param return: new value of followers if read_back key in context
"""
self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
# TDE: temp, must check followers widget
if context and context.get('read_back'):
return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
return []
# return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
#------------------------------------------------------
# Thread state
@ -679,4 +672,3 @@ class mail_thread(osv.AbstractModel):
partner_id = %s
''', (ids, self._name, partner_id))
return True

View File

@ -9,7 +9,7 @@ openerp_mail_followers = function(session, mail) {
* mail_followers Widget
* ------------------------------------------------------------
*
* This widget handles the display of a list of records as a vetical
* This widget handles the display of a list of records as a vertical
* list, with an image on the left. The widget itself is a floatting
* right-sided box.
* This widget is mainly used to display the followers of records
@ -65,25 +65,17 @@ openerp_mail_followers = function(session, mail) {
this.$el.find('div.oe_mail_recthread_aside').hide();
return;
}
if (this.getParent().fields.message_is_follower === undefined) {
// TDE: TMP, need to change all form views
this.message_is_follower = false;
}
else {
this.message_is_follower = this.getParent().fields.message_is_follower.get_value();
}
return this.fetch_followers(value_);
},
fetch_followers: function (value_) {
return this.ds_follow.call('read', [value_ || this.get_value(), ['name']]).then(this.proxy('display_followers'));
return this.ds_follow.call('read', [value_ || this.get_value(), ['name', 'user_ids']]).then(this.proxy('display_followers'));
},
/**
* Display the followers.
* TODO: replace the is_follower check by fields read */
/** Display the followers, evaluate is_follower directly */
display_followers: function (records) {
var self = this;
this.message_is_follower = _.indexOf(_.flatten(_.pluck(records, 'user_ids')), this.session.uid) != -1;
var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty();
this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')');
_(records).each(function (record) {
@ -99,11 +91,13 @@ openerp_mail_followers = function(session, mail) {
},
do_follow: function () {
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id]]).pipe(this.proxy('set_value'));
var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
},
do_unfollow: function () {
return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id]]).pipe(this.proxy('set_value'));
var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
},
});
};

View File

@ -250,7 +250,7 @@ class test_mail(common.TransactionCase):
_attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')]
# CASE1: post comment, body and subject specified
msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, msg_type='comment')
msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment')
message = self.mail_message.browse(cr, uid, msg_id)
mail_ids = self.mail_mail.search(cr, uid, [], limit=1)
mail = self.mail_mail.browse(cr, uid, mail_ids[0])
@ -280,7 +280,7 @@ class test_mail(common.TransactionCase):
# CASE2: post an email with attachments, parent_id, partner_ids
# TESTS: automatic subject, signature in body_html, attachments propagation
msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, msg_type='email',
msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email',
partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments)
message = self.mail_message.browse(cr, uid, msg_id2)
mail_ids = self.mail_mail.search(cr, uid, [], limit=1)

View File

@ -269,7 +269,7 @@ class mail_compose_message(osv.TransientModel):
post_values['attachments'] += new_attachments
post_values.update(email_dict)
# post the message
active_model_pool.message_post(cr, uid, [res_id], msg_type='comment', context=context, **post_values)
active_model_pool.message_post(cr, uid, [res_id], type='comment', context=context, **post_values)
return {'type': 'ir.actions.act_window_close'}