123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- # -*- 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
|