From dbaeee703fc16027bf17552acc6bb3c409d21958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 22 Mar 2013 16:57:34 +0100 Subject: [IMP] mail: alias_contact on alias. However, not sure this will be usefull, to discuss. bzr revid: tde@openerp.com-20130322155734-9jfc7w8nw8oiytd4 --- addons/mail/mail_alias.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index 55746b11678..dad69fd8be3 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -87,13 +87,21 @@ class mail_alias(osv.Model): "messages will be attached, even if they did not reply to it. " "If set, this will disable the creation of new records completely."), 'alias_domain': fields.function(_get_alias_domain, string="Alias domain", type='char', size=None), + 'alias_contact': fields.selection([ + ('everyone', 'Everyone'), + ('partners', 'Authenticated Partners'), + ], string='Contact policy', required=True, + help="Allows to restrict the access to the alias. If set to partners, only emails coming " + "from a partner are accepted. Unknown emails are bounced. If set to everyone, every " + "incoming email is accepted for this alias."), } _defaults = { 'alias_defaults': '{}', - 'alias_user_id': lambda self,cr,uid,context: uid, + 'alias_user_id': lambda self, cr, uid, context: uid, # looks better when creating new aliases - even if the field is informative only - 'alias_domain': lambda self,cr,uid,context: self._get_alias_domain(cr, SUPERUSER_ID,[1],None,None)[1] + 'alias_domain': lambda self, cr, uid, context: self._get_alias_domain(cr, SUPERUSER_ID, [1], None, None)[1], + 'alias_contact': 'everyone', } _sql_constraints = [ -- cgit v1.2.3 From a3de5c872f7c26ec085dc62b95cfc62382ab970a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 9 Apr 2013 13:11:58 +0200 Subject: [REF] [IMP] mail_alias improvement alias_name is not required anymore crm, hr_job, project, mail_group, res_users: alias creation is now different and done more like other inherits, except an alias_model_name that is given to the context to find the alias alias_model_id. crm, jr_job, project, mail_group, res_users: updated form views using aliases mail_alias: added a filter on 'inactive' aliases (alias_name False) and added a button to redirect to the related document if any bzr revid: tde@openerp.com-20130409111158-bv04n5o01z9l3c17 --- addons/mail/mail_alias.py | 63 ++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 22 deletions(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index dad69fd8be3..51f9d36ab8d 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -39,6 +39,7 @@ def remove_accents(input_str): nkfd_form = unicodedata.normalize('NFKD', input_str) return u''.join([c for c in nkfd_form if not unicodedata.combining(c)]) + class mail_alias(osv.Model): """A Mail Alias is a mapping of an email address with a given OpenERP Document model. It is used by OpenERP's mail gateway when processing incoming emails @@ -47,7 +48,7 @@ class mail_alias(osv.Model): of that alias. If the message is a reply it will be attached to the existing discussion on the corresponding record, otherwise a new record of the corresponding model will be created. - + This is meant to be used in combination with a catch-all email configuration on the company's mail server, so that as soon as a new mail.alias is created, it becomes immediately usable and OpenERP will accept email for it. @@ -63,7 +64,7 @@ class mail_alias(osv.Model): return dict.fromkeys(ids, domain or "") _columns = { - 'alias_name': fields.char('Alias', required=True, + 'alias_name': fields.char('Alias', help="The name of the email alias, e.g. 'jobs' " "if you want to catch emails for ",), 'alias_model_id': fields.many2one('ir.model', 'Aliased Model', required=True, ondelete="cascade", @@ -147,7 +148,8 @@ class mail_alias(osv.Model): return new_name def migrate_to_alias(self, cr, child_model_name, child_table_name, child_model_auto_init_fct, - alias_id_column, alias_key, alias_prefix = '', alias_force_key = '', alias_defaults = {}, context=None): + alias_id_column, alias_key, alias_prefix='', alias_force_key='', alias_defaults={}, + alias_generate_name=False, context=None): """ Installation hook to create aliases for all users and avoid constraint errors. :param child_model_name: model name of the child class (i.e. res.users) @@ -156,14 +158,12 @@ class mail_alias(osv.Model): (i.e. super(res_users,self)._auto_init(cr, context=context)) :param alias_id_column: alias_id column (i.e. self._columns['alias_id']) :param alias_key: name of the column used for the unique name (i.e. 'login') - :param alias_prefix: prefix for the unique name (i.e. 'jobs' + ...) :param alias_force_key': name of the column for force_thread_id; if empty string, not taken into account :param alias_defaults: dict, keys = mail.alias columns, values = child model column name used for default values (i.e. {'job_id': 'id'}) """ - - # disable the unique alias_id not null constraint, to avoid spurious warning during + # disable the unique alias_id not null constraint, to avoid spurious warning during # super.auto_init. We'll reinstall it afterwards. alias_id_column.required = False @@ -173,16 +173,18 @@ class mail_alias(osv.Model): registry = RegistryManager.get(cr.dbname) mail_alias = registry.get('mail.alias') child_class_model = registry.get(child_model_name) - no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test':False}) + no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test': False}) # Use read() not browse(), to avoid prefetching uninitialized inherited fields for obj_data in child_class_model.read(cr, SUPERUSER_ID, no_alias_ids, [alias_key]): - alias_vals = {'alias_name': '%s%s' % (alias_prefix, obj_data[alias_key]) } + alias_vals = {'alias_name': False} + if alias_generate_name: + alias_vals['alias_name'] = '%s%s' % (alias_prefix, obj_data[alias_key]) if alias_force_key: alias_vals['alias_force_thread_id'] = obj_data[alias_force_key] - alias_vals['alias_defaults'] = dict( (k, obj_data[v]) for k, v in alias_defaults.iteritems()) - alias_id = mail_alias.create_unique_alias(cr, SUPERUSER_ID, alias_vals, model_name=child_model_name) + alias_vals['alias_defaults'] = dict((k, obj_data[v]) for k, v in alias_defaults.iteritems()) + alias_id = mail_alias.create(cr, SUPERUSER_ID, alias_vals, {'alias_model_name': child_model_name}) child_class_model.write(cr, SUPERUSER_ID, obj_data['id'], {'alias_id': alias_id}) - _logger.info('Mail alias created for %s %s (uid %s)', child_model_name, obj_data[alias_key], obj_data['id']) + _logger.info('Mail alias created for %s %s (id %s)', child_model_name, obj_data[alias_key], obj_data['id']) # Finally attempt to reinstate the missing constraint try: @@ -196,19 +198,36 @@ class mail_alias(osv.Model): # set back the unique alias_id constraint alias_id_column.required = True - def create_unique_alias(self, cr, uid, vals, model_name=None, context=None): - """Creates an email.alias record according to the values provided in ``vals``, - with 2 alterations: the ``alias_name`` value may be suffixed in order to - make it unique (and certain unsafe characters replaced), and - he ``alias_model_id`` value will set to the model ID of the ``model_name`` - value, if provided, + def create(self, cr, uid, vals, context=None): + """ Creates an email.alias record according to the values provided in ``vals``, + with 2 alterations: the ``alias_name`` value may be suffixed in order to + make it unique (and certain unsafe characters replaced), and + he ``alias_model_id`` value will set to the model ID of the ``model_name`` + context value, if provided. """ + if context is None: + context = {} + model_name = context.get('alias_model_name') # when an alias name appears to already be an email, we keep the local part only - alias_name = remove_accents(vals['alias_name']).lower().split('@')[0] - alias_name = re.sub(r'[^\w+.]+', '-', alias_name) - alias_name = self._find_unique(cr, uid, alias_name, context=context) - vals['alias_name'] = alias_name + if vals.get('alias_name'): + alias_name = remove_accents(vals['alias_name']).lower().split('@')[0] + alias_name = re.sub(r'[^\w+.]+', '-', alias_name) + alias_name = self._find_unique(cr, uid, alias_name, context=context) + vals['alias_name'] = alias_name if model_name: model_id = self.pool.get('ir.model').search(cr, uid, [('model', '=', model_name)], context=context)[0] vals['alias_model_id'] = model_id - return self.create(cr, uid, vals, context=context) + res = super(mail_alias, self).create(cr, uid, vals, context=context) + return res + + def open_document(self, cr, uid, ids, context=None): + alias = self.browse(cr, uid, ids, context=context)[0] + if not alias.alias_model_id or not alias.alias_force_thread_id: + return False + return { + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': alias.alias_model_id.model, + 'res_id': alias.alias_force_thread_id, + 'type': 'ir.actions.act_window', + } -- cgit v1.2.3 From 7f6a47559094c57d2e858e1749b6c37237f96582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 16 Apr 2013 15:28:13 +0200 Subject: [IMP] [REF] mail_thread: refactored a bit message_parse, message_route and various find_partner methods. Now handles private aliases (alias_contact as partners or followers). message_route now works in 2 steps : 1/ finding all possible routes, as before 2/ checks and filtrates those routes, by finding the most relevant message author and using it to check alias contact settings. Also refactored the various partner finding method in one method that checks in res.partner, for: partners, partners that are users, partners that follow a given document. bzr revid: tde@openerp.com-20130416132813-zcm1r5kx0dwrfeic --- addons/mail/mail_alias.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index 8df7f031fbf..37b709292e1 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -91,10 +91,12 @@ class mail_alias(osv.Model): 'alias_contact': fields.selection([ ('everyone', 'Everyone'), ('partners', 'Authenticated Partners'), + ('followers', 'Followers only'), ], string='Contact policy', required=True, - help="Allows to restrict the access to the alias. If set to partners, only emails coming " - "from a partner are accepted. Unknown emails are bounced. If set to everyone, every " - "incoming email is accepted for this alias."), + help="Policy to post a message on the document using the mailgateway.\n" + "- everyone: everyone can post\n" + "- partners: only authenticated partners\n" + "- followers: only followers of the related document\n"), } _defaults = { -- cgit v1.2.3 From a5bb69ec28bad2d86f5559d377862f0f77744f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 7 May 2013 11:36:36 +0200 Subject: [IMP] project: improved privacy_visiliby options labels, improved form view according to new specs. bzr revid: tde@openerp.com-20130507093636-gk9k1rc52u3ats3a --- addons/mail/mail_alias.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index dbf5af057b5..4ecc41b6ee8 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -92,7 +92,7 @@ class mail_alias(osv.Model): ('everyone', 'Everyone'), ('partners', 'Authenticated Partners'), ('followers', 'Followers only'), - ], string='Contact policy', required=True, + ], string='Alias Contact Security', required=True, help="Policy to post a message on the document using the mailgateway.\n" "- everyone: everyone can post\n" "- partners: only authenticated partners\n" -- cgit v1.2.3 From b8214efe450c3ce63b4d9476a176a4d0ef3fbf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 16 May 2013 13:24:25 +0200 Subject: =?UTF-8?q?[FIX]=20mail:=20email=5Ffrom=20does=20not=20take=20alia?= =?UTF-8?q?s=20into=20account=20if=20it=20is=20False.=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bzr revid: tde@openerp.com-20130516112425-n3qq2lm509qa8hy5 --- addons/mail/mail_alias.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index 4ecc41b6ee8..86b4959e4f6 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -175,7 +175,7 @@ class mail_alias(osv.Model): registry = RegistryManager.get(cr.dbname) mail_alias = registry.get('mail.alias') child_class_model = registry[child_model_name] - no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test':False}) + no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test': False}) # Use read() not browse(), to avoid prefetching uninitialized inherited fields for obj_data in child_class_model.read(cr, SUPERUSER_ID, no_alias_ids, [alias_key]): alias_vals = {'alias_name': False} -- cgit v1.2.3 From 88e3505554038350ae0274e9359bbffff342b9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 16 May 2013 18:42:07 +0200 Subject: [IMP] mail_alias: added reference to the parent record. The parent record is the record that holds the alias. It is different from the record updated or created using the alias. For example projects have aliases whose parent is the given projet, and that creates new task inside the project. Updated alias creation and management accordingly. This ownership concept is used to compute the 'followers' contact settings of aliases. bzr revid: tde@openerp.com-20130516164207-1zr0q6abw6a34ndf --- addons/mail/mail_alias.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index 86b4959e4f6..43eb9f7dfaa 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -88,6 +88,11 @@ class mail_alias(osv.Model): "messages will be attached, even if they did not reply to it. " "If set, this will disable the creation of new records completely."), 'alias_domain': fields.function(_get_alias_domain, string="Alias domain", type='char', size=None), + 'alias_parent_model_id': fields.many2one('ir.model', 'Parent Model', + help="Parent model holding the alias. The model holding the alias reference\n" + "is not necessarily the model given by alias_model_id (hint: project and task)"), + 'alias_parent_thread_id': fields.integer('Parent Record Thread ID', + help="ID of the parent record holding the alias."), 'alias_contact': fields.selection([ ('everyone', 'Everyone'), ('partners', 'Authenticated Partners'), @@ -150,7 +155,7 @@ class mail_alias(osv.Model): return new_name def migrate_to_alias(self, cr, child_model_name, child_table_name, child_model_auto_init_fct, - alias_id_column, alias_key, alias_prefix='', alias_force_key='', alias_defaults={}, + alias_model_name, alias_id_column, alias_key, alias_prefix='', alias_force_key='', alias_defaults={}, alias_generate_name=False, context=None): """ Installation hook to create aliases for all users and avoid constraint errors. @@ -184,7 +189,8 @@ class mail_alias(osv.Model): if alias_force_key: alias_vals['alias_force_thread_id'] = obj_data[alias_force_key] alias_vals['alias_defaults'] = dict((k, obj_data[v]) for k, v in alias_defaults.iteritems()) - alias_id = mail_alias.create(cr, SUPERUSER_ID, alias_vals, {'alias_model_name': child_model_name}) + alias_create_ctx = dict(context, alias_model_name=alias_model_name, alias_parent_model_name=child_model_name) + alias_id = mail_alias.create(cr, SUPERUSER_ID, alias_vals, {'alias_parent_thread_id': obj_data.id}, context=alias_create_ctx) child_class_model.write(cr, SUPERUSER_ID, obj_data['id'], {'alias_id': alias_id}) _logger.info('Mail alias created for %s %s (id %s)', child_model_name, obj_data[alias_key], obj_data['id']) @@ -211,6 +217,7 @@ class mail_alias(osv.Model): if context is None: context = {} model_name = context.get('alias_model_name') + parent_model_name = context.get('alias_parent_model_name') # when an alias name appears to already be an email, we keep the local part only if vals.get('alias_name'): alias_name = remove_accents(vals['alias_name']).lower().split('@')[0] @@ -220,6 +227,9 @@ class mail_alias(osv.Model): if model_name: model_id = self.pool.get('ir.model').search(cr, uid, [('model', '=', model_name)], context=context)[0] vals['alias_model_id'] = model_id + if parent_model_name: + model_id = self.pool.get('ir.model').search(cr, uid, [('model', '=', parent_model_name)], context=context)[0] + vals['alias_parent_model_id'] = model_id res = super(mail_alias, self).create(cr, uid, vals, context=context) return res @@ -234,3 +244,15 @@ class mail_alias(osv.Model): 'res_id': alias.alias_force_thread_id, 'type': 'ir.actions.act_window', } + + def open_parent_document(self, cr, uid, ids, context=None): + alias = self.browse(cr, uid, ids, context=context)[0] + if not alias.alias_parent_model_id or not alias.alias_parent_thread_id: + return False + return { + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': alias.alias_parent_model_id.model, + 'res_id': alias.alias_parent_thread_id, + 'type': 'ir.actions.act_window', + } -- cgit v1.2.3 From 754122155aac594744f5dd9abb636e789e479056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 17 May 2013 10:43:13 +0200 Subject: [FIX] mail_alias: fixed implementation errors in new migrate_to_alias bzr revid: tde@openerp.com-20130517084313-hwkafiecpxgipoe9 --- addons/mail/mail_alias.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index 43eb9f7dfaa..7050ea8d01b 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -189,8 +189,9 @@ class mail_alias(osv.Model): if alias_force_key: alias_vals['alias_force_thread_id'] = obj_data[alias_force_key] alias_vals['alias_defaults'] = dict((k, obj_data[v]) for k, v in alias_defaults.iteritems()) + alias_vals['alias_parent_thread_id'] = obj_data['id'] alias_create_ctx = dict(context, alias_model_name=alias_model_name, alias_parent_model_name=child_model_name) - alias_id = mail_alias.create(cr, SUPERUSER_ID, alias_vals, {'alias_parent_thread_id': obj_data.id}, context=alias_create_ctx) + alias_id = mail_alias.create(cr, SUPERUSER_ID, alias_vals, context=alias_create_ctx) child_class_model.write(cr, SUPERUSER_ID, obj_data['id'], {'alias_id': alias_id}) _logger.info('Mail alias created for %s %s (id %s)', child_model_name, obj_data[alias_key], obj_data['id']) -- cgit v1.2.3 From bd7c26657c1468bd28761f0398ae826838e547b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 19 Jun 2013 15:52:29 +0200 Subject: [CLEAN] mail_alias: added / cleaned a bit the comments bzr revid: tde@openerp.com-20130619135229-ow0is5kvl6ux60ze --- addons/mail/mail_alias.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'addons/mail/mail_alias.py') diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index 74b6a391e5a..97d2842d15c 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -65,8 +65,7 @@ class mail_alias(osv.Model): _columns = { 'alias_name': fields.char('Alias', - help="The name of the email alias, e.g. 'jobs' " - "if you want to catch emails for ",), + help="The name of the email alias, e.g. 'jobs' if you want to catch emails for ",), 'alias_model_id': fields.many2one('ir.model', 'Aliased Model', required=True, ondelete="cascade", help="The model (OpenERP Document Kind) to which this alias " "corresponds. Any incoming email that does not reply to an " @@ -90,9 +89,10 @@ class mail_alias(osv.Model): 'alias_domain': fields.function(_get_alias_domain, string="Alias domain", type='char', size=None), 'alias_parent_model_id': fields.many2one('ir.model', 'Parent Model', help="Parent model holding the alias. The model holding the alias reference\n" - "is not necessarily the model given by alias_model_id (hint: project and task)"), + "is not necessarily the model given by alias_model_id\n" + "(example: project (parent_model) and task (model))"), 'alias_parent_thread_id': fields.integer('Parent Record Thread ID', - help="ID of the parent record holding the alias."), + help="ID of the parent record holding the alias (example: project holding the task creation alias)"), 'alias_contact': fields.selection([ ('everyone', 'Everyone'), ('partners', 'Authenticated Partners'), @@ -163,12 +163,16 @@ class mail_alias(osv.Model): :param child_table_name: table name of the child class (i.e. res_users) :param child_model_auto_init_fct: pointer to the _auto_init function (i.e. super(res_users,self)._auto_init(cr, context=context)) + :param alias_model_name: name of the aliased model :param alias_id_column: alias_id column (i.e. self._columns['alias_id']) :param alias_key: name of the column used for the unique name (i.e. 'login') + :param alias_prefix: prefix for the unique name (i.e. 'jobs' + ...) :param alias_force_key': name of the column for force_thread_id; if empty string, not taken into account :param alias_defaults: dict, keys = mail.alias columns, values = child model column name used for default values (i.e. {'job_id': 'id'}) + :param alias_generate_name: automatically generate alias name using prefix / alias key; + default alias_name value is False because since 8.0 it is not required anymore """ if context is None: context = {} @@ -222,8 +226,8 @@ class mail_alias(osv.Model): context = {} model_name = context.get('alias_model_name') parent_model_name = context.get('alias_parent_model_name') - # when an alias name appears to already be an email, we keep the local part only if vals.get('alias_name'): + # when an alias name appears to already be an email, we keep the local part only alias_name = remove_accents(vals['alias_name']).lower().split('@')[0] alias_name = re.sub(r'[^\w+.]+', '-', alias_name) alias_name = self._find_unique(cr, uid, alias_name, context=context) @@ -234,8 +238,7 @@ class mail_alias(osv.Model): if parent_model_name: model_id = self.pool.get('ir.model').search(cr, uid, [('model', '=', parent_model_name)], context=context)[0] vals['alias_parent_model_id'] = model_id - res = super(mail_alias, self).create(cr, uid, vals, context=context) - return res + return super(mail_alias, self).create(cr, uid, vals, context=context) def open_document(self, cr, uid, ids, context=None): alias = self.browse(cr, uid, ids, context=context)[0] -- cgit v1.2.3