mail_guest.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. import pytz
  4. import uuid
  5. from odoo.tools import consteq
  6. from odoo import _, api, fields, models
  7. from odoo.addons.base.models.res_partner import _tz_get
  8. from odoo.exceptions import UserError
  9. from odoo.addons.bus.models.bus_presence import AWAY_TIMER, DISCONNECTION_TIMER
  10. class MailGuest(models.Model):
  11. _name = 'mail.guest'
  12. _description = "Guest"
  13. _inherit = ['avatar.mixin']
  14. _avatar_name_field = "name"
  15. _cookie_name = 'dgid'
  16. _cookie_separator = '|'
  17. @api.model
  18. def _lang_get(self):
  19. return self.env['res.lang'].get_installed()
  20. name = fields.Char(string="Name", required=True)
  21. access_token = fields.Char(string="Access Token", default=lambda self: str(uuid.uuid4()), groups='base.group_system', required=True, readonly=True, copy=False)
  22. country_id = fields.Many2one(string="Country", comodel_name='res.country')
  23. lang = fields.Selection(string="Language", selection=_lang_get)
  24. timezone = fields.Selection(string="Timezone", selection=_tz_get)
  25. channel_ids = fields.Many2many(string="Channels", comodel_name='mail.channel', relation='mail_channel_member', column1='guest_id', column2='channel_id', copy=False)
  26. im_status = fields.Char('IM Status', compute='_compute_im_status')
  27. def _compute_im_status(self):
  28. self.env.cr.execute("""
  29. SELECT
  30. guest_id as id,
  31. CASE WHEN age(now() AT TIME ZONE 'UTC', last_poll) > interval %s THEN 'offline'
  32. WHEN age(now() AT TIME ZONE 'UTC', last_presence) > interval %s THEN 'away'
  33. ELSE 'online'
  34. END as status
  35. FROM bus_presence
  36. WHERE guest_id IN %s
  37. """, ("%s seconds" % DISCONNECTION_TIMER, "%s seconds" % AWAY_TIMER, tuple(self.ids)))
  38. res = dict(((status['id'], status['status']) for status in self.env.cr.dictfetchall()))
  39. for guest in self:
  40. guest.im_status = res.get(guest.id, 'offline')
  41. def _get_guest_from_context(self):
  42. """Returns the current guest record from the context, if applicable."""
  43. guest = self.env.context.get('guest')
  44. if isinstance(guest, self.pool['mail.guest']):
  45. return guest
  46. return self.env['mail.guest']
  47. def _get_guest_from_request(self, request):
  48. parts = request.httprequest.cookies.get(self._cookie_name, '').split(self._cookie_separator)
  49. if len(parts) != 2:
  50. return self.env['mail.guest']
  51. guest_id, guest_access_token = parts
  52. if not guest_id or not guest_access_token:
  53. return self.env['mail.guest']
  54. guest = self.env['mail.guest'].browse(int(guest_id)).sudo().exists()
  55. if not guest or not guest.access_token or not consteq(guest.access_token, guest_access_token):
  56. return self.env['mail.guest']
  57. if not guest.timezone:
  58. timezone = self._get_timezone_from_request(request)
  59. if timezone:
  60. guest._update_timezone(timezone)
  61. return guest.sudo(False).with_context(guest=guest)
  62. def _get_timezone_from_request(self, request):
  63. timezone = request.httprequest.cookies.get('tz')
  64. return timezone if timezone in pytz.all_timezones else False
  65. def _update_name(self, name):
  66. self.ensure_one()
  67. name = name.strip()
  68. if len(name) < 1:
  69. raise UserError(_("Guest's name cannot be empty."))
  70. if len(name) > 512:
  71. raise UserError(_("Guest's name is too long."))
  72. self.name = name
  73. guest_data = {
  74. 'id': self.id,
  75. 'name': self.name
  76. }
  77. bus_notifs = [(channel, 'mail.guest/insert', guest_data) for channel in self.channel_ids]
  78. bus_notifs.append((self, 'mail.guest/insert', guest_data))
  79. self.env['bus.bus']._sendmany(bus_notifs)
  80. def _update_timezone(self, timezone):
  81. query = """
  82. UPDATE mail_guest
  83. SET timezone = %s
  84. WHERE id IN (
  85. SELECT id FROM mail_guest WHERE id = %s
  86. FOR NO KEY UPDATE SKIP LOCKED
  87. )
  88. """
  89. self.env.cr.execute(query, (timezone, self.id))
  90. def _init_messaging(self):
  91. self.ensure_one()
  92. partner_root = self.env.ref('base.partner_root')
  93. return {
  94. 'channels': self.channel_ids.channel_info(),
  95. 'companyName': self.env.company.name,
  96. 'currentGuest': {
  97. 'id': self.id,
  98. 'name': self.name,
  99. },
  100. 'current_partner': False,
  101. 'current_user_id': False,
  102. 'current_user_settings': False,
  103. 'hasLinkPreviewFeature': self.env['mail.link.preview']._is_link_preview_enabled(),
  104. 'menu_id': False,
  105. 'needaction_inbox_counter': False,
  106. 'partner_root': {
  107. 'id': partner_root.id,
  108. 'name': partner_root.name,
  109. },
  110. 'shortcodes': [],
  111. 'starred_counter': False,
  112. }
  113. def _guest_format(self, fields=None):
  114. if not fields:
  115. fields = {'id': True, 'name': True, 'im_status': True}
  116. guests_formatted_data = {}
  117. for guest in self:
  118. data = {}
  119. if 'id' in fields:
  120. data['id'] = guest.id
  121. if 'name' in fields:
  122. data['name'] = guest.name
  123. if 'im_status' in fields:
  124. data['im_status'] = guest.im_status
  125. guests_formatted_data[guest] = data
  126. return guests_formatted_data