[IMP] mail cleaning
[odoo/odoo.git] / addons / mail / mail_group.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2010-today OpenERP SA (<http://www.openerp.com>)
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>
19 #
20 ##############################################################################
21
22 import datetime as DT
23 import openerp
24 import openerp.tools as tools
25 from operator import itemgetter
26 from osv import osv
27 from osv import fields
28 from tools.translate import _
29
30 class mail_group(osv.Model):
31     """
32     A mail_group is a collection of users sharing messages in a discussion
33     group. Group users are users that follow the mail group, using the
34     subscription/follow mechanism of OpenSocial. A mail group has nothing
35     in common with res.users.group.
36     """
37     _description = 'Discussion group'
38     _name = 'mail.group'
39     _inherit = ['mail.thread','ir.needaction']
40     _inherits = {'mail.alias': 'alias_id', 'ir.ui.menu': 'menu_id'}
41
42     def _get_image(self, cr, uid, ids, name, args, context=None):
43         result = dict.fromkeys(ids, False)
44         for obj in self.browse(cr, uid, ids, context=context):
45             result[obj.id] = tools.image_get_resized_images(obj.image)
46         return result
47
48     def _set_image(self, cr, uid, id, name, value, args, context=None):
49         return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
50
51     def _get_default_image(self, cr, uid, context=None):
52         image_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
53         return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
54
55     _columns = {
56         'description': fields.text('Description'),
57         'menu_id': fields.many2one('ir.ui.menu', string='Related Menu', required=True, ondelete="cascade"),
58         'public': fields.selection([('public','Public'),('private','Private'),('groups','Selected Group Only')], 'Privacy', required=True,
59             help='This group is visible by non members. \
60             Invisible groups can add members through the invite button.'),
61         'group_public_id': fields.many2one('res.groups', string='Authorized Group'),
62         'group_ids': fields.many2many('res.groups', rel='mail_group_res_group_rel',
63             id1='mail_group_id', id2='groups_id', string='Auto Subscription',
64             help="Members of those groups will automatically added as followers. "\
65                  "Note that they will be able to manage their subscription manually "\
66                  "if necessary."),
67         'image': fields.binary("Photo",
68             help="This field holds the image used as photo for the "\
69                  "user. The image is base64 encoded, and PIL-supported. "\
70                  "It is limited to a 1024x1024 px image."),
71         'image_medium': fields.function(_get_image, fnct_inv=_set_image,
72             string="Medium-sized photo", type="binary", multi="_get_image",
73             store = {
74                 'mail.group': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
75             },
76             help="Medium-sized photo of the group. It is automatically "\
77                  "resized as a 180x180px image, with aspect ratio preserved. "\
78                  "Use this field in form views or some kanban views."),
79         'image_small': fields.function(_get_image, fnct_inv=_set_image,
80             string="Small-sized photo", type="binary", multi="_get_image",
81             store = {
82                 'mail.group': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
83             },
84             help="Small-sized photo of the group. It is automatically "\
85                  "resized as a 50x50px image, with aspect ratio preserved. "\
86                  "Use this field anywhere a small image is required."),
87         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade",
88             help="The email address associated with this group. New emails received will automatically "
89                  "create new topics."),
90     }
91
92     def _get_default_employee_group(self, cr, uid, context=None):
93         ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
94         return ref and ref[1] or False
95
96     def _get_menu_parent(self, cr, uid, context=None):
97         ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'mail_group_root')
98         return ref and ref[1] or False
99
100     _defaults = {
101         'public': 'groups',
102         'group_public_id': _get_default_employee_group,
103         'image': _get_default_image,
104         'parent_id': _get_menu_parent,
105         'alias_domain': False, # always hide alias during creation
106     }
107
108     # FP Note: code to be improved. Check we have a code for res.users
109     # when we give them a new group.
110     def _subscribe_users(self, cr, uid, ids, context=None):
111         for mail_group in self.browse(cr, uid, ids, context=context):
112             partner_ids = []
113             for group in mail_group.group_ids:
114                 partner_ids += [user.partner_id.id for user in group.users]
115             self.message_subscribe(cr, uid, ids, partner_ids, context=context)
116
117     def create(self, cr, uid, vals, context=None):
118         mail_alias = self.pool.get('mail.alias')
119         if not vals.get('alias_id'):
120             vals.pop('alias_name', None) # prevent errors during copy()
121             alias_id = mail_alias.create_unique_alias(cr, uid,
122                           # Using '+' allows using subaddressing for those who don't
123                           # have a catchall domain setup.
124                           {'alias_name': "group+"+vals['name']},
125                           model_name=self._name, context=context)
126             vals['alias_id'] = alias_id
127
128         mail_group_id = super(mail_group, self).create(cr, uid, vals, context)
129
130         # Create client action for this group and link the menu to it
131         ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'action_mail_group_feeds')
132         if ref:
133             search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search_wall')
134             params = {
135                 'search_view_id': search_ref and search_ref[1] or False,
136                 'domain': [('model','=','mail.group'),('res_id','=',mail_group_id)],
137                 'res_model': 'mail.group',
138                 'res_id': mail_group_id,
139                 'thread_level': 2
140             }
141             cobj = self.pool.get('ir.actions.client')
142             newref = cobj.copy(cr, uid, ref[1], default={'params': str(params), 'name': vals['name']}, context=context)
143             self.write(cr, uid, [mail_group_id], {'action': 'ir.actions.client,'+str(newref), 'mail_group_id': mail_group_id}, context=context)
144
145         mail_alias.write(cr, uid, [vals['alias_id']], {"alias_force_thread_id": mail_group_id}, context)
146
147         if vals.get('group_ids'):
148             self._subscribe_users(cr, uid, [mail_group_id], context=context)
149         return mail_group_id
150
151     def unlink(self, cr, uid, ids, context=None):
152         # Cascade-delete mail aliases as well, as they should not exist without the mail group.
153         mail_alias = self.pool.get('mail.alias')
154         alias_ids = [group.alias_id.id for group in self.browse(cr, uid, ids, context=context) if group.alias_id]
155         res = super(mail_group, self).unlink(cr, uid, ids, context=context)
156         mail_alias.unlink(cr, uid, alias_ids, context=context)
157         return res
158
159     def write(self, cr, uid, ids, vals, context=None):
160         result = super(mail_group, self).write(cr, uid, ids, vals, context=context)
161         if vals.get('group_ids'):
162             self._subscribe_users(cr, uid, ids, vals.get('group_ids'), context=context)
163         return result
164