diff options
Diffstat (limited to 'addons/link_tracker/models/link_tracker.py')
| -rw-r--r-- | addons/link_tracker/models/link_tracker.py | 144 |
1 files changed, 74 insertions, 70 deletions
diff --git a/addons/link_tracker/models/link_tracker.py b/addons/link_tracker/models/link_tracker.py index f5db16a35fc..81c2a03e465 100644 --- a/addons/link_tracker/models/link_tracker.py +++ b/addons/link_tracker/models/link_tracker.py @@ -17,6 +17,7 @@ from odoo.tools import ustr URL_REGEX = r'(\bhref=[\'"](?!mailto:|tel:|sms:)([^\'"]+)[\'"])' + def VALIDATE_URL(url): if urls.url_parse(url).scheme not in ('http', 'https', 'ftp', 'ftps'): return 'http://' + url @@ -24,50 +25,32 @@ def VALIDATE_URL(url): return url -class link_tracker(models.Model): - """link_tracker allow users to wrap any URL into a short and trackable URL. - link_tracker counts clicks on each tracked link. - This module is also used by mass_mailing, where each link in mail_mail html_body are converted into - a trackable link to get the click-through rate of each mass_mailing.""" +class LinkTracker(models.Model): + """ Link trackers allow users to wrap any URL into a short URL that can be + tracked by Odoo. Clicks are counter on each link. A tracker is linked to + UTMs allowing to analyze marketing actions. + This model is also used in mass_mailing where each link in html body is + automatically converted into a short link that is tracked and integrates + UTMs. """ _name = "link.tracker" _rec_name = "short_url" - _description = 'Link Tracker' - - _inherit = ['utm.mixin'] + _description = "Link Tracker" + _inherit = ["utm.mixin"] + # URL info url = fields.Char(string='Target URL', required=True) - count = fields.Integer(string='Number of Clicks', compute='_compute_count', store=True) short_url = fields.Char(string='Tracked URL', compute='_compute_short_url') - link_click_ids = fields.One2many('link.tracker.click', 'link_id', string='Clicks') + redirected_url = fields.Char(string='Redirected URL', compute='_compute_redirected_url') + short_url_host = fields.Char(string='Host of the short URL', compute='_compute_short_url_host') title = fields.Char(string='Page Title', store=True) favicon = fields.Char(string='Favicon', compute='_compute_favicon', store=True) + icon_src = fields.Char(string='Favicon Source', compute='_compute_icon_src') + # Tracking link_code_ids = fields.One2many('link.tracker.code', 'link_id', string='Codes') code = fields.Char(string='Short URL code', compute='_compute_code') - redirected_url = fields.Char(string='Redirected URL', compute='_compute_redirected_url') - short_url_host = fields.Char(string='Host of the short URL', compute='_compute_short_url_host') - icon_src = fields.Char(string='Favicon Source', compute='_compute_icon_src') - - @api.model - def convert_links(self, html, vals, blacklist=None): - for match in re.findall(URL_REGEX, html): - - short_schema = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + '/r/' - - href = match[0] - long_url = match[1] - - vals['url'] = utils.unescape(long_url) - - if not blacklist or not [s for s in blacklist if s in long_url] and not long_url.startswith(short_schema): - link = self.create(vals) - shorten_url = self.browse(link.id)[0].short_url - - if shorten_url: - new_href = href.replace(long_url, shorten_url) - html = html.replace(href, new_href) - - return html + link_click_ids = fields.One2many('link.tracker.click', 'link_id', string='Clicks') + count = fields.Integer(string='Number of Clicks', compute='_compute_count', store=True) @api.one @api.depends('link_click_ids.link_id') @@ -131,32 +114,6 @@ class link_tracker(models.Model): self.favicon = icon_base64 - @api.multi - def action_view_statistics(self): - action = self.env['ir.actions.act_window'].for_xml_id('link_tracker', 'action_view_click_statistics') - action['domain'] = [('link_id', '=', self.id)] - return action - - @api.multi - def action_visit_page(self): - return { - 'name': _("Visit Webpage"), - 'type': 'ir.actions.act_url', - 'url': self.url, - 'target': 'new', - } - - @api.model - def recent_links(self, filter, limit): - if filter == 'newest': - return self.search_read([], order='create_date DESC', limit=limit) - elif filter == 'most-clicked': - return self.search_read([('count', '!=', 0)], order='count DESC', limit=limit) - elif filter == 'recently-used': - return self.search_read([('count', '!=', 0)], order='write_date DESC', limit=limit) - else: - return {'Error': "This filter doesn't exist."} - @api.model def create(self, vals): create_vals = vals.copy() @@ -183,7 +140,7 @@ class link_tracker(models.Model): if fname not in create_vals: create_vals[fname] = False - link = super(link_tracker, self).create(create_vals) + link = super(LinkTracker, self).create(create_vals) code = self.env['link.tracker.code'].get_random_code_string() self.env['link.tracker.code'].sudo().create({'code': code, 'link_id': link.id}) @@ -191,6 +148,53 @@ class link_tracker(models.Model): return link @api.model + def convert_links(self, html, vals, blacklist=None): + for match in re.findall(URL_REGEX, html): + + short_schema = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + '/r/' + + href = match[0] + long_url = match[1] + + vals['url'] = utils.unescape(long_url) + + if not blacklist or not [s for s in blacklist if s in long_url] and not long_url.startswith(short_schema): + link = self.create(vals) + shorten_url = self.browse(link.id)[0].short_url + + if shorten_url: + new_href = href.replace(long_url, shorten_url) + html = html.replace(href, new_href) + + return html + + @api.multi + def action_view_statistics(self): + action = self.env['ir.actions.act_window'].for_xml_id('link_tracker', 'action_view_click_statistics') + action['domain'] = [('link_id', '=', self.id)] + return action + + @api.multi + def action_visit_page(self): + return { + 'name': _("Visit Webpage"), + 'type': 'ir.actions.act_url', + 'url': self.url, + 'target': 'new', + } + + @api.model + def recent_links(self, filter, limit): + if filter == 'newest': + return self.search_read([], order='create_date DESC', limit=limit) + elif filter == 'most-clicked': + return self.search_read([('count', '!=', 0)], order='count DESC', limit=limit) + elif filter == 'recently-used': + return self.search_read([('count', '!=', 0)], order='write_date DESC', limit=limit) + else: + return {'Error': "This filter doesn't exist."} + + @api.model def get_url_from_code(self, code, context=None): code_rec = self.env['link.tracker.code'].sudo().search([('code', '=', code)]) @@ -204,13 +208,17 @@ class link_tracker(models.Model): ] -class link_tracker_code(models.Model): +class LinkTrackerCode(models.Model): _name = "link.tracker.code" - _description = 'Link Tracker Code' + _description = "Link Tracker Code" code = fields.Char(string='Short URL Code', store=True) link_id = fields.Many2one('link.tracker', 'Link', required=True, ondelete='cascade') + _sql_constraints = [ + ('code', 'unique( code )', 'Code must be unique.') + ] + @api.model def get_random_code_string(self): size = 3 @@ -222,18 +230,14 @@ class link_tracker_code(models.Model): else: return code_proposition - _sql_constraints = [ - ('code', 'unique( code )', 'Code must be unique.') - ] - -class link_tracker_click(models.Model): +class LinkTrackerClick(models.Model): _name = "link.tracker.click" _rec_name = "link_id" - _description = 'Link Tracker Click' + _description = "Link Tracker Click" - click_date = fields.Date(string='Create Date') link_id = fields.Many2one('link.tracker', 'Link', required=True, ondelete='cascade') + click_date = fields.Date(string='Create Date') ip = fields.Char(string='Internet Protocol') country_id = fields.Many2one('res.country', 'Country') |
