On enregistre l'auteur d'une modification

Fix #228
This commit is contained in:
Jean-Marie Favreau 2024-11-29 19:35:45 +01:00
parent c55ed5c4dc
commit 7f1bbabebf
8 changed files with 113 additions and 16 deletions

View File

@ -291,7 +291,7 @@ def weekly_imports(self):
run_recurrent_imports_from_list([imp.pk for imp in imports]) run_recurrent_imports_from_list([imp.pk for imp in imports])
@app.task(base=ChromiumTask, bind=True) @app.task(base=ChromiumTask, bind=True)
def import_events_from_url(self, url, cat, tags, force=False): def import_events_from_url(self, url, cat, tags, force=False, user_id=None):
from .db_importer import DBImporterEvents from .db_importer import DBImporterEvents
from agenda_culturel.models import RecurrentImport, BatchImportation from agenda_culturel.models import RecurrentImport, BatchImportation
from agenda_culturel.models import Event, Category from agenda_culturel.models import Event, Category
@ -337,7 +337,7 @@ def import_events_from_url(self, url, cat, tags, force=False):
json_events = json.dumps(events, default=str) json_events = json.dumps(events, default=str)
# import events (from json) # import events (from json)
success, error_message = importer.import_events(json_events) success, error_message = importer.import_events(json_events, user_id)
# finally, close task # finally, close task
close_import_task(self.request.id, success, error_message, importer) close_import_task(self.request.id, success, error_message, importer)
@ -354,14 +354,14 @@ def import_events_from_url(self, url, cat, tags, force=False):
@app.task(base=ChromiumTask, bind=True) @app.task(base=ChromiumTask, bind=True)
def import_events_from_urls(self, urls_cat_tags): def import_events_from_urls(self, urls_cat_tags, user_id=None):
for ucat in urls_cat_tags: for ucat in urls_cat_tags:
if ucat is not None: if ucat is not None:
url = ucat[0] url = ucat[0]
cat = ucat[1] cat = ucat[1]
tags = ucat[2] tags = ucat[2]
import_events_from_url.delay(url, cat, tags) import_events_from_url.delay(url, cat, tags, user_id=user_id)
app.conf.beat_schedule = { app.conf.beat_schedule = {

View File

@ -11,6 +11,7 @@ class DBImporterEvents:
def __init__(self, celery_id): def __init__(self, celery_id):
self.celery_id = celery_id self.celery_id = celery_id
self.error_message = "" self.error_message = ""
self.user_id = None
self.init_result_properties() self.init_result_properties()
self.today = timezone.now().date().isoformat() self.today = timezone.now().date().isoformat()
@ -34,9 +35,10 @@ class DBImporterEvents:
def get_nb_removed_events(self): def get_nb_removed_events(self):
return self.nb_removed return self.nb_removed
def import_events(self, json_structure): def import_events(self, json_structure, user_id=None):
print(json_structure) print(json_structure)
self.init_result_properties() self.init_result_properties()
self.user_id = user_id
try: try:
structure = json.loads(json_structure) structure = json.loads(json_structure)
@ -95,7 +97,7 @@ class DBImporterEvents:
def save_imported(self): def save_imported(self):
self.db_event_objects, self.nb_updated, self.nb_removed = Event.import_events( self.db_event_objects, self.nb_updated, self.nb_removed = Event.import_events(
self.event_objects, remove_missing_from_source=self.url self.event_objects, remove_missing_from_source=self.url, user_id=self.user_id
) )
def is_valid_event_structure(self, event): def is_valid_event_structure(self, event):

View File

@ -205,7 +205,11 @@ class EventForm(GroupFormMixin, ModelForm):
"modified_date", "modified_date",
"moderated_date", "moderated_date",
"import_sources", "import_sources",
"image" "image",
"moderated_by_user",
"modified_by_user",
"created_by_user",
"imported_by_user"
] ]
widgets = { widgets = {
"start_day": TextInput( "start_day": TextInput(

View File

@ -0,0 +1,36 @@
# Generated by Django 4.2.9 on 2024-11-29 18:18
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('agenda_culturel', '0122_alter_recurrentimport_processor'),
]
operations = [
migrations.AddField(
model_name='event',
name='created_by_user',
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='created_events', to=settings.AUTH_USER_MODEL, verbose_name='Author of the event creation'),
),
migrations.AddField(
model_name='event',
name='imported_by_user',
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='imported_events', to=settings.AUTH_USER_MODEL, verbose_name='Author of the last importation'),
),
migrations.AddField(
model_name='event',
name='moderated_by_user',
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='moderated_events', to=settings.AUTH_USER_MODEL, verbose_name='Author of the last moderation'),
),
migrations.AddField(
model_name='event',
name='modified_by_user',
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='modified_events', to=settings.AUTH_USER_MODEL, verbose_name='Author of the last modification'),
),
]

View File

@ -10,6 +10,7 @@ from colorfield.fields import ColorField
from django_ckeditor_5.fields import CKEditor5Field from django_ckeditor_5.fields import CKEditor5Field
from urllib.parse import urlparse from urllib.parse import urlparse
from django.core.cache import cache from django.core.cache import cache
from django.contrib.auth.models import User
import emoji import emoji
import hashlib import hashlib
@ -558,6 +559,39 @@ class Event(models.Model):
modified_date = models.DateTimeField(blank=True, null=True) modified_date = models.DateTimeField(blank=True, null=True)
moderated_date = models.DateTimeField(blank=True, null=True) moderated_date = models.DateTimeField(blank=True, null=True)
created_by_user = models.ForeignKey(
User,
verbose_name=_("Author of the event creation"),
null=True,
default=None,
on_delete=models.SET_DEFAULT,
related_name="created_events"
)
imported_by_user = models.ForeignKey(
User,
verbose_name=_("Author of the last importation"),
null=True,
default=None,
on_delete=models.SET_DEFAULT,
related_name="imported_events"
)
modified_by_user = models.ForeignKey(
User,
verbose_name=_("Author of the last modification"),
null=True,
default=None,
on_delete=models.SET_DEFAULT,
related_name="modified_events"
)
moderated_by_user = models.ForeignKey(
User,
verbose_name=_("Author of the last moderation"),
null=True,
default=None,
on_delete=models.SET_DEFAULT,
related_name="moderated_events"
)
recurrence_dtstart = models.DateTimeField(editable=False, blank=True, null=True) recurrence_dtstart = models.DateTimeField(editable=False, blank=True, null=True)
recurrence_dtend = models.DateTimeField(editable=False, blank=True, null=True) recurrence_dtend = models.DateTimeField(editable=False, blank=True, null=True)
@ -692,6 +726,10 @@ class Event(models.Model):
blank=True, blank=True,
) )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.processing_user = None
def get_consolidated_end_day(self, intuitive=True): def get_consolidated_end_day(self, intuitive=True):
if intuitive: if intuitive:
end_day = self.get_consolidated_end_day(False) end_day = self.get_consolidated_end_day(False)
@ -896,6 +934,9 @@ class Event(models.Model):
def set_no_modification_date_changed(self): def set_no_modification_date_changed(self):
self.no_modification_date_changed = True self.no_modification_date_changed = True
def set_processing_user(self, user):
self.processing_user = user
def set_in_moderation_process(self): def set_in_moderation_process(self):
self.in_moderation_process = True self.in_moderation_process = True
@ -906,12 +947,16 @@ class Event(models.Model):
now = timezone.now() now = timezone.now()
if not self.id: if not self.id:
self.created_date = now self.created_date = now
self.created_by_user = self.processing_user
if self.is_in_importation_process(): if self.is_in_importation_process():
self.imported_date = now self.imported_date = now
self.imported_by_user = self.processing_user
if self.modified_date is None or not self.is_no_modification_date_changed(): if self.modified_date is None or not self.is_no_modification_date_changed():
self.modified_date = now self.modified_date = now
self.modified_by_user = self.processing_user
if self.is_in_moderation_process(): if self.is_in_moderation_process():
self.moderated_date = now self.moderated_date = now
self.moderated_by_user = self.processing_user
def get_recurrence_at_date(self, year, month, day): def get_recurrence_at_date(self, year, month, day):
dtstart = timezone.make_aware( dtstart = timezone.make_aware(
@ -1412,7 +1457,11 @@ class Event(models.Model):
self.import_sources.append(source) self.import_sources.append(source)
# Limitation: the given events should not be considered similar one to another... # Limitation: the given events should not be considered similar one to another...
def import_events(events, remove_missing_from_source=None): def import_events(events, remove_missing_from_source=None, user_id=None):
user = None
if user_id:
user = User.objects.filter(pk=user_id).first()
to_import = [] to_import = []
to_update = [] to_update = []
@ -1439,6 +1488,7 @@ class Event(models.Model):
# imported events should be updated # imported events should be updated
event.set_in_importation_process() event.set_in_importation_process()
event.set_processing_user(user)
event.prepare_save() event.prepare_save()
# check if the event has already be imported (using uuid) # check if the event has already be imported (using uuid)

View File

@ -1,10 +1,10 @@
<footer class="remarque"> <footer class="remarque">
Informations complémentaires non éditables&nbsp;: Informations complémentaires non éditables&nbsp;:
<ul> <ul>
{% if object.created_date %}<li>Création&nbsp;: {{ object.created_date }}</li>{% endif %} {% if object.created_date %}<li>Création&nbsp;: {{ object.created_date }}{% if object.created_by_user %} par <em>{{ object.created_by_user.username }}</em>{% endif %}</li>{% endif %}
{% if object.modified_date %}<li>Dernière modification&nbsp;: {{ object.modified_date }}</li>{% endif %} {% if object.modified_date %}<li>Dernière modification&nbsp;: {{ object.modified_date }}{% if object.modified_by_user %} par <em>{{ object.modified_by_user.username }}</em>{% endif %}</li>{% endif %}
{% if object.moderated_date %}<li>Dernière modération&nbsp;: {{ object.moderated_date }}</li>{% endif %} {% if object.moderated_date %}<li>Dernière modération&nbsp;: {{ object.moderated_date }}{% if object.moderated_by_user %} par <em>{{ object.moderated_by_user.username }}</em>{% endif %}</li>{% endif %}
{% if object.imported_date %}<li>Dernière importation&nbsp;: {{ object.imported_date }}</li>{% endif %} {% if object.imported_date %}<li>Dernière importation&nbsp;: {{ object.imported_date }}{% if object.imported_by_user %} par <em>{{ object.imported_by_user.username }}</em>{% endif %}</li>{% endif %}
{% if object.uuids %} {% if object.uuids %}
{% if object.uuids|length > 0 %} {% if object.uuids|length > 0 %}
<li>UUIDs (identifiants uniques d'événements dans les sources)&nbsp;: <li>UUIDs (identifiants uniques d'événements dans les sources)&nbsp;:

View File

@ -57,7 +57,7 @@
<h2>Modification des méta-informations</h2> <h2>Modification des méta-informations</h2>
{% if event.moderated_date %} {% if event.moderated_date %}
<p class="message info">Cet événement a déjà été modéré par le {{ event.moderated_date }}. <p class="message info">Cet événement a déjà été modéré {% if event.moderation_by_user %}par {<em>{ event.moderation_by_user.username }}</em> {% endif %}le {{ event.moderated_date }}.
Vous pouvez bien sûr modifier de nouveau ces méta-informations en utilisant Vous pouvez bien sûr modifier de nouveau ces méta-informations en utilisant
le formulaire ci-après. le formulaire ci-après.
</p> </p>

View File

@ -293,7 +293,7 @@ def update_from_source(request, pk):
if url is None: if url is None:
messages.warning(request, _("The event cannot be updated because the import process is not available for the referenced sources.")) messages.warning(request, _("The event cannot be updated because the import process is not available for the referenced sources."))
else: else:
import_events_from_url.delay(url, None, True) import_events_from_url.delay(url, None, True, user_id=request.user.pk if request.user else None)
messages.success(request, _("The event update has been queued and will be completed shortly.")) messages.success(request, _("The event update has been queued and will be completed shortly."))
return HttpResponseRedirect(event.get_absolute_url()) return HttpResponseRedirect(event.get_absolute_url())
@ -313,6 +313,10 @@ class EventUpdateView(
kwargs["is_simple_cloning"] = self.is_simple_cloning kwargs["is_simple_cloning"] = self.is_simple_cloning
return kwargs return kwargs
def form_valid(self, form):
form.instance.set_processing_user(self.request.user)
return super().form_valid(form)
def get_initial(self): def get_initial(self):
self.is_cloning = "clone" in self.request.path.split('/') self.is_cloning = "clone" in self.request.path.split('/')
self.is_simple_cloning = "simple-clone" in self.request.path.split('/') self.is_simple_cloning = "simple-clone" in self.request.path.split('/')
@ -408,6 +412,7 @@ class EventModerateView(
def form_valid(self, form): def form_valid(self, form):
form.instance.set_no_modification_date_changed() form.instance.set_no_modification_date_changed()
form.instance.set_in_moderation_process() form.instance.set_in_moderation_process()
form.instance.set_processing_user(self.request.user)
return super().form_valid(form) return super().form_valid(form)
def get_success_url(self): def get_success_url(self):
@ -640,7 +645,7 @@ def import_from_urls(request):
request, request,
_('Integrating {} url(s) into our import process.').format(len(ucat)) _('Integrating {} url(s) into our import process.').format(len(ucat))
) )
import_events_from_urls.delay(ucat) import_events_from_urls.delay(ucat, user_id=request.user.pk if request.user else None)
return HttpResponseRedirect(reverse("thank_you")) return HttpResponseRedirect(reverse("thank_you"))
else: else:
return HttpResponseRedirect(reverse("home")) return HttpResponseRedirect(reverse("home"))
@ -690,7 +695,7 @@ def import_from_url(request):
request, request,
_('Integrating {} into our import process.').format(uc.url) _('Integrating {} into our import process.').format(uc.url)
) )
import_events_from_url.delay(uc.url, uc.cat, uc.tags) import_events_from_url.delay(uc.url, uc.cat, uc.tags, user_id=request.user.pk if request.user else None)
return HttpResponseRedirect(reverse("thank_you")) return HttpResponseRedirect(reverse("thank_you"))