Before this commit, a JS widget would be instanciated for every `.js_follow` on
the page.
Every widget would then perform a RPC to know if the object was followed.
That would be an issue if there was too many `.js_follow` on the DOM.
Eg: on the forum tag page (/forum/1/tag), there might be unlimited tags. This
is where the biggest issue is ATM, on Odoo.com we have over 5500 tags,
which performs 5500 RPC.
Your browser will most of the time just crash.
This commit improves that behavior by sending only one RPC to get the tags info
in once.
With 5000 tags, there was 5000 RPCs, now there will only be one for the tags.
Also, each RPC were doing 8 requests each, so this will bring requests from
40.000 to 80.
Fixes #45576
closes odoo/odoo#46278
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
80 lines
3.2 KiB
Python
80 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
from odoo import http
|
|
from odoo.http import request
|
|
|
|
|
|
class WebsiteMail(http.Controller):
|
|
|
|
@http.route(['/website_mail/follow'], type='json', auth="public", website=True)
|
|
def website_message_subscribe(self, id=0, object=None, message_is_follower="on", email=False, **post):
|
|
# TDE FIXME: check this method with new followers
|
|
res_id = int(id)
|
|
is_follower = message_is_follower == 'on'
|
|
record = request.env[object].browse(res_id).exists()
|
|
if not record:
|
|
return False
|
|
|
|
record.check_access_rights('read')
|
|
record.check_access_rule('read')
|
|
|
|
# search partner_id
|
|
if request.env.user != request.website.user_id:
|
|
partner_ids = request.env.user.partner_id.ids
|
|
else:
|
|
# mail_thread method
|
|
partner_ids = [p.id for p in request.env['mail.thread'].sudo()._mail_find_partner_from_emails([email], records=record.sudo()) if p]
|
|
if not partner_ids or not partner_ids[0]:
|
|
name = email.split('@')[0]
|
|
partner_ids = request.env['res.partner'].sudo().create({'name': name, 'email': email}).ids
|
|
# add or remove follower
|
|
if is_follower:
|
|
record.sudo().message_unsubscribe(partner_ids)
|
|
return False
|
|
else:
|
|
# add partner to session
|
|
request.session['partner_id'] = partner_ids[0]
|
|
record.sudo().message_subscribe(partner_ids)
|
|
return True
|
|
|
|
@http.route(['/website_mail/is_follower'], type='json', auth="public", website=True)
|
|
def is_follower(self, records, **post):
|
|
""" Given a list of `models` containing a list of res_ids, return
|
|
the res_ids for which the user is follower and some practical info.
|
|
|
|
:param records: dict of models containing record IDS, eg: {
|
|
'res.model': [1, 2, 3..],
|
|
'res.model2': [1, 2, 3..],
|
|
..
|
|
}
|
|
|
|
:returns: [
|
|
{'is_user': True/False, 'email': 'admin@yourcompany.example.com'},
|
|
{'res.model': [1, 2], 'res.model2': [1]}
|
|
]
|
|
"""
|
|
user = request.env.user
|
|
partner = None
|
|
public_user = request.website.user_id
|
|
if user != public_user:
|
|
partner = request.env.user.partner_id
|
|
elif request.session.get('partner_id'):
|
|
partner = request.env['res.partner'].sudo().browse(request.session.get('partner_id'))
|
|
|
|
res = {}
|
|
if partner:
|
|
for model in records:
|
|
mail_followers_ids = request.env['mail.followers'].sudo().read_group([
|
|
('res_model', '=', model),
|
|
('res_id', 'in', records[model]),
|
|
('partner_id', '=', partner.id)
|
|
], ['res_id', 'follow_count:count(id)'], ['res_id'])
|
|
# `read_group` will filter out the ones without count result
|
|
for m in mail_followers_ids:
|
|
res.setdefault(model, []).append(m['res_id'])
|
|
|
|
return [{
|
|
'is_user': user != public_user,
|
|
'email': partner.email if partner else "",
|
|
}, res]
|