141 lines
5.5 KiB
Python
141 lines
5.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import pytz
|
|
import uuid
|
|
|
|
from odoo.tools import consteq
|
|
from odoo import _, api, fields, models
|
|
from odoo.addons.base.models.res_partner import _tz_get
|
|
from odoo.exceptions import UserError
|
|
from odoo.addons.bus.models.bus_presence import AWAY_TIMER, DISCONNECTION_TIMER
|
|
|
|
|
|
class MailGuest(models.Model):
|
|
_name = 'mail.guest'
|
|
_description = "Guest"
|
|
_inherit = ['avatar.mixin']
|
|
_avatar_name_field = "name"
|
|
_cookie_name = 'dgid'
|
|
_cookie_separator = '|'
|
|
|
|
@api.model
|
|
def _lang_get(self):
|
|
return self.env['res.lang'].get_installed()
|
|
|
|
name = fields.Char(string="Name", required=True)
|
|
access_token = fields.Char(string="Access Token", default=lambda self: str(uuid.uuid4()), groups='base.group_system', required=True, readonly=True, copy=False)
|
|
country_id = fields.Many2one(string="Country", comodel_name='res.country')
|
|
lang = fields.Selection(string="Language", selection=_lang_get)
|
|
timezone = fields.Selection(string="Timezone", selection=_tz_get)
|
|
channel_ids = fields.Many2many(string="Channels", comodel_name='mail.channel', relation='mail_channel_member', column1='guest_id', column2='channel_id', copy=False)
|
|
im_status = fields.Char('IM Status', compute='_compute_im_status')
|
|
|
|
def _compute_im_status(self):
|
|
self.env.cr.execute("""
|
|
SELECT
|
|
guest_id as id,
|
|
CASE WHEN age(now() AT TIME ZONE 'UTC', last_poll) > interval %s THEN 'offline'
|
|
WHEN age(now() AT TIME ZONE 'UTC', last_presence) > interval %s THEN 'away'
|
|
ELSE 'online'
|
|
END as status
|
|
FROM bus_presence
|
|
WHERE guest_id IN %s
|
|
""", ("%s seconds" % DISCONNECTION_TIMER, "%s seconds" % AWAY_TIMER, tuple(self.ids)))
|
|
res = dict(((status['id'], status['status']) for status in self.env.cr.dictfetchall()))
|
|
for guest in self:
|
|
guest.im_status = res.get(guest.id, 'offline')
|
|
|
|
def _get_guest_from_context(self):
|
|
"""Returns the current guest record from the context, if applicable."""
|
|
guest = self.env.context.get('guest')
|
|
if isinstance(guest, self.pool['mail.guest']):
|
|
return guest
|
|
return self.env['mail.guest']
|
|
|
|
def _get_guest_from_request(self, request):
|
|
parts = request.httprequest.cookies.get(self._cookie_name, '').split(self._cookie_separator)
|
|
if len(parts) != 2:
|
|
return self.env['mail.guest']
|
|
guest_id, guest_access_token = parts
|
|
if not guest_id or not guest_access_token:
|
|
return self.env['mail.guest']
|
|
guest = self.env['mail.guest'].browse(int(guest_id)).sudo().exists()
|
|
if not guest or not guest.access_token or not consteq(guest.access_token, guest_access_token):
|
|
return self.env['mail.guest']
|
|
if not guest.timezone:
|
|
timezone = self._get_timezone_from_request(request)
|
|
if timezone:
|
|
guest._update_timezone(timezone)
|
|
return guest.sudo(False).with_context(guest=guest)
|
|
|
|
def _get_timezone_from_request(self, request):
|
|
timezone = request.httprequest.cookies.get('tz')
|
|
return timezone if timezone in pytz.all_timezones else False
|
|
|
|
def _update_name(self, name):
|
|
self.ensure_one()
|
|
name = name.strip()
|
|
if len(name) < 1:
|
|
raise UserError(_("Guest's name cannot be empty."))
|
|
if len(name) > 512:
|
|
raise UserError(_("Guest's name is too long."))
|
|
self.name = name
|
|
guest_data = {
|
|
'id': self.id,
|
|
'name': self.name
|
|
}
|
|
bus_notifs = [(channel, 'mail.guest/insert', guest_data) for channel in self.channel_ids]
|
|
bus_notifs.append((self, 'mail.guest/insert', guest_data))
|
|
self.env['bus.bus']._sendmany(bus_notifs)
|
|
|
|
def _update_timezone(self, timezone):
|
|
query = """
|
|
UPDATE mail_guest
|
|
SET timezone = %s
|
|
WHERE id IN (
|
|
SELECT id FROM mail_guest WHERE id = %s
|
|
FOR NO KEY UPDATE SKIP LOCKED
|
|
)
|
|
"""
|
|
self.env.cr.execute(query, (timezone, self.id))
|
|
|
|
def _init_messaging(self):
|
|
self.ensure_one()
|
|
partner_root = self.env.ref('base.partner_root')
|
|
return {
|
|
'channels': self.channel_ids.channel_info(),
|
|
'companyName': self.env.company.name,
|
|
'currentGuest': {
|
|
'id': self.id,
|
|
'name': self.name,
|
|
},
|
|
'current_partner': False,
|
|
'current_user_id': False,
|
|
'current_user_settings': False,
|
|
'hasLinkPreviewFeature': self.env['mail.link.preview']._is_link_preview_enabled(),
|
|
'menu_id': False,
|
|
'needaction_inbox_counter': False,
|
|
'partner_root': {
|
|
'id': partner_root.id,
|
|
'name': partner_root.name,
|
|
},
|
|
'shortcodes': [],
|
|
'starred_counter': False,
|
|
}
|
|
|
|
def _guest_format(self, fields=None):
|
|
if not fields:
|
|
fields = {'id': True, 'name': True, 'im_status': True}
|
|
guests_formatted_data = {}
|
|
for guest in self:
|
|
data = {}
|
|
if 'id' in fields:
|
|
data['id'] = guest.id
|
|
if 'name' in fields:
|
|
data['name'] = guest.name
|
|
if 'im_status' in fields:
|
|
data['im_status'] = guest.im_status
|
|
guests_formatted_data[guest] = data
|
|
return guests_formatted_data
|