Commit5d1b323. re-enabled the user presence updates and notifications. Unfortunately, it showed poor performance due to the high frequency of bus notifications triggered on our instance (~600k users). In this rev., we don't trigger notifications on presence changes anymore, but we rather send the presence of users we have a DM open with, at the end of each poll period. For performance reasons, we ensure not to do that more than once every 30 seconds. We also refined the detection of the 'away' status client side. 'Last presence' timestamps are stored in the local storage, and the current inactivity period is sent at each poll. Those presence timestamps now rely on browser activity detection (click, keypress... events) rather than on the focus on Odoo tabs. Finally, we removed the no more necessary cron introduced in5d1b323.
58 lines
2.4 KiB
Python
58 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
from openerp import api, fields, models
|
|
|
|
from openerp.addons.bus.models.bus_presence import AWAY_TIMER
|
|
from openerp.addons.bus.models.bus_presence import DISCONNECTION_TIMER
|
|
|
|
|
|
class ResPartner(models.Model):
|
|
_inherit = 'res.partner'
|
|
|
|
im_status = fields.Char('IM Status', compute='_compute_im_status')
|
|
|
|
@api.multi
|
|
def _compute_im_status(self):
|
|
self.env.cr.execute("""
|
|
SELECT
|
|
U.partner_id as id,
|
|
CASE WHEN age(now() AT TIME ZONE 'UTC', B.last_poll) > interval %s THEN 'offline'
|
|
WHEN age(now() AT TIME ZONE 'UTC', B.last_presence) > interval %s THEN 'away'
|
|
ELSE 'online'
|
|
END as status
|
|
FROM bus_presence B
|
|
JOIN res_users U ON B.user_id = U.id
|
|
WHERE U.partner_id IN %s AND U.active = 't'
|
|
""", ("%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 partner in self:
|
|
partner.im_status = res.get(partner.id, 'offline')
|
|
|
|
@api.model
|
|
def im_search(self, name, limit=20):
|
|
""" Search partner with a name and return its id, name and im_status.
|
|
Note : the user must be logged
|
|
:param name : the partner name to search
|
|
:param limit : the limit of result to return
|
|
"""
|
|
name = '%' + name + '%'
|
|
excluded_partner_ids = [self.env.user.partner_id.id]
|
|
self.env.cr.execute("""
|
|
SELECT
|
|
U.id as user_id,
|
|
P.id as id,
|
|
P.name as name,
|
|
CASE WHEN B.last_poll IS NULL THEN 'offline'
|
|
WHEN age(now() AT TIME ZONE 'UTC', B.last_poll) > interval %s THEN 'offline'
|
|
WHEN age(now() AT TIME ZONE 'UTC', B.last_presence) > interval %s THEN 'away'
|
|
ELSE 'online'
|
|
END as im_status
|
|
FROM res_users U
|
|
JOIN res_partner P ON P.id = U.partner_id
|
|
LEFT JOIN bus_presence B ON B.user_id = U.id
|
|
WHERE P.name ILIKE %s
|
|
AND P.id NOT IN %s
|
|
AND U.active = 't'
|
|
LIMIT %s
|
|
""", ("%s seconds" % DISCONNECTION_TIMER, "%s seconds" % AWAY_TIMER, name, tuple(excluded_partner_ids), limit))
|
|
return self.env.cr.dictfetchall()
|