[IMP] link_tracker, http_routing: ignore requests from social bots for link tracker
Purpose ======= Avoid counting requests from social bots (twitter, facebook, linkedin...) when tracking a link. Specifications ============= Social media platforms have a specific user agent in the HTTP headers that can be used to detect them and to not increment the click count in that case. Task-2578902 closes odoo/odoo#78806 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
committed by
Thibault Delavallée
parent
66ba1c3c4a
commit
a66cdf3f7f
@@ -327,18 +327,6 @@ class IrHttp(models.AbstractModel):
|
||||
"""
|
||||
return ['web']
|
||||
|
||||
bots = "bot|crawl|slurp|spider|curl|wget|facebookexternalhit".split("|")
|
||||
|
||||
@classmethod
|
||||
def is_a_bot(cls):
|
||||
# We don't use regexp and ustr voluntarily
|
||||
# timeit has been done to check the optimum method
|
||||
user_agent = request.httprequest.environ.get('HTTP_USER_AGENT', '').lower()
|
||||
try:
|
||||
return any(bot in user_agent for bot in cls.bots)
|
||||
except UnicodeDecodeError:
|
||||
return any(bot in user_agent.encode('ascii', 'ignore') for bot in cls.bots)
|
||||
|
||||
@classmethod
|
||||
def _get_frontend_langs(cls):
|
||||
return [code for code, _ in request.env['res.lang'].get_installed()]
|
||||
@@ -385,7 +373,7 @@ class IrHttp(models.AbstractModel):
|
||||
if request.routing_iteration == 1:
|
||||
context = dict(request.context)
|
||||
path = request.httprequest.path.split('/')
|
||||
is_a_bot = cls.is_a_bot()
|
||||
is_a_bot = request.env['ir.http'].is_a_bot()
|
||||
|
||||
lang_codes = [code for code, *_ in Lang.get_available()]
|
||||
nearest_lang = not func and cls.get_nearest_lang(Lang._lang_get_code(path[1]))
|
||||
@@ -462,7 +450,7 @@ class IrHttp(models.AbstractModel):
|
||||
path = request.httprequest.path.split('/')
|
||||
default_lg_id = cls._get_default_lang()
|
||||
if request.routing_iteration == 1:
|
||||
is_a_bot = cls.is_a_bot()
|
||||
is_a_bot = request.env['ir.http'].is_a_bot()
|
||||
nearest_lang = not func and cls.get_nearest_lang(request.env['res.lang']._lang_get_code(path[1]))
|
||||
url_lg = nearest_lang and path[1]
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
@@ -9,11 +11,15 @@ class LinkTracker(http.Controller):
|
||||
|
||||
@http.route('/r/<string:code>', type='http', auth='public', website=True)
|
||||
def full_url_redirect(self, code, **post):
|
||||
country_code = request.session.geoip and request.session.geoip.get('country_code') or False
|
||||
request.env['link.tracker.click'].sudo().add_click(
|
||||
code,
|
||||
ip=request.httprequest.remote_addr,
|
||||
country_code=country_code
|
||||
)
|
||||
if not request.env['ir.http'].is_a_bot():
|
||||
country_code = request.session.geoip and request.session.geoip.get(
|
||||
'country_code') or False
|
||||
request.env['link.tracker.click'].sudo().add_click(
|
||||
code,
|
||||
ip=request.httprequest.remote_addr,
|
||||
country_code=country_code,
|
||||
)
|
||||
redirect_url = request.env['link.tracker'].get_url_from_code(code)
|
||||
return request.redirect(redirect_url or '', code=301, local=False)
|
||||
if not redirect_url:
|
||||
raise NotFound()
|
||||
return request.redirect(redirect_url, code=301, local=False)
|
||||
|
||||
@@ -16,6 +16,15 @@ from odoo.addons.web.controllers.main import HomeStaticTemplateHelpers
|
||||
class Http(models.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
bots = ["bot", "crawl", "slurp", "spider", "curl", "wget", "facebookexternalhit", "whatsapp", "trendsmapresolver", "pinterest", "instagram"]
|
||||
|
||||
@classmethod
|
||||
def is_a_bot(cls):
|
||||
user_agent = request.httprequest.user_agent.string.lower()
|
||||
# We don't use regexp and ustr voluntarily
|
||||
# timeit has been done to check the optimum method
|
||||
return any(bot in user_agent for bot in cls.bots)
|
||||
|
||||
def webclient_rendering_context(self):
|
||||
return {
|
||||
'menu_data': request.env['ir.ui.menu'].load_menus(request.session.debug),
|
||||
|
||||
Reference in New Issue
Block a user