2013-01-16 13:43:48 +00:00
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
2014-01-26 21:20:18 +00:00
# it under the terms of the GNU Affero General Public License as
2013-01-16 13:43:48 +00:00
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2014-01-26 21:20:18 +00:00
# GNU Affero General Public License for more details.
2013-01-16 13:43:48 +00:00
#
2014-01-26 21:20:18 +00:00
# You should have received a copy of the GNU Affero General Public License
2013-01-16 13:43:48 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
2013-01-29 15:05:56 +00:00
2013-02-01 09:55:46 +00:00
import json
2013-02-04 16:37:20 +00:00
import random
2013-02-05 13:47:11 +00:00
import jinja2
2013-10-22 17:06:59 +00:00
import openerp
import openerp . addons . im . im as im
2013-02-18 15:26:43 +00:00
from openerp . osv import osv , fields
from openerp import tools
2013-10-27 16:40:23 +00:00
from openerp import http
2013-10-22 17:06:59 +00:00
from openerp . http import request
2013-02-01 09:55:46 +00:00
2013-02-05 13:47:11 +00:00
env = jinja2 . Environment (
2013-03-15 11:21:53 +00:00
loader = jinja2 . PackageLoader ( ' openerp.addons.im_livechat ' , " . " ) ,
2013-02-05 13:47:11 +00:00
autoescape = False
)
env . filters [ " json " ] = json . dumps
2013-06-21 13:33:10 +00:00
class LiveChatController ( http . Controller ) :
2013-02-05 13:47:11 +00:00
2013-07-11 16:07:02 +00:00
def _auth ( self , db ) :
reg = openerp . modules . registry . RegistryManager . get ( db )
2014-01-28 14:32:24 +00:00
uid = request . uid
2013-07-11 16:07:02 +00:00
return reg , uid
2014-01-28 14:32:24 +00:00
@http.route ( ' /im_livechat/loader ' , auth = " public " )
2013-06-21 13:33:10 +00:00
def loader ( self , * * kwargs ) :
2013-02-05 13:53:25 +00:00
p = json . loads ( kwargs [ " p " ] )
db = p [ " db " ]
channel = p [ " channel " ]
2013-02-12 15:57:56 +00:00
user_name = p . get ( " user_name " , None )
2013-02-05 13:47:11 +00:00
2013-07-11 16:07:02 +00:00
reg , uid = self . _auth ( db )
with reg . cursor ( ) as cr :
info = reg . get ( ' im_livechat.channel ' ) . get_info_for_chat_src ( cr , uid , channel )
info [ " db " ] = db
info [ " channel " ] = channel
info [ " userName " ] = user_name
return request . make_response ( env . get_template ( " loader.js " ) . render ( info ) ,
headers = [ ( ' Content-Type ' , " text/javascript " ) ] )
2014-01-28 14:32:24 +00:00
@http.route ( ' /im_livechat/web_page ' , auth = " public " )
2013-06-21 13:33:10 +00:00
def web_page ( self , * * kwargs ) :
2013-02-05 15:15:06 +00:00
p = json . loads ( kwargs [ " p " ] )
db = p [ " db " ]
channel = p [ " channel " ]
2013-07-11 16:07:02 +00:00
reg , uid = self . _auth ( db )
with reg . cursor ( ) as cr :
script = reg . get ( ' im_livechat.channel ' ) . read ( cr , uid , channel , [ " script " ] ) [ " script " ]
info = reg . get ( ' im_livechat.channel ' ) . get_info_for_chat_src ( cr , uid , channel )
info [ " script " ] = script
return request . make_response ( env . get_template ( " web_page.html " ) . render ( info ) ,
headers = [ ( ' Content-Type ' , " text/html " ) ] )
2013-02-05 15:15:06 +00:00
2014-01-28 14:32:24 +00:00
@http.route ( ' /im_livechat/available ' , type = ' json ' , auth = " public " )
2013-06-21 13:33:10 +00:00
def available ( self , db , channel ) :
2013-07-11 16:07:02 +00:00
reg , uid = self . _auth ( db )
with reg . cursor ( ) as cr :
2013-09-02 12:23:11 +00:00
return len ( reg . get ( ' im_livechat.channel ' ) . get_available_users ( cr , uid , channel ) ) > 0
2013-02-05 14:01:43 +00:00
2013-03-15 11:21:53 +00:00
class im_livechat_channel ( osv . osv ) :
_name = ' im_livechat.channel '
2013-02-05 14:52:54 +00:00
2013-02-13 09:07:14 +00:00
def _get_default_image ( self , cr , uid , context = None ) :
2013-03-15 11:21:53 +00:00
image_path = openerp . modules . get_module_resource ( ' im_livechat ' , ' static/src/img ' , ' default.png ' )
2013-02-13 09:07:14 +00:00
return tools . image_resize_image_big ( open ( image_path , ' rb ' ) . read ( ) . encode ( ' base64 ' ) )
def _get_image ( self , cr , uid , ids , name , args , context = None ) :
result = dict . fromkeys ( ids , False )
for obj in self . browse ( cr , uid , ids , context = context ) :
result [ obj . id ] = tools . image_get_resized_images ( obj . image )
return result
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 )
2013-02-05 14:52:54 +00:00
def _are_you_inside ( self , cr , uid , ids , name , arg , context = None ) :
res = { }
for record in self . browse ( cr , uid , ids , context = context ) :
res [ record . id ] = False
for user in record . user_ids :
2013-02-25 11:06:30 +00:00
if user . id == uid :
2013-02-05 14:52:54 +00:00
res [ record . id ] = True
break
return res
2013-02-05 15:15:06 +00:00
def _script ( self , cr , uid , ids , name , arg , context = None ) :
res = { }
for record in self . browse ( cr , uid , ids , context = context ) :
res [ record . id ] = env . get_template ( " include.html " ) . render ( {
" url " : self . pool . get ( ' ir.config_parameter ' ) . get_param ( cr , uid , ' web.base.url ' ) ,
" parameters " : { " db " : cr . dbname , " channel " : record . id } ,
} )
return res
def _web_page ( self , cr , uid , ids , name , arg , context = None ) :
res = { }
for record in self . browse ( cr , uid , ids , context = context ) :
res [ record . id ] = self . pool . get ( ' ir.config_parameter ' ) . get_param ( cr , uid , ' web.base.url ' ) + \
2013-03-15 11:21:53 +00:00
" /im_livechat/web_page?p= " + json . dumps ( { " db " : cr . dbname , " channel " : record . id } )
2013-02-05 15:15:06 +00:00
return res
2013-02-01 09:55:46 +00:00
_columns = {
2014-05-21 09:52:05 +00:00
' name ' : fields . char ( string = " Channel Name " , required = True ) ,
2013-03-15 11:21:53 +00:00
' user_ids ' : fields . many2many ( ' res.users ' , ' im_livechat_channel_im_user ' , ' channel_id ' , ' user_id ' , string = " Users " ) ,
2013-02-05 14:52:54 +00:00
' are_you_inside ' : fields . function ( _are_you_inside , type = ' boolean ' , string = ' Are you inside the matrix? ' , store = False ) ,
2013-02-05 15:15:06 +00:00
' script ' : fields . function ( _script , type = ' text ' , string = ' Script ' , store = False ) ,
' web_page ' : fields . function ( _web_page , type = ' url ' , string = ' Web Page ' , store = False , size = " 200 " ) ,
2014-05-21 09:52:05 +00:00
' button_text ' : fields . char ( string = " Text of the Button " ) ,
' input_placeholder ' : fields . char ( string = " Chat Input Placeholder " ) ,
' default_message ' : fields . char ( string = " Welcome Message " , help = " This is an automated ' welcome ' message that your visitor will see when they initiate a new chat session. " ) ,
2013-02-13 09:07:14 +00:00
# image: all image fields are base64 encoded and PIL-supported
' image ' : fields . binary ( " Photo " ,
help = " This field holds the image used as photo for the group, limited to 1024x1024px. " ) ,
' image_medium ' : fields . function ( _get_image , fnct_inv = _set_image ,
string = " Medium-sized photo " , type = " binary " , multi = " _get_image " ,
store = {
2013-03-15 11:21:53 +00:00
' im_livechat.channel ' : ( lambda self , cr , uid , ids , c = { } : ids , [ ' image ' ] , 10 ) ,
2013-02-13 09:07:14 +00:00
} ,
help = " Medium-sized photo of the group. It is automatically " \
" resized as a 128x128px image, with aspect ratio preserved. " \
" Use this field in form views or some kanban views. " ) ,
' image_small ' : fields . function ( _get_image , fnct_inv = _set_image ,
string = " Small-sized photo " , type = " binary " , multi = " _get_image " ,
store = {
2013-03-15 11:21:53 +00:00
' im_livechat.channel ' : ( lambda self , cr , uid , ids , c = { } : ids , [ ' image ' ] , 10 ) ,
2013-02-13 09:07:14 +00:00
} ,
help = " Small-sized photo of the group. It is automatically " \
" resized as a 64x64px image, with aspect ratio preserved. " \
" Use this field anywhere a small image is required. " ) ,
2013-02-11 09:55:10 +00:00
}
2013-02-13 14:38:52 +00:00
def _default_user_ids ( self , cr , uid , context = None ) :
2013-02-25 11:06:30 +00:00
return [ ( 6 , 0 , [ uid ] ) ]
2013-02-13 14:38:52 +00:00
2013-02-11 09:55:10 +00:00
_defaults = {
2013-02-13 11:04:20 +00:00
' button_text ' : " Have a Question? Chat with us. " ,
2013-02-11 09:55:10 +00:00
' input_placeholder ' : " How may I help you? " ,
' default_message ' : ' ' ,
2013-02-13 14:38:52 +00:00
' user_ids ' : _default_user_ids ,
2013-02-13 09:07:14 +00:00
' image ' : _get_default_image ,
2013-02-04 15:36:12 +00:00
}
2013-09-02 12:23:11 +00:00
def get_available_users ( self , cr , uid , channel_id , context = None ) :
2013-02-25 11:06:30 +00:00
channel = self . browse ( cr , openerp . SUPERUSER_ID , channel_id , context = context )
2013-08-26 12:39:47 +00:00
im_user_ids = self . pool . get ( " im.user " ) . search ( cr , uid , [ [ " user_id " , " in " , [ user . id for user in channel . user_ids ] ] ] , context = context )
2013-02-04 16:37:20 +00:00
users = [ ]
2013-08-26 12:39:47 +00:00
for iuid in im_user_ids :
2013-02-25 11:06:30 +00:00
imuser = self . pool . get ( " im.user " ) . browse ( cr , uid , iuid , context = context )
if imuser . im_status :
users . append ( imuser )
2013-09-02 12:23:11 +00:00
return users
def get_session ( self , cr , uid , channel_id , uuid , context = None ) :
2014-01-28 16:26:49 +00:00
self . pool . get ( " im.user " ) . get_my_id ( cr , uid , uuid , context = context )
users = self . get_available_users ( cr , openerp . SUPERUSER_ID , channel_id , context = context )
2013-02-04 16:37:20 +00:00
if len ( users ) == 0 :
return False
2013-09-02 12:23:11 +00:00
user_id = random . choice ( users ) . id
2013-09-02 17:29:23 +00:00
session = self . pool . get ( " im.session " ) . session_get ( cr , uid , [ user_id ] , uuid , context = context )
2013-09-02 12:23:11 +00:00
self . pool . get ( " im.session " ) . write ( cr , openerp . SUPERUSER_ID , session . get ( " id " ) , { ' channel_id ' : channel_id } , context = context )
return session . get ( " id " )
2013-02-04 16:37:20 +00:00
2013-02-13 10:43:21 +00:00
def test_channel ( self , cr , uid , channel , context = None ) :
if not channel :
return { }
return {
' url ' : self . browse ( cr , uid , channel [ 0 ] , context = context or { } ) . web_page ,
' type ' : ' ir.actions.act_url '
}
2013-02-11 09:55:10 +00:00
def get_info_for_chat_src ( self , cr , uid , channel , context = None ) :
2013-02-05 13:47:11 +00:00
url = self . pool . get ( ' ir.config_parameter ' ) . get_param ( cr , openerp . SUPERUSER_ID , ' web.base.url ' )
2013-02-11 09:55:10 +00:00
chan = self . browse ( cr , uid , channel , context = context )
return {
" url " : url ,
' buttonText ' : chan . button_text ,
' inputPlaceholder ' : chan . input_placeholder ,
' defaultMessage ' : chan . default_message ,
2013-02-11 13:47:23 +00:00
" channelName " : chan . name ,
2013-02-11 09:55:10 +00:00
}
2013-02-05 13:47:11 +00:00
2013-02-05 14:52:54 +00:00
def join ( self , cr , uid , ids , context = None ) :
2013-02-25 11:06:30 +00:00
self . write ( cr , uid , ids , { ' user_ids ' : [ ( 4 , uid ) ] } )
2013-02-05 14:52:54 +00:00
return True
def quit ( self , cr , uid , ids , context = None ) :
2013-02-25 11:06:30 +00:00
self . write ( cr , uid , ids , { ' user_ids ' : [ ( 3 , uid ) ] } )
2013-02-05 14:52:54 +00:00
return True
2013-09-02 12:23:11 +00:00
class im_session ( osv . osv ) :
_inherit = ' im.session '
2013-02-13 11:08:10 +00:00
_columns = {
[FIX] im_livechat: many2one channel_id of im_session to the right model.
In im_session model, field channel_id was a many2one to im_user, or, obviously, this should be a many2one to im_livechat.channel
Well, obviously, this is a copy/paste error (or distraction, your choice!). This fix should normally not be pushed on a stable branch (like the current one, saas-2), but considering the severity of the problem, and the few changes in database (alter foreign key only), this is acceptable. Why such a big mistake has not been seen earlier ? Do you even test or read back what you write ?
bzr revid: dle@openerp.com-20131204122727-q0ch5j2v8rrli41e
2013-12-04 12:27:27 +00:00
' channel_id ' : fields . many2one ( " im_livechat.channel " , " Channel " ) ,
2013-02-13 11:08:10 +00:00
}