[REV] crm: reverted most changes about stages for this branch.
[odoo/odoo.git] / addons / im_livechat / im_livechat.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
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 openerp
23 import openerp.addons.im.im as im
24 import json
25 import random
26 import jinja2
27 from openerp.osv import osv, fields
28 from openerp import tools
29 import openerp.addons.web.http as http
30 from openerp.addons.web.http import request
31
32 env = jinja2.Environment(
33     loader=jinja2.PackageLoader('openerp.addons.im_livechat', "."),
34     autoescape=False
35 )
36 env.filters["json"] = json.dumps
37
38 class LiveChatController(http.Controller):
39
40     def _auth(self, db):
41         reg = openerp.modules.registry.RegistryManager.get(db)
42         uid = openerp.netsvc.dispatch_rpc('common', 'authenticate', [db, "anonymous", "anonymous", None])
43         return reg, uid
44
45     @http.route('/im_livechat/loader', auth="none")
46     def loader(self, **kwargs):
47         p = json.loads(kwargs["p"])
48         db = p["db"]
49         channel = p["channel"]
50         user_name = p.get("user_name", None)
51
52         reg, uid = self._auth(db)
53         with reg.cursor() as cr:
54             info = reg.get('im_livechat.channel').get_info_for_chat_src(cr, uid, channel)
55             info["db"] = db
56             info["channel"] = channel
57             info["userName"] = user_name
58             return request.make_response(env.get_template("loader.js").render(info),
59                  headers=[('Content-Type', "text/javascript")])
60
61     @http.route('/im_livechat/web_page', auth="none")
62     def web_page(self, **kwargs):
63         p = json.loads(kwargs["p"])
64         db = p["db"]
65         channel = p["channel"]
66         reg, uid = self._auth(db)
67         with reg.cursor() as cr:
68             script = reg.get('im_livechat.channel').read(cr, uid, channel, ["script"])["script"]
69             info = reg.get('im_livechat.channel').get_info_for_chat_src(cr, uid, channel)
70             info["script"] = script
71             return request.make_response(env.get_template("web_page.html").render(info),
72                  headers=[('Content-Type', "text/html")])
73
74     @http.route('/im_livechat/available', type='json', auth="none")
75     def available(self, db, channel):
76         reg, uid = self._auth(db)
77         with reg.cursor() as cr:
78             return len(reg.get('im_livechat.channel').get_available_users(cr, uid, channel)) > 0
79
80 class im_livechat_channel(osv.osv):
81     _name = 'im_livechat.channel'
82
83     def _get_default_image(self, cr, uid, context=None):
84         image_path = openerp.modules.get_module_resource('im_livechat', 'static/src/img', 'default.png')
85         return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
86     def _get_image(self, cr, uid, ids, name, args, context=None):
87         result = dict.fromkeys(ids, False)
88         for obj in self.browse(cr, uid, ids, context=context):
89             result[obj.id] = tools.image_get_resized_images(obj.image)
90         return result
91     def _set_image(self, cr, uid, id, name, value, args, context=None):
92         return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
93
94
95     def _are_you_inside(self, cr, uid, ids, name, arg, context=None):
96         res = {}
97         for record in self.browse(cr, uid, ids, context=context):
98             res[record.id] = False
99             for user in record.user_ids:
100                 if user.id == uid:
101                     res[record.id] = True
102                     break
103         return res
104
105     def _script(self, cr, uid, ids, name, arg, context=None):
106         res = {}
107         for record in self.browse(cr, uid, ids, context=context):
108             res[record.id] = env.get_template("include.html").render({
109                 "url": self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),
110                 "parameters": {"db":cr.dbname, "channel":record.id},
111             })
112         return res
113
114     def _web_page(self, cr, uid, ids, name, arg, context=None):
115         res = {}
116         for record in self.browse(cr, uid, ids, context=context):
117             res[record.id] = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') + \
118                 "/im_livechat/web_page?p=" + json.dumps({"db":cr.dbname, "channel":record.id})
119         return res
120
121     _columns = {
122         'name': fields.char(string="Channel Name", size=200, required=True),
123         'user_ids': fields.many2many('res.users', 'im_livechat_channel_im_user', 'channel_id', 'user_id', string="Users"),
124         'are_you_inside': fields.function(_are_you_inside, type='boolean', string='Are you inside the matrix?', store=False),
125         'script': fields.function(_script, type='text', string='Script', store=False),
126         'web_page': fields.function(_web_page, type='url', string='Web Page', store=False, size="200"),
127         'button_text': fields.char(string="Text of the Button", size=200),
128         'input_placeholder': fields.char(string="Chat Input Placeholder", size=200),
129         'default_message': fields.char(string="Welcome Message", size=200, help="This is an automated 'welcome' message that your visitor will see when they initiate a new chat session."),
130         # image: all image fields are base64 encoded and PIL-supported
131         'image': fields.binary("Photo",
132             help="This field holds the image used as photo for the group, limited to 1024x1024px."),
133         'image_medium': fields.function(_get_image, fnct_inv=_set_image,
134             string="Medium-sized photo", type="binary", multi="_get_image",
135             store={
136                 'im_livechat.channel': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
137             },
138             help="Medium-sized photo of the group. It is automatically "\
139                  "resized as a 128x128px image, with aspect ratio preserved. "\
140                  "Use this field in form views or some kanban views."),
141         'image_small': fields.function(_get_image, fnct_inv=_set_image,
142             string="Small-sized photo", type="binary", multi="_get_image",
143             store={
144                 'im_livechat.channel': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
145             },
146             help="Small-sized photo of the group. It is automatically "\
147                  "resized as a 64x64px image, with aspect ratio preserved. "\
148                  "Use this field anywhere a small image is required."),
149     }
150
151     def _default_user_ids(self, cr, uid, context=None):
152         return [(6, 0, [uid])]
153
154     _defaults = {
155         'button_text': "Have a Question? Chat with us.",
156         'input_placeholder': "How may I help you?",
157         'default_message': '',
158         'user_ids': _default_user_ids,
159         'image': _get_default_image,
160     }
161
162     def get_available_users(self, cr, uid, channel_id, context=None):
163         channel = self.browse(cr, openerp.SUPERUSER_ID, channel_id, context=context)
164         im_user_ids = self.pool.get("im.user").search(cr, uid, [["user_id", "in", [user.id for user in channel.user_ids]]], context=context)
165         users = []
166         for iuid in im_user_ids:
167             imuser = self.pool.get("im.user").browse(cr, uid, iuid, context=context)
168             if imuser.im_status:
169                 users.append(imuser)
170         return users
171
172     def get_session(self, cr, uid, channel_id, uuid, context=None):
173         my_id = self.pool.get("im.user").get_my_id(cr, uid, uuid, context=context)
174         users = self.get_available_users(cr, uid, channel_id, context=context)
175         if len(users) == 0:
176             return False
177         user_id = random.choice(users).id
178         session = self.pool.get("im.session").session_get(cr, uid, [user_id], uuid, context=context)
179         self.pool.get("im.session").write(cr, openerp.SUPERUSER_ID, session.get("id"), {'channel_id': channel_id}, context=context)
180         return session.get("id")
181
182     def test_channel(self, cr, uid, channel, context=None):
183         if not channel:
184             return {}
185         return {
186             'url': self.browse(cr, uid, channel[0], context=context or {}).web_page,
187             'type': 'ir.actions.act_url'
188         }
189
190     def get_info_for_chat_src(self, cr, uid, channel, context=None):
191         url = self.pool.get('ir.config_parameter').get_param(cr, openerp.SUPERUSER_ID, 'web.base.url')
192         chan = self.browse(cr, uid, channel, context=context)
193         return {
194             "url": url,
195             'buttonText': chan.button_text,
196             'inputPlaceholder': chan.input_placeholder,
197             'defaultMessage': chan.default_message,
198             "channelName": chan.name,
199         }
200
201     def join(self, cr, uid, ids, context=None):
202         self.write(cr, uid, ids, {'user_ids': [(4, uid)]})
203         return True
204
205     def quit(self, cr, uid, ids, context=None):
206         self.write(cr, uid, ids, {'user_ids': [(3, uid)]})
207         return True
208
209 class im_session(osv.osv):
210     _inherit = 'im.session'
211
212     _columns = {
213         'channel_id': fields.many2one("im.user", "Channel"),
214     }