Ajout mécanisme warnings

This commit is contained in:
Jean-Marie Favreau 2025-02-01 00:02:40 +01:00
parent 4c36079379
commit fd8667d144
4 changed files with 104 additions and 15 deletions

View File

@ -1,11 +1,17 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from enum import IntEnum
from datetime import datetime, time, date, timedelta from datetime import datetime, time, date, timedelta
import re import re
import unicodedata import unicodedata
from django.utils import timezone from django.utils import timezone
import logging
class Extractor(ABC): class Extractor(ABC):
class Warning(IntEnum):
NO_TITLE = 1
NO_START_DATE = 2
url_referer=None url_referer=None
def __init__(self): def __init__(self):
@ -177,16 +183,17 @@ class Extractor(ABC):
image_alt=None, image_alt=None,
): ):
comments = '' comments = ''
warnings = []
if title is None: if title is None:
print("WARNING: cannot publish an event without name") print("WARNING: cannot publish an event without name")
published = False published = False
title = _('Unknown title') title = _('Unknown title')
warnings.append(Extractor.Warning.NO_TITLE)
if start_day is None: if start_day is None:
print("WARNING: cannot publish an event without start day") print("WARNING: cannot publish an event without start day")
published = False published = False
start_day = datetime.now().date().strftime("%Y-%m-%d") start_day = datetime.now().date().strftime("%Y-%m-%d")
comments = 'Warning: the date has not been imported correctly.' warnings.append(Extractor.Warning.NO_START_DATE)
title += ' - Warning: the date has not been imported correctly.'
tags_default = self.default_value_if_exists(default_values, "tags") tags_default = self.default_value_if_exists(default_values, "tags")
if not tags_default: if not tags_default:
@ -206,6 +213,7 @@ class Extractor(ABC):
"image_alt": image_alt, "image_alt": image_alt,
"email": self.default_value_if_exists(default_values, "email"), "email": self.default_value_if_exists(default_values, "email"),
"comments": self.default_value_if_exists(default_values, "comments"), "comments": self.default_value_if_exists(default_values, "comments"),
"warnings": warnings,
} }
if event["comments"] is None: if event["comments"] is None:
event["comments"] = comments event["comments"] = comments

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.9 on 2025-01-29 09:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agenda_culturel', '0137_category_slug'),
]
operations = [
migrations.AlterField(
model_name='message',
name='message_type',
field=models.CharField(choices=[('from_contributor', 'From contributor'), ('import_process', 'Import process'), ('update_process', 'Update process'), ('contact_form', 'Contact form'), ('event_report', 'Event report'), ('from_contrib_no_msg', 'From contributor (without message)')], default=None, max_length=20, null=True, verbose_name='Type'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.9 on 2025-01-31 23:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agenda_culturel', '0138_alter_message_message_type'),
]
operations = [
migrations.AlterField(
model_name='message',
name='message_type',
field=models.CharField(choices=[('from_contributor', 'From contributor'), ('import_process', 'Import process'), ('update_process', 'Update process'), ('contact_form', 'Contact form'), ('event_report', 'Event report'), ('from_contrib_no_msg', 'From contributor (without message)'), ('warning', 'Warning')], default=None, max_length=20, null=True, verbose_name='Type'),
),
]

View File

@ -36,6 +36,7 @@ import copy
import unicodedata import unicodedata
from collections import defaultdict from collections import defaultdict
from .import_tasks.extractor_facebook import FacebookEventExtractor from .import_tasks.extractor_facebook import FacebookEventExtractor
from .import_tasks.extractor import Extractor
from django.template.defaultfilters import date as _date from django.template.defaultfilters import date as _date
from datetime import time, timedelta, date from datetime import time, timedelta, date
@ -768,6 +769,7 @@ class Event(models.Model):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.processing_user = None self.processing_user = None
self._messages = []
def get_import_messages(self): def get_import_messages(self):
return self.message_set.filter(message_type__in=[Message.TYPE.IMPORT_PROCESS, Message.TYPE.UPDATE_PROCESS]).order_by("date") return self.message_set.filter(message_type__in=[Message.TYPE.IMPORT_PROCESS, Message.TYPE.UPDATE_PROCESS]).order_by("date")
@ -798,14 +800,14 @@ class Event(models.Model):
end_date = parse_date(end_date) end_date = parse_date(end_date)
return parse_date(self.start_day) + timedelta(days=min_days) < end_date return parse_date(self.start_day) + timedelta(days=min_days) < end_date
def set_message(self, msg): def add_message(self, msg):
self._message = msg self._messages.append(msg)
def get_message(self): def get_messages(self):
return self._message return self._messages
def has_message(self): def has_message(self):
return hasattr(self, '_message') return len(self._messages) > 0
def contains_date(self, d, intuitive=True): def contains_date(self, d, intuitive=True):
return d >= self.start_day and d <= self.get_consolidated_end_day(intuitive) return d >= self.start_day and d <= self.get_consolidated_end_day(intuitive)
@ -1055,6 +1057,18 @@ class Event(models.Model):
def is_in_moderation_process(self): def is_in_moderation_process(self):
return hasattr(self, "in_moderation_process") return hasattr(self, "in_moderation_process")
def set_invalid_start_date(self):
self.invalid_start_date = True
def has_invalid_start_date(self):
return hasattr(self, "invalid_start_date")
def set_invalid_title(self):
self.invalid_title = True
def has_invalid_title(self):
return hasattr(self, "invalid_title")
def update_modification_dates(self): def update_modification_dates(self):
now = timezone.now() now = timezone.now()
if not self.id: if not self.id:
@ -1283,7 +1297,7 @@ class Event(models.Model):
# save message if required # save message if required
if self.has_message(): if self.has_message():
msg = self.get_message() for msg in self.get_messages():
msg.related_event = self msg.related_event = self
msg.save() msg.save()
@ -1303,8 +1317,15 @@ class Event(models.Model):
def from_structure(event_structure, import_source=None): def from_structure(event_structure, import_source=None):
# organisers is a manytomany relation thus cannot be initialised before creation of the event # organisers is a manytomany relation thus cannot be initialised before creation of the event
organisers = event_structure.pop('organisers', None) organisers = event_structure.pop('organisers', None)
# supplementary information
email = event_structure.pop('email', None) email = event_structure.pop('email', None)
comments = event_structure.pop('comments', None) comments = event_structure.pop('comments', None)
warnings = event_structure.pop('warnings', [])
for w in warnings:
if w == Extractor.Warning.NO_START_DATE:
event_structure["title"] += " - " + _('Warning') + ": " + _('the date has not been imported correctly.')
if "category" in event_structure and event_structure["category"] is not None: if "category" in event_structure and event_structure["category"] is not None:
try: try:
@ -1383,11 +1404,25 @@ class Event(models.Model):
result.add_pending_organisers(organisers) result.add_pending_organisers(organisers)
if email or comments: if email or comments:
has_comments = not comments in ["", None] has_comments = not comments in ["", None]
result.set_message(Message(subject=_('during import process'), result.add_message(Message(subject=_('during import process'),
email=email, email=email,
message=comments, message=comments,
closed=False, closed=False,
message_type=Message.TYPE.FROM_CONTRIBUTOR if has_comments else Message.TYPE.FROM_CONTRIBUTOR_NO_MSG)) message_type=Message.TYPE.FROM_CONTRIBUTOR if has_comments else Message.TYPE.FROM_CONTRIBUTOR_NO_MSG))
for w in warnings:
if w == Extractor.Warning.NO_START_DATE:
result.set_invalid_start_date()
result.add_message(Message(subject=_('warning'),
closed=False,
message=_('the date has not been imported correctly.'),
message_type=Message.TYPE.WARNING))
if w == Extractor.Warning.NO_TITLE:
result.set_invalid_title()
result.add_message(Message(subject=_('warning'),
closed=False,
message=_('the title has not been imported correctly.'),
message_type=Message.TYPE.WARNING))
return result return result
@ -1522,6 +1557,10 @@ class Event(models.Model):
res = Event.get_comparison([self, event], all) res = Event.get_comparison([self, event], all)
for r in res: for r in res:
if not r["similar"]: if not r["similar"]:
if r["key"] == "title" and (self.has_invalid_title() or event.has_invalid_title()):
continue
if r["key"] == "start_date" and (self.has_invalid_start_date() or event.has_invalid_start_date()):
continue
return False return False
return True return True
@ -1606,8 +1645,13 @@ class Event(models.Model):
if other.has_pending_organisers(): if other.has_pending_organisers():
self.organisers.set(other.pending_organisers) self.organisers.set(other.pending_organisers)
logger.warning("process update " + other.title + ' ' + str(other.has_invalid_start_date()))
# set attributes # set attributes
for attr in Event.data_fields(all=all, no_m2m=True): for attr in Event.data_fields(all=all, no_m2m=True):
if attr == "title" and other.has_invalid_title():
continue
if attr == "start_date" and other.has_invalid_start_date():
continue
setattr(self, attr, getattr(other, attr)) setattr(self, attr, getattr(other, attr))
# adjust modified date if required # adjust modified date if required
@ -1735,7 +1779,7 @@ class Event(models.Model):
for e in to_import: for e in to_import:
if e.is_event_long_duration(): if e.is_event_long_duration():
e.status = Event.STATUS.DRAFT e.status = Event.STATUS.DRAFT
e.set_message( e.add_message(
Message(subject=_('Import'), Message(subject=_('Import'),
name=_('import process'), name=_('import process'),
message=_("The duration of the event is a little too long for direct publication. Moderators can choose to publish it or not."), message=_("The duration of the event is a little too long for direct publication. Moderators can choose to publish it or not."),
@ -1749,7 +1793,7 @@ class Event(models.Model):
if ti.has_pending_organisers() and ti.pending_organisers is not None: if ti.has_pending_organisers() and ti.pending_organisers is not None:
i.organisers.set(ti.pending_organisers) i.organisers.set(ti.pending_organisers)
if ti.has_message(): if ti.has_message():
msg = ti.get_message() for msg in ti.get_messages():
msg.related_event = i msg.related_event = i
msg.save() msg.save()
@ -1944,6 +1988,7 @@ class Message(models.Model):
CONTACT_FORM = "contact_form", _("Contact form") CONTACT_FORM = "contact_form", _("Contact form")
EVENT_REPORT = "event_report", _("Event report") EVENT_REPORT = "event_report", _("Event report")
FROM_CONTRIBUTOR_NO_MSG = "from_contrib_no_msg", _("From contributor (without message)") FROM_CONTRIBUTOR_NO_MSG = "from_contrib_no_msg", _("From contributor (without message)")
WARNING = "warning", _("Warning")
class Meta: class Meta:
verbose_name = _("Message") verbose_name = _("Message")