Les événements correspondant aux sources ne sont pas éditables,

on créé un clône à la place
This commit is contained in:
Jean-Marie Favreau 2024-11-08 23:12:15 +01:00
parent 28ca7b1b03
commit 4c5decd682
10 changed files with 107 additions and 26 deletions

View File

@ -77,7 +77,6 @@ class EventForm(ModelForm):
class Meta:
model = Event
exclude = [
"other_versions",
"imported_date",
"modified_date",
"moderated_date",
@ -100,6 +99,7 @@ class EventForm(ModelForm):
"end_day": TextInput(attrs={"type": "date"}),
"end_time": TextInput(attrs={"type": "time"}),
"uuids": MultipleHiddenInput(),
"other_versions": HiddenInput(),
"import_sources": MultipleHiddenInput(),
"reference_urls": DynamicArrayWidgetURLs(),
"tags": DynamicArrayWidgetTags(),
@ -107,12 +107,17 @@ class EventForm(ModelForm):
def __init__(self, *args, **kwargs):
is_authenticated = kwargs.pop("is_authenticated", False)
self.cloning = kwargs.pop("is_cloning", False)
super().__init__(*args, **kwargs)
if not is_authenticated:
del self.fields["status"]
self.fields['category'].queryset = self.fields['category'].queryset.order_by('name')
self.fields['category'].empty_label = None
self.fields['category'].initial = Category.get_default_category()
logger.warning("ça se passe là")
def is_clone_from_url(self):
return self.cloning
def clean_end_day(self):
start_day = self.cleaned_data.get("start_day")

View File

@ -642,9 +642,34 @@ class Event(models.Model):
def modified(self):
return (
not self.modified_date is None
not self.pure_import()
and (self.modified_date - self.created_date).total_seconds() > 1
)
def pure_import(self):
if self.imported_date is None:
return False
return self.modified_date is None or (self.modified_date - self.imported_date).total_seconds() <= 0
def get_local_version(self):
# a non-pure import is a local version
if not self.pure_import():
return self
# in case of non other version, return None
if self.other_versions is None:
return None
# otherwise check the representative version
if not self.other_versions.representative is None:
if self.other_versions.representative.modified():
return self.other_versions.representative
# finally, get the last modified version within the other versions
e = [e for e in self.other_versions.event_set.order_by("-modified_date") if e.modified]
return None if len(e) == 0 else e[0]
def nb_draft_events():
return Event.objects.filter(status=Event.STATUS.DRAFT).count()
@ -834,11 +859,12 @@ class Event(models.Model):
if len(similar_events) != 0:
self.set_other_versions(similar_events)
# delete duplicated group if it's only with one element
if (
self.pk and
self.other_versions is not None
and self.other_versions.nb_duplicated() == 1
):
logger.warning("le other est juste dans ", self.other_versions.event_set.all())
self.other_versions.delete()
self.other_versions = None
@ -1003,6 +1029,14 @@ class Event(models.Model):
return True
return False
def get_other_not_trash_versions(self):
if self.other_versions is None:
return []
else:
return Event.objects.filter(
other_versions=self.other_versions
).filter(~Q(status=Event.STATUS.TRASH)).exclude(pk=self.pk)
def get_other_versions(self):
if self.other_versions is None:
return []
@ -1012,7 +1046,7 @@ class Event(models.Model):
).exclude(pk=self.pk)
def masked(self):
return self.other_versions and self.other_versions.representative == self
return self.other_versions and self.other_versions.representative != self
def get_comparison(events, all=True):
result = []

View File

@ -9,10 +9,13 @@
</div>
<ul>
<li>{{ e|picto_status }} <a href="{{ e.get_absolute_url }}">{{ e.title }}</a></li>
<li>Masqué&nbsp;: {{ e.masked|yesno:"Oui,Non" }}</li>
<li>Création&nbsp;: {{ e.created_date }}</li>
<li>Dernière modification&nbsp;: {{ e.modified_date }}</li>
{% if e.imported_date %}<li>Dernière importation&nbsp;: {{ e.imported_date }}</li>{% endif %}
<li>État&nbsp;:
{% if e.pure_import %}version fidèle à la source importée{% endif %}
{% if e.modified %}version modifiée localement{% endif %}
</li>
</ul>
</div>
{% endfor %}

View File

@ -1,13 +1,23 @@
{% load utils_extra %}
<!-- a href="{% url 'moderate_event' event.id %}" role="button">modérer {% picto_from_name "edit" %}</a-->
{% if event.pure_import %}
{% with event.get_local_version as local %}
{% if local %}
<a href="{{ local.get_absolute_url }}" role="button">voir la version locale {% picto_from_name "eye" %}</a>
{% else %}
<a href="{% url 'clone_edit' event.id %}" role="button">créer une copie locale {% picto_from_name "plus-circle" %}</a>
{% endif %}
{% endwith %}
{% else %}
<a href="{% url 'edit_event' event.id %}" role="button">modifier {% picto_from_name "edit-3" %}</a>
{% endif %}
{% if event.is_updateable %}
<a href="{% url 'update_from_source' event.id %}" role="button">Réimporter {% picto_from_name "download-cloud" %}</a>
{% endif %}
<!-- a href="{% url 'moderate_event' event.id %}" role="button">modérer {% picto_from_name "edit" %}</a-->
<a href="{% url 'edit_event' event.id %}" role="button">modifier {% picto_from_name "edit-3" %}</a>
{% if event.status != "published" %}
<a href="{% url 'change_status_event' event.id 'published' %}" role="button">publier {% picto_from_name "eye" %}</a>
{% endif %}

View File

@ -5,7 +5,6 @@
{% if object.modified_date %}<li>Dernière modification&nbsp;: {{ object.modified_date }}</li>{% endif %}
{% if object.moderated_date %}<li>Dernière modération&nbsp;: {{ object.moderated_date }}</li>{% endif %}
{% if object.imported_date %}<li>Dernière importation&nbsp;: {{ object.imported_date }}</li>{% endif %}
<li>Masqué&nbsp;: {{ object.masked }}</li>
{% if object.uuids %}
{% if object.uuids|length > 0 %}
<li>UUIDs (identifiants uniques d'événements dans les sources)&nbsp;:

View File

@ -3,8 +3,10 @@
{% block title %}{% block og_title %}
{% if object %}
{% if object %}{% if form.is_clone_from_url %}
Création d'une copie de {% else %}
Édition de l'événement {{ object.title }} ({{ object.start_day }})
{% endif %}
{% else %}
{% if from_import %}
Ajuster l'événement importé
@ -40,13 +42,14 @@
{% block content %}
{% load static_content_extra %}
<article>
<header>
{% if object %}
<h1>Édition de l'événement {{ object.title }} ({{ object.start_day }})</h1>
<h1>{% if form.is_clone_from_url %}
Création d'une copie de {% else %}
Édition de l'événement{% endif %} {{ object.title }} ({{ object.start_day }})</h1>
{% else %}
{% if from_import %}
<h1>Ajuster l'événement importé</h1>
@ -58,7 +61,10 @@
</header>
<div id="container"></div>
<form method="post" enctype="multipart/form-data">{% csrf_token %}
{% if form.is_clone_from_url %}
{% url "add_event_details" as urlparam %}
{% endif %}
<form method="post" action="{{ urlparam }}" enctype="multipart/form-data">{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<div class="grid buttons">
@ -66,6 +72,7 @@
<input type="submit" value="Enregistrer">
</div>
</form>
{% if object %}
{% include "agenda_culturel/event-info-inc.html" %}
{% endif %}

View File

@ -87,15 +87,15 @@
{% if event.other_versions %}
{% with poss_dup=event.get_other_versions|only_allowed:user.is_authenticated %}
{% if poss_dup.count > 0 %}
<article>
<article id="liste-dupliques">
<header>
{% if event.other_versions.representative %}
<h2>Sources multiples</h2>
<p class="remarque">L'événement affiché a également été trouvé à partir
<p class="remarque">L'événement affiché est également disponible
{% if poss_dup.count == 1 %}
d'une autre source
dans une autre version
{% else %}
d'autres sources
dans d'autres versions
{% endif %}&nbsp;:</p>
{% else %}
<h2>Possibles doublons</h2>

View File

@ -19,18 +19,18 @@
{% include "agenda_culturel/event-location-inc.html" with event=event %}
</p>
{% if event.other_versions %}
{% with poss_dup=event.get_other_versions|only_allowed:user.is_authenticated %}
{% with poss_dup=event.get_other_not_trash_versions|only_allowed:user.is_authenticated %}
{% if poss_dup.count > 0 %}
<p class="remarque">
{% if event.other_versions.representative %}
cet événement a été {% if user.is_authenticated %}<a href="{{ event.other_versions.get_absolute_url }}">importé plusieurs fois</a>{% else %}importé plusieurs fois{% endif %},
cet événement existe <a href="{% if user.is_authenticated %}{{ event.other_versions.get_absolute_url }}{% else %}#liste-dupliques{% endif %}">en plusieurs versions</a>,
{% if event.masked %}
vous pouvez <a href="{{ event.other_versions.get_one_event.get_absolute_url }}">consulter l'import principal</a>
vous pouvez consulter <a href="{{ event.other_versions.get_one_event.get_absolute_url }}">la version mise en avant</a>
{% else %}
et vous consultez l'import principal
et vous consultez la version mise en avant
{% endif %}
{% else %}
cet événement a probablement été {% if user.is_authenticated %}<a href="{{ event.other_versions.get_absolute_url }}">importé plusieurs fois</a>{% else %}importé plusieurs fois{% endif %}
cet événement existe probablement <a href="{% if user.is_authenticated %}{{ event.other_versions.get_absolute_url }}{% else %}#liste-dupliques{% endif %}">en plusieurs versions</a>
{% endif %}
</p>
{% endif %}
@ -83,9 +83,16 @@
{% if event.modified %}
— dernière modification&nbsp;: {{ event.modified_date }}
{% endif %}
{% if event.imported_date %}
— dernière importation&nbsp;: {{ event.imported_date }}
{% endif %}
{% if event.moderated_date %}
— dernière modération&nbsp;: {{ event.moderated_date }}
{% endif %}
{% if event.pure_import %}
<strong>version importée</strong>
{% endif %}
{{ event.delai }}
</p>
</div>
<div class="buttons">

View File

@ -30,6 +30,7 @@ urlpatterns = [
name="view_event",
),
path("event/<int:pk>/edit", EventUpdateView.as_view(), name="edit_event"),
path("event/<int:pk>/clone/edit", EventUpdateView.as_view(), name="clone_edit"),
path("event/<int:pk>/update-from-source", update_from_source, name="update_from_source"),
path(
"event/<int:pk>/change-status/<status>",

View File

@ -563,12 +563,22 @@ class EventUpdateView(
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
if not self.get_object().modified():
messages.warning(self.request, _("Please note that this event has not been modified since it was last updated by import. If you modify any information from this import, the event will be desynchronized with the source, and will need to be merged with each future automatic import."))
kwargs["is_authenticated"] = self.request.user.is_authenticated
kwargs["is_cloning"] = self.is_cloning
return kwargs
def get_initial(self):
self.is_cloning = "clone" in self.request.path.split('/')
result = super().get_initial()
if self.is_cloning and not "other_versions" in result:
obj = self.get_object()
# if no DuplicatedEvents is associated, create one
obj.other_versions = DuplicatedEvents.objects.create()
obj.other_versions.save()
obj.save()
result["other_versions"] = obj.other_versions
return result
class EventDeleteView(
SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, DeleteView
@ -653,7 +663,6 @@ def import_event_proxy(request):
class EventCreateView(SuccessMessageMixin, CreateView):
model = Event
success_url = reverse_lazy("home")
form_class = EventForm
def get_form_kwargs(self):
@ -661,6 +670,12 @@ class EventCreateView(SuccessMessageMixin, CreateView):
kwargs["is_authenticated"] = self.request.user.is_authenticated
return kwargs
def get_success_url(self):
if self.request.user.is_authenticated:
return self.object.get_absolute_url()
else:
return reverse_lazy("home")
def get_success_message(self, cleaned_data):
if self.request.user.is_authenticated:
return mark_safe(_('The event was created: <a href="{}">{}</a>.').format(self.object.get_absolute_url(), self.object.title))