Files
odoo_source/addons/website_mail/controllers/main.py
T
Romain Derie c593e7d598 [FIX] website_mail: avoid sending too many RPCs
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>
2020-02-27 16:54:25 +00:00

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]