Files
odoo_source/addons/website_event_track_session/models/event_track.py
T
Thibault Delavallée 0f5b57523a [FIX] website_event_track_session: sanitize cta url
Sanitize URL given to CTA button, allowing to ensure it has a netloc and a
scheme. Otherwise URLs may be considered as local whereas they are not
(e.g. www.example.com).

LINKS

Related to testing of EventOnline
Task ID-2314778
Fwd port of PR #55625
PR #55642
2020-08-13 06:30:33 +00:00

156 lines
6.7 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import timedelta
from random import randint
from pytz import utc
from odoo import api, fields, models
from odoo.osv import expression
class EventTrack(models.Model):
_inherit = "event.track"
# Call to action
website_cta = fields.Boolean('Magic Button')
website_cta_title = fields.Char('Button Title')
website_cta_url = fields.Char('Button Target URL')
website_cta_delay = fields.Integer('Button appears')
# time information for track
is_track_live = fields.Boolean(
'Is Track Live', compute='_compute_track_time_data',
help="Track has started and is ongoing")
is_track_soon = fields.Boolean(
'Is Track Soon', compute='_compute_track_time_data',
help="Track begins soon")
is_track_today = fields.Boolean(
'Is Track Today', compute='_compute_track_time_data',
help="Track begins today")
is_track_upcoming = fields.Boolean(
'Is Track Upcoming', compute='_compute_track_time_data',
help="Track is not yet started")
is_track_done = fields.Boolean(
'Is Track Done', compute='_compute_track_time_data',
help="Track is finished")
track_start_remaining = fields.Integer(
'Minutes before track starts', compute='_compute_track_time_data',
help="Remaining time before track starts (seconds)")
track_start_relative = fields.Integer(
'Minutes compare to track start', compute='_compute_track_time_data',
help="Relative time compared to track start (seconds)")
# time information for CTA
is_website_cta_live = fields.Boolean(
'Is CTA Live', compute='_compute_cta_time_data',
help="CTA button is available")
website_cta_start_remaining = fields.Integer(
'Minutes before CTA starts', compute='_compute_cta_time_data',
help="Remaining time before CTA starts (seconds)")
@api.depends('date', 'date_end')
def _compute_track_time_data(self):
""" Compute start and remaining time for track itself. Do everything in
UTC as we compute only time deltas here. """
now_utc = utc.localize(fields.Datetime.now().replace(microsecond=0))
for track in self:
if not track.date:
track.is_track_live = track.is_track_soon = track.is_track_today = track.is_track_upcoming = track.is_track_done = False
track.track_start_relative = track.track_start_remaining = 0
continue
date_begin_utc = utc.localize(track.date, is_dst=False)
date_end_utc = utc.localize(track.date_end, is_dst=False)
track.is_track_live = date_begin_utc <= now_utc < date_end_utc
track.is_track_soon = (date_begin_utc - now_utc).total_seconds() < 30*60 if date_begin_utc > now_utc else False
track.is_track_today = date_begin_utc.date() == now_utc.date()
track.is_track_upcoming = date_begin_utc > now_utc
track.is_track_done = date_end_utc <= now_utc
if date_begin_utc >= now_utc:
track.track_start_relative = int((date_begin_utc - now_utc).total_seconds())
track.track_start_remaining = track.track_start_relative
else:
track.track_start_relative = int((now_utc - date_begin_utc).total_seconds())
track.track_start_remaining = 0
@api.depends('date', 'date_end', 'website_cta', 'website_cta_delay')
def _compute_cta_time_data(self):
""" Compute start and remaining time for track itself. Do everything in
UTC as we compute only time deltas here. """
now_utc = utc.localize(fields.Datetime.now().replace(microsecond=0))
for track in self:
if not track.website_cta:
track.is_website_cta_live = track.website_cta_start_remaining = False
continue
date_begin_utc = utc.localize(track.date, is_dst=False) + timedelta(minutes=track.website_cta_delay or 0)
date_end_utc = utc.localize(track.date_end, is_dst=False)
track.is_website_cta_live = date_begin_utc <= now_utc <= date_end_utc
if date_begin_utc >= now_utc:
td = date_begin_utc - now_utc
track.website_cta_start_remaining = int(td.total_seconds())
else:
track.website_cta_start_remaining = 0
@api.model_create_multi
def create(self, values_list):
for values in values_list:
if values.get('website_cta_url'):
values['website_cta_url'] = self.env['res.partner']._clean_website(values['website_cta_url'])
return super(EventTrack, self).create(values_list)
def write(self, values):
if values.get('website_cta_url'):
values['website_cta_url'] = self.env['res.partner']._clean_website(values['website_cta_url'])
return super(EventTrack, self).write(values)
def _get_track_suggestions(self, restrict_domain=None, limit=None):
""" Returns the next tracks suggested after going to the current one
given by self. Tracks always belong to the same event.
Heuristic is
* live first;
* then ordered by start date, finished being sent to the end;
* wishlisted (manually or by default);
* tag matching with current track;
* location matching with current track;
* finally a random to have an "equivalent wave" randomly given;
:param restrict_domain: an additional domain to restrict candidates;
:param limit: number of tracks to return;
"""
self.ensure_one()
base_domain = [
'&',
('event_id', '=', self.event_id.id),
('id', '!=', self.id),
]
if restrict_domain:
base_domain = expression.AND([
base_domain,
restrict_domain
])
track_candidates = self.search(base_domain, limit=None, order='date asc')
if not track_candidates:
return track_candidates
track_candidates = track_candidates.sorted(
lambda track:
(track.is_published,
track.is_track_live,
track.track_start_remaining > 0,
-1 * track.track_start_remaining,
track.is_reminder_on,
not track.wishlisted_by_default,
len(track.tag_ids & self.tag_ids),
track.location_id == self.location_id,
randint(0, 20),
), reverse=True
)
return track_candidates[:limit]
def get_backend_menu_id(self):
return self.env.ref('event.event_main_menu').id