Consolidation de la structure des doublons

This commit is contained in:
Jean-Marie Favreau 2024-11-08 16:23:23 +01:00
parent d756de6993
commit 28ca7b1b03
6 changed files with 264 additions and 263 deletions

View File

@ -154,49 +154,33 @@ class FixDuplicates(Form):
action = ChoiceField() action = ChoiceField()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
nb_events = kwargs.pop("nb_events", None) edup = kwargs.pop("edup", None)
events = edup.event_set.all()
nb_events = edup.event_set.count()
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if nb_events == 2: choices = []
choices = [("NotDuplicates", "Ces événements sont différents")] for i, e in enumerate(events):
if e.status != Event.STATUS.TRASH:
il = auc[i]
choices += [ choices += [
( (
"SelectA", "Select" + il,
"Ces événements sont identiques, on conserve A et on masque B", _("These inputs represent the same event, and {} is selected as the representative version.").format(il)
) )
] ]
choices += [ choices += [
( ("Merge", _("These entries represent the same event, and a new one is created by merging them."))
"SelectB",
"Ces événements sont identiques, on conserve B et on masque A",
)
] ]
choices += [ for i, e in enumerate(events):
("Merge", "Ces événements sont identiques, créé une nouvelle version par fusion") if e.status != Event.STATUS.TRASH:
] il = auc[i]
else:
choices = [("NotDuplicates", "Ces événements sont tous différents")]
for i in auc[0:nb_events]:
choices += [ choices += [
( (
"Remove" + i, "Remove" + il,
"L'événement " _("event {} is different from the others, we make it independent").format(il))
+ i
+ " n'est pas identique aux autres, on le rend indépendant",
)
]
for i in auc[0:nb_events]:
choices += [
(
"Select" + i,
"Ces événements sont identiques, on conserve "
+ i
+ " et on masque les autres",
)
]
choices += [
("Merge", "Ces événements sont identiques, on en créé un nouveau par fusion")
] ]
choices += [("NotDuplicates", _("These events are all different, so we make them independent."))]
self.fields["action"].choices = choices self.fields["action"].choices = choices
@ -248,7 +232,7 @@ class MergeDuplicates(Form):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
choices = [ choices = [
("event" + i, "Valeur de l'événement " + i) for i in auc[0:nb_events] ("event" + i, _("Value of event {}").format(i)) for i in auc[0:nb_events]
] ]
for f in self.duplicates.get_items_comparison(): for f in self.duplicates.get_items_comparison():

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: agenda_culturel\n" "Project-Id-Version: agenda_culturel\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-07 22:56+0100\n" "POT-Creation-Date: 2024-11-08 16:22+0100\n"
"PO-Revision-Date: 2023-10-29 14:16+0000\n" "PO-Revision-Date: 2023-10-29 14:16+0000\n"
"Last-Translator: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n" "Last-Translator: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
"Language-Team: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n" "Language-Team: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
@ -91,8 +91,8 @@ msgid "Evening"
msgstr "Soir" msgstr "Soir"
#: agenda_culturel/forms.py:44 agenda_culturel/models.py:165 #: agenda_culturel/forms.py:44 agenda_culturel/models.py:165
#: agenda_culturel/models.py:191 agenda_culturel/models.py:417 #: agenda_culturel/models.py:191 agenda_culturel/models.py:440
#: agenda_culturel/models.py:1494 agenda_culturel/models.py:1599 #: agenda_culturel/models.py:1512 agenda_culturel/models.py:1617
msgid "Category" msgid "Category"
msgstr "Catégorie" msgstr "Catégorie"
@ -113,33 +113,61 @@ msgstr "L'heure de fin ne peut pas être avant l'heure de début."
msgid "JSON in the format expected for the import." msgid "JSON in the format expected for the import."
msgstr "JSON dans le format attendu pour l'import" msgstr "JSON dans le format attendu pour l'import"
#: agenda_culturel/forms.py:406 #: agenda_culturel/forms.py:169
msgid ""
"These inputs represent the same event, and {} is selected as the "
"representative version."
msgstr ""
"Ces entrées représentent le même événement, et on sélectionne {} comme la "
"version représentative."
#: agenda_culturel/forms.py:173
msgid ""
"These entries represent the same event, and a new one is created by merging "
"them."
msgstr ""
"Ces entrées représentent le même événement, et on en créé une nouvelle en "
"les fusionnant."
#: agenda_culturel/forms.py:181
msgid "event {} is different from the others, we make it independent"
msgstr "L'événement {} est différent des autres, on le rend indépendant."
#: agenda_culturel/forms.py:183
msgid "These events are all different, so we make them independent."
msgstr "Les événements sont tous différents, on les rend indépendants."
#: agenda_culturel/forms.py:235
msgid "Value of event {}"
msgstr "Valeur de l'événement {}"
#: agenda_culturel/forms.py:390
msgid "Apply category {} to the event {}" msgid "Apply category {} to the event {}"
msgstr "Appliquer la catégorie {} à l'événement {}" msgstr "Appliquer la catégorie {} à l'événement {}"
#: agenda_culturel/forms.py:421 agenda_culturel/models.py:341 #: agenda_culturel/forms.py:405 agenda_culturel/models.py:364
#: agenda_culturel/models.py:1651 #: agenda_culturel/models.py:1669
msgid "Place" msgid "Place"
msgstr "Lieu" msgstr "Lieu"
#: agenda_culturel/forms.py:423 #: agenda_culturel/forms.py:407
msgid "Create a missing place" msgid "Create a missing place"
msgstr "Créer un lieu manquant" msgstr "Créer un lieu manquant"
#: agenda_culturel/forms.py:433 #: agenda_culturel/forms.py:417
msgid "Add \"{}\" to the aliases of the place" msgid "Add \"{}\" to the aliases of the place"
msgstr "Ajouter « {} » aux alias du lieu" msgstr "Ajouter « {} » aux alias du lieu"
#: agenda_culturel/forms.py:460 #: agenda_culturel/forms.py:444
msgid "On saving, use aliases to detect all matching events with missing place" msgid "On saving, use aliases to detect all matching events with missing place"
msgstr "" msgstr ""
"Lors de l'enregistrement, utiliser des alias pour détecter tous les " "Lors de l'enregistrement, utiliser des alias pour détecter tous les "
"événements correspondants dont la place est manquante." "événements correspondants dont la place est manquante."
#: agenda_culturel/models.py:49 agenda_culturel/models.py:94 #: agenda_culturel/models.py:49 agenda_culturel/models.py:94
#: agenda_culturel/models.py:172 agenda_culturel/models.py:303 #: agenda_culturel/models.py:172 agenda_culturel/models.py:326
#: agenda_culturel/models.py:320 agenda_culturel/models.py:1366 #: agenda_culturel/models.py:343 agenda_culturel/models.py:1384
#: agenda_culturel/models.py:1440 #: agenda_culturel/models.py:1458
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
@ -199,7 +227,7 @@ msgstr "Catégories"
msgid "Tag name" msgid "Tag name"
msgstr "Nom de l'étiquette" msgstr "Nom de l'étiquette"
#: agenda_culturel/models.py:177 agenda_culturel/models.py:470 #: agenda_culturel/models.py:177 agenda_culturel/models.py:493
msgid "Description" msgid "Description"
msgstr "Description" msgstr "Description"
@ -237,51 +265,51 @@ msgstr ""
msgid "Duplicated events" msgid "Duplicated events"
msgstr "Événements dupliqués" msgstr "Événements dupliqués"
#: agenda_culturel/models.py:303 #: agenda_culturel/models.py:326
msgid "Name of the location" msgid "Name of the location"
msgstr "Nom de la position" msgstr "Nom de la position"
#: agenda_culturel/models.py:306 #: agenda_culturel/models.py:329
msgid "Main" msgid "Main"
msgstr "Principale" msgstr "Principale"
#: agenda_culturel/models.py:307 #: agenda_culturel/models.py:330
msgid "This location is one of the main locations (shown first)." msgid "This location is one of the main locations (shown first)."
msgstr "Cette position est une position principale (affichée en premier)." msgstr "Cette position est une position principale (affichée en premier)."
#: agenda_culturel/models.py:312 #: agenda_culturel/models.py:335
msgid "Reference location" msgid "Reference location"
msgstr "Position de référence" msgstr "Position de référence"
#: agenda_culturel/models.py:313 #: agenda_culturel/models.py:336
msgid "Reference locations" msgid "Reference locations"
msgstr "Positions de référence" msgstr "Positions de référence"
#: agenda_culturel/models.py:320 #: agenda_culturel/models.py:343
msgid "Name of the place" msgid "Name of the place"
msgstr "Nom du lieu" msgstr "Nom du lieu"
#: agenda_culturel/models.py:322 #: agenda_culturel/models.py:345
msgid "Address" msgid "Address"
msgstr "Adresse" msgstr "Adresse"
#: agenda_culturel/models.py:323 #: agenda_culturel/models.py:346
msgid "Address of this place (without city name)" msgid "Address of this place (without city name)"
msgstr "Adresse de ce lieu (sans le nom de la ville)" msgstr "Adresse de ce lieu (sans le nom de la ville)"
#: agenda_culturel/models.py:327 #: agenda_culturel/models.py:350
msgid "City" msgid "City"
msgstr "Ville" msgstr "Ville"
#: agenda_culturel/models.py:327 #: agenda_culturel/models.py:350
msgid "City name" msgid "City name"
msgstr "Nom de la ville" msgstr "Nom de la ville"
#: agenda_culturel/models.py:332 #: agenda_culturel/models.py:355
msgid "Alternative names" msgid "Alternative names"
msgstr "Noms alternatifs" msgstr "Noms alternatifs"
#: agenda_culturel/models.py:334 #: agenda_culturel/models.py:357
msgid "" msgid ""
"Alternative names or addresses used to match a place with the free-form " "Alternative names or addresses used to match a place with the free-form "
"location of an event." "location of an event."
@ -289,77 +317,77 @@ msgstr ""
"Noms et adresses alternatives qui seront utilisées pour associer une adresse " "Noms et adresses alternatives qui seront utilisées pour associer une adresse "
"avec la localisation en forme libre d'un événement" "avec la localisation en forme libre d'un événement"
#: agenda_culturel/models.py:342 #: agenda_culturel/models.py:365
msgid "Places" msgid "Places"
msgstr "Lieux" msgstr "Lieux"
#: agenda_culturel/models.py:395 agenda_culturel/models.py:1481 #: agenda_culturel/models.py:418 agenda_culturel/models.py:1499
msgid "Published" msgid "Published"
msgstr "Publié" msgstr "Publié"
#: agenda_culturel/models.py:396 #: agenda_culturel/models.py:419
msgid "Draft" msgid "Draft"
msgstr "Brouillon" msgstr "Brouillon"
#: agenda_culturel/models.py:397 #: agenda_culturel/models.py:420
msgid "Trash" msgid "Trash"
msgstr "Corbeille" msgstr "Corbeille"
#: agenda_culturel/models.py:408 #: agenda_culturel/models.py:431
msgid "Title" msgid "Title"
msgstr "Titre" msgstr "Titre"
#: agenda_culturel/models.py:408 #: agenda_culturel/models.py:431
msgid "Short title" msgid "Short title"
msgstr "Titre court" msgstr "Titre court"
#: agenda_culturel/models.py:412 agenda_culturel/models.py:1567 #: agenda_culturel/models.py:435 agenda_culturel/models.py:1585
msgid "Status" msgid "Status"
msgstr "Status" msgstr "Status"
#: agenda_culturel/models.py:418 #: agenda_culturel/models.py:441
msgid "Category of the event" msgid "Category of the event"
msgstr "Catégorie de l'événement" msgstr "Catégorie de l'événement"
#: agenda_culturel/models.py:425 #: agenda_culturel/models.py:448
msgid "Day of the event" msgid "Day of the event"
msgstr "Date de l'événement" msgstr "Date de l'événement"
#: agenda_culturel/models.py:428 agenda_culturel/models.py:429 #: agenda_culturel/models.py:451 agenda_culturel/models.py:452
msgid "Starting time" msgid "Starting time"
msgstr "Heure de début" msgstr "Heure de début"
#: agenda_culturel/models.py:435 #: agenda_culturel/models.py:458
msgid "End day of the event" msgid "End day of the event"
msgstr "Fin de l'événement" msgstr "Fin de l'événement"
#: agenda_culturel/models.py:437 #: agenda_culturel/models.py:460
msgid "End day of the event, only required if different from the start day." msgid "End day of the event, only required if different from the start day."
msgstr "" msgstr ""
"Date de fin de l'événement, uniquement nécessaire s'il est différent du " "Date de fin de l'événement, uniquement nécessaire s'il est différent du "
"premier jour de l'événement" "premier jour de l'événement"
#: agenda_culturel/models.py:443 #: agenda_culturel/models.py:466
msgid "Final time" msgid "Final time"
msgstr "Heure de fin" msgstr "Heure de fin"
#: agenda_culturel/models.py:447 #: agenda_culturel/models.py:470
msgid "Recurrence" msgid "Recurrence"
msgstr "Récurrence" msgstr "Récurrence"
#: agenda_culturel/models.py:452 agenda_culturel/models.py:1486 #: agenda_culturel/models.py:475 agenda_culturel/models.py:1504
msgid "Location" msgid "Location"
msgstr "Localisation" msgstr "Localisation"
#: agenda_culturel/models.py:453 #: agenda_culturel/models.py:476
msgid "Address of the event" msgid "Address of the event"
msgstr "Adresse de l'événement" msgstr "Adresse de l'événement"
#: agenda_culturel/models.py:459 #: agenda_culturel/models.py:482
msgid "Location (free form)" msgid "Location (free form)"
msgstr "Localisation (forme libre)" msgstr "Localisation (forme libre)"
#: agenda_culturel/models.py:461 #: agenda_culturel/models.py:484
msgid "" msgid ""
"Address of the event in case its not available in the already known places " "Address of the event in case its not available in the already known places "
"(free form)" "(free form)"
@ -367,219 +395,211 @@ msgstr ""
"Addresse d'un événement si elle n'est pas déjà présente dans la liste des " "Addresse d'un événement si elle n'est pas déjà présente dans la liste des "
"lieux disponible (forme libre)" "lieux disponible (forme libre)"
#: agenda_culturel/models.py:471 #: agenda_culturel/models.py:494
msgid "General description of the event" msgid "General description of the event"
msgstr "Description générale de l'événement" msgstr "Description générale de l'événement"
#: agenda_culturel/models.py:477 #: agenda_culturel/models.py:500
msgid "Illustration (local image)" msgid "Illustration (local image)"
msgstr "Illustration (image locale)" msgstr "Illustration (image locale)"
#: agenda_culturel/models.py:478 #: agenda_culturel/models.py:501
msgid "Illustration image stored in the agenda server" msgid "Illustration image stored in the agenda server"
msgstr "Image d'illustration stockée sur le serveur de l'agenda" msgstr "Image d'illustration stockée sur le serveur de l'agenda"
#: agenda_culturel/models.py:485 #: agenda_culturel/models.py:508
msgid "Illustration" msgid "Illustration"
msgstr "Illustration" msgstr "Illustration"
#: agenda_culturel/models.py:486 #: agenda_culturel/models.py:509
msgid "URL of the illustration image" msgid "URL of the illustration image"
msgstr "URL de l'image illustrative" msgstr "URL de l'image illustrative"
#: agenda_culturel/models.py:492 #: agenda_culturel/models.py:515
msgid "Illustration description" msgid "Illustration description"
msgstr "Description de l'illustration" msgstr "Description de l'illustration"
#: agenda_culturel/models.py:493 #: agenda_culturel/models.py:516
msgid "Alternative text used by screen readers for the image" msgid "Alternative text used by screen readers for the image"
msgstr "Texte alternatif utiliser par les lecteurs d'écrans pour l'image" msgstr "Texte alternatif utiliser par les lecteurs d'écrans pour l'image"
#: agenda_culturel/models.py:500 #: agenda_culturel/models.py:524
msgid "Masked"
msgstr "Masqué"
#: agenda_culturel/models.py:501
msgid "This event is masked by a duplicated version."
msgstr "L'événement est masqué par une version dupliquée."
#: agenda_culturel/models.py:509
msgid "Importation source" msgid "Importation source"
msgstr "Source d'importation" msgstr "Source d'importation"
#: agenda_culturel/models.py:510 #: agenda_culturel/models.py:525
msgid "Importation source used to detect removed entries." msgid "Importation source used to detect removed entries."
msgstr "Source d'importation utilisée pour détecter les éléments supprimés/" msgstr "Source d'importation utilisée pour détecter les éléments supprimés/"
#: agenda_culturel/models.py:516 #: agenda_culturel/models.py:531
msgid "UUIDs" msgid "UUIDs"
msgstr "UUIDs" msgstr "UUIDs"
#: agenda_culturel/models.py:517 #: agenda_culturel/models.py:532
msgid "UUIDs from import to detect duplicated entries." msgid "UUIDs from import to detect duplicated entries."
msgstr "UUIDs utilisés pendant l'import pour détecter les entrées dupliquées" msgstr "UUIDs utilisés pendant l'import pour détecter les entrées dupliquées"
#: agenda_culturel/models.py:523 #: agenda_culturel/models.py:538
msgid "URLs" msgid "URLs"
msgstr "URLs" msgstr "URLs"
#: agenda_culturel/models.py:524 #: agenda_culturel/models.py:539
msgid "List of all the urls where this event can be found." msgid "List of all the urls where this event can be found."
msgstr "Liste de toutes les urls où l'événement peut être trouvé." msgstr "Liste de toutes les urls où l'événement peut être trouvé."
#: agenda_culturel/models.py:531 #: agenda_culturel/models.py:546
msgid "Tags" msgid "Tags"
msgstr "Étiquettes" msgstr "Étiquettes"
#: agenda_culturel/models.py:532 #: agenda_culturel/models.py:547
msgid "A list of tags that describe the event." msgid "A list of tags that describe the event."
msgstr "Une liste d'étiquettes décrivant l'événement" msgstr "Une liste d'étiquettes décrivant l'événement"
#: agenda_culturel/models.py:539 #: agenda_culturel/models.py:554
msgid "Possibly duplicated" msgid "Other versions"
msgstr "Possibles doublons" msgstr ""
#: agenda_culturel/models.py:604 #: agenda_culturel/models.py:619
msgid "Event" msgid "Event"
msgstr "Événement" msgstr "Événement"
#: agenda_culturel/models.py:605 #: agenda_culturel/models.py:620
msgid "Events" msgid "Events"
msgstr "Événements" msgstr "Événements"
#: agenda_culturel/models.py:1357 #: agenda_culturel/models.py:1375
msgid "Contact message" msgid "Contact message"
msgstr "Message de contact" msgstr "Message de contact"
#: agenda_culturel/models.py:1358 #: agenda_culturel/models.py:1376
msgid "Contact messages" msgid "Contact messages"
msgstr "Messages de contact" msgstr "Messages de contact"
#: agenda_culturel/models.py:1361 #: agenda_culturel/models.py:1379
msgid "Subject" msgid "Subject"
msgstr "Sujet" msgstr "Sujet"
#: agenda_culturel/models.py:1362 #: agenda_culturel/models.py:1380
msgid "The subject of your message" msgid "The subject of your message"
msgstr "Sujet de votre message" msgstr "Sujet de votre message"
#: agenda_culturel/models.py:1367 #: agenda_culturel/models.py:1385
msgid "Your name" msgid "Your name"
msgstr "Votre nom" msgstr "Votre nom"
#: agenda_culturel/models.py:1373 #: agenda_culturel/models.py:1391
msgid "Email address" msgid "Email address"
msgstr "Adresse email" msgstr "Adresse email"
#: agenda_culturel/models.py:1374 #: agenda_culturel/models.py:1392
msgid "Your email address" msgid "Your email address"
msgstr "Votre adresse email" msgstr "Votre adresse email"
#: agenda_culturel/models.py:1379 #: agenda_culturel/models.py:1397
msgid "Message" msgid "Message"
msgstr "Message" msgstr "Message"
#: agenda_culturel/models.py:1379 #: agenda_culturel/models.py:1397
msgid "Your message" msgid "Your message"
msgstr "Votre message" msgstr "Votre message"
#: agenda_culturel/models.py:1384 agenda_culturel/views.py:952 #: agenda_culturel/models.py:1402 agenda_culturel/views.py:952
msgid "Spam" msgid "Spam"
msgstr "Spam" msgstr "Spam"
#: agenda_culturel/models.py:1385 #: agenda_culturel/models.py:1403
msgid "This message is a spam." msgid "This message is a spam."
msgstr "Ce message est un spam." msgstr "Ce message est un spam."
#: agenda_culturel/models.py:1390 agenda_culturel/views.py:947 #: agenda_culturel/models.py:1408 agenda_culturel/views.py:947
msgid "Closed" msgid "Closed"
msgstr "Fermé" msgstr "Fermé"
#: agenda_culturel/models.py:1392 #: agenda_culturel/models.py:1410
msgid "this message has been processed and no longer needs to be handled" msgid "this message has been processed and no longer needs to be handled"
msgstr "Ce message a été traité et ne nécessite plus d'être pris en charge" msgstr "Ce message a été traité et ne nécessite plus d'être pris en charge"
#: agenda_culturel/models.py:1397 #: agenda_culturel/models.py:1415
msgid "Comments" msgid "Comments"
msgstr "Commentaires" msgstr "Commentaires"
#: agenda_culturel/models.py:1398 #: agenda_culturel/models.py:1416
msgid "Comments on the message from the moderation team" msgid "Comments on the message from the moderation team"
msgstr "Commentaires sur ce message par l'équipe de modération" msgstr "Commentaires sur ce message par l'équipe de modération"
#: agenda_culturel/models.py:1410 agenda_culturel/models.py:1547 #: agenda_culturel/models.py:1428 agenda_culturel/models.py:1565
msgid "Recurrent import" msgid "Recurrent import"
msgstr "Import récurrent" msgstr "Import récurrent"
#: agenda_culturel/models.py:1411 #: agenda_culturel/models.py:1429
msgid "Recurrent imports" msgid "Recurrent imports"
msgstr "Imports récurrents" msgstr "Imports récurrents"
#: agenda_culturel/models.py:1415 #: agenda_culturel/models.py:1433
msgid "ical" msgid "ical"
msgstr "ical" msgstr "ical"
#: agenda_culturel/models.py:1416 #: agenda_culturel/models.py:1434
msgid "ical no busy" msgid "ical no busy"
msgstr "ical sans busy" msgstr "ical sans busy"
#: agenda_culturel/models.py:1417 #: agenda_culturel/models.py:1435
msgid "ical no VC" msgid "ical no VC"
msgstr "ical sans VC" msgstr "ical sans VC"
#: agenda_culturel/models.py:1418 #: agenda_culturel/models.py:1436
msgid "lacoope.org" msgid "lacoope.org"
msgstr "lacoope.org" msgstr "lacoope.org"
#: agenda_culturel/models.py:1419 #: agenda_culturel/models.py:1437
msgid "la comédie" msgid "la comédie"
msgstr "la comédie" msgstr "la comédie"
#: agenda_culturel/models.py:1420 #: agenda_culturel/models.py:1438
msgid "le fotomat" msgid "le fotomat"
msgstr "le fotomat" msgstr "le fotomat"
#: agenda_culturel/models.py:1421 #: agenda_culturel/models.py:1439
msgid "la puce à l'oreille" msgid "la puce à l'oreille"
msgstr "la puce à loreille" msgstr "la puce à loreille"
#: agenda_culturel/models.py:1422 #: agenda_culturel/models.py:1440
msgid "Plugin wordpress MEC" msgid "Plugin wordpress MEC"
msgstr "Plugin wordpress MEC" msgstr "Plugin wordpress MEC"
#: agenda_culturel/models.py:1423 #: agenda_culturel/models.py:1441
msgid "Événements d'une page FB" msgid "Événements d'une page FB"
msgstr "Événements d'une page FB" msgstr "Événements d'une page FB"
#: agenda_culturel/models.py:1424 #: agenda_culturel/models.py:1442
msgid "la cour des 3 coquins" msgid "la cour des 3 coquins"
msgstr "la cour des 3 coquins" msgstr "la cour des 3 coquins"
#: agenda_culturel/models.py:1425 #: agenda_culturel/models.py:1443
msgid "Arachnée concert" msgid "Arachnée concert"
msgstr "Arachnée concert" msgstr "Arachnée concert"
#: agenda_culturel/models.py:1428 #: agenda_culturel/models.py:1446
msgid "simple" msgid "simple"
msgstr "simple" msgstr "simple"
#: agenda_culturel/models.py:1429 #: agenda_culturel/models.py:1447
msgid "Headless Chromium" msgid "Headless Chromium"
msgstr "chromium sans interface" msgstr "chromium sans interface"
#: agenda_culturel/models.py:1430 #: agenda_culturel/models.py:1448
msgid "Headless Chromium (pause)" msgid "Headless Chromium (pause)"
msgstr "chromium sans interface (pause)" msgstr "chromium sans interface (pause)"
#: agenda_culturel/models.py:1435 #: agenda_culturel/models.py:1453
msgid "daily" msgid "daily"
msgstr "chaque jour" msgstr "chaque jour"
#: agenda_culturel/models.py:1437 #: agenda_culturel/models.py:1455
msgid "weekly" msgid "weekly"
msgstr "chaque semaine" msgstr "chaque semaine"
#: agenda_culturel/models.py:1442 #: agenda_culturel/models.py:1460
msgid "" msgid ""
"Recurrent import name. Be careful to choose a name that is easy to " "Recurrent import name. Be careful to choose a name that is easy to "
"understand, as it will be public and displayed on the sites About page." "understand, as it will be public and displayed on the sites About page."
@ -587,135 +607,135 @@ msgstr ""
"Nom de l'import récurrent. Attention à choisir un nom compréhensible, car il " "Nom de l'import récurrent. Attention à choisir un nom compréhensible, car il "
"sera public, et affiché sur la page à propos du site." "sera public, et affiché sur la page à propos du site."
#: agenda_culturel/models.py:1449 #: agenda_culturel/models.py:1467
msgid "Processor" msgid "Processor"
msgstr "Processeur" msgstr "Processeur"
#: agenda_culturel/models.py:1452 #: agenda_culturel/models.py:1470
msgid "Downloader" msgid "Downloader"
msgstr "Téléchargeur" msgstr "Téléchargeur"
#: agenda_culturel/models.py:1459 #: agenda_culturel/models.py:1477
msgid "Import recurrence" msgid "Import recurrence"
msgstr "Récurrence d'import" msgstr "Récurrence d'import"
#: agenda_culturel/models.py:1466 #: agenda_culturel/models.py:1484
msgid "Source" msgid "Source"
msgstr "Source" msgstr "Source"
#: agenda_culturel/models.py:1467 #: agenda_culturel/models.py:1485
msgid "URL of the source document" msgid "URL of the source document"
msgstr "URL du document source" msgstr "URL du document source"
#: agenda_culturel/models.py:1471 #: agenda_culturel/models.py:1489
msgid "Browsable url" msgid "Browsable url"
msgstr "URL navigable" msgstr "URL navigable"
#: agenda_culturel/models.py:1473 #: agenda_culturel/models.py:1491
msgid "URL of the corresponding document that will be shown to visitors." msgid "URL of the corresponding document that will be shown to visitors."
msgstr "URL correspondant au document et qui sera montrée aux visiteurs" msgstr "URL correspondant au document et qui sera montrée aux visiteurs"
#: agenda_culturel/models.py:1482 #: agenda_culturel/models.py:1500
msgid "Status of each imported event (published or draft)" msgid "Status of each imported event (published or draft)"
msgstr "Status de chaque événement importé (publié ou brouillon)" msgstr "Status de chaque événement importé (publié ou brouillon)"
#: agenda_culturel/models.py:1487 #: agenda_culturel/models.py:1505
msgid "Address for each imported event" msgid "Address for each imported event"
msgstr "Adresse de chaque événement importé" msgstr "Adresse de chaque événement importé"
#: agenda_culturel/models.py:1495 #: agenda_culturel/models.py:1513
msgid "Category of each imported event" msgid "Category of each imported event"
msgstr "Catégorie de chaque événement importé" msgstr "Catégorie de chaque événement importé"
#: agenda_culturel/models.py:1503 #: agenda_culturel/models.py:1521
msgid "Tags for each imported event" msgid "Tags for each imported event"
msgstr "Étiquettes de chaque événement importé" msgstr "Étiquettes de chaque événement importé"
#: agenda_culturel/models.py:1504 #: agenda_culturel/models.py:1522
msgid "A list of tags that describe each imported event." msgid "A list of tags that describe each imported event."
msgstr "Une liste d'étiquettes décrivant chaque événement importé" msgstr "Une liste d'étiquettes décrivant chaque événement importé"
#: agenda_culturel/models.py:1533 #: agenda_culturel/models.py:1551
msgid "Running" msgid "Running"
msgstr "En cours" msgstr "En cours"
#: agenda_culturel/models.py:1534 #: agenda_culturel/models.py:1552
msgid "Canceled" msgid "Canceled"
msgstr "Annulé" msgstr "Annulé"
#: agenda_culturel/models.py:1535 #: agenda_culturel/models.py:1553
msgid "Success" msgid "Success"
msgstr "Succès" msgstr "Succès"
#: agenda_culturel/models.py:1536 #: agenda_culturel/models.py:1554
msgid "Failed" msgid "Failed"
msgstr "Erreur" msgstr "Erreur"
#: agenda_culturel/models.py:1539 #: agenda_culturel/models.py:1557
msgid "Batch importation" msgid "Batch importation"
msgstr "Importation par lot" msgstr "Importation par lot"
#: agenda_culturel/models.py:1540 #: agenda_culturel/models.py:1558
msgid "Batch importations" msgid "Batch importations"
msgstr "Importations par lot" msgstr "Importations par lot"
#: agenda_culturel/models.py:1548 #: agenda_culturel/models.py:1566
msgid "Reference to the recurrent import processing" msgid "Reference to the recurrent import processing"
msgstr "Référence du processus d'import récurrent" msgstr "Référence du processus d'import récurrent"
#: agenda_culturel/models.py:1556 #: agenda_culturel/models.py:1574
msgid "URL (if not recurrent import)" msgid "URL (if not recurrent import)"
msgstr "URL (si pas d'import récurrent)" msgstr "URL (si pas d'import récurrent)"
#: agenda_culturel/models.py:1558 #: agenda_culturel/models.py:1576
msgid "Source URL if no RecurrentImport is associated." msgid "Source URL if no RecurrentImport is associated."
msgstr "URL source si aucun import récurrent n'est associé" msgstr "URL source si aucun import récurrent n'est associé"
#: agenda_culturel/models.py:1571 #: agenda_culturel/models.py:1589
msgid "Error message" msgid "Error message"
msgstr "Votre message" msgstr "Votre message"
#: agenda_culturel/models.py:1575 #: agenda_culturel/models.py:1593
msgid "Number of collected events" msgid "Number of collected events"
msgstr "Nombre d'événements collectés" msgstr "Nombre d'événements collectés"
#: agenda_culturel/models.py:1578 #: agenda_culturel/models.py:1596
msgid "Number of imported events" msgid "Number of imported events"
msgstr "Nombre d'événements importés" msgstr "Nombre d'événements importés"
#: agenda_culturel/models.py:1581 #: agenda_culturel/models.py:1599
msgid "Number of updated events" msgid "Number of updated events"
msgstr "Nombre d'événements mis à jour" msgstr "Nombre d'événements mis à jour"
#: agenda_culturel/models.py:1584 #: agenda_culturel/models.py:1602
msgid "Number of removed events" msgid "Number of removed events"
msgstr "Nombre d'événements supprimés" msgstr "Nombre d'événements supprimés"
#: agenda_culturel/models.py:1592 #: agenda_culturel/models.py:1610
msgid "Weight" msgid "Weight"
msgstr "Poids" msgstr "Poids"
#: agenda_culturel/models.py:1593 #: agenda_culturel/models.py:1611
msgid "The lower is the weight, the earlier the filter is applied" msgid "The lower is the weight, the earlier the filter is applied"
msgstr "Plus le poids est léger, plus le filtre sera appliqué tôt" msgstr "Plus le poids est léger, plus le filtre sera appliqué tôt"
#: agenda_culturel/models.py:1600 #: agenda_culturel/models.py:1618
msgid "Category applied to the event" msgid "Category applied to the event"
msgstr "Catégorie appliquée à l'événement" msgstr "Catégorie appliquée à l'événement"
#: agenda_culturel/models.py:1605 #: agenda_culturel/models.py:1623
msgid "Contained in the title" msgid "Contained in the title"
msgstr "Contenu dans le titre" msgstr "Contenu dans le titre"
#: agenda_culturel/models.py:1606 #: agenda_culturel/models.py:1624
msgid "Text contained in the event title" msgid "Text contained in the event title"
msgstr "Texte contenu dans le titre de l'événement" msgstr "Texte contenu dans le titre de l'événement"
#: agenda_culturel/models.py:1612 #: agenda_culturel/models.py:1630
msgid "Exact title extract" msgid "Exact title extract"
msgstr "Extrait exact du titre" msgstr "Extrait exact du titre"
#: agenda_culturel/models.py:1614 #: agenda_culturel/models.py:1632
msgid "" msgid ""
"If checked, the extract will be searched for in the title using the exact " "If checked, the extract will be searched for in the title using the exact "
"form (capitals, accents)." "form (capitals, accents)."
@ -723,19 +743,19 @@ msgstr ""
"Si coché, l'extrait sera recherché dans le titre en utilisant la forme " "Si coché, l'extrait sera recherché dans le titre en utilisant la forme "
"exacte (majuscules, accents)" "exacte (majuscules, accents)"
#: agenda_culturel/models.py:1620 #: agenda_culturel/models.py:1638
msgid "Contained in the description" msgid "Contained in the description"
msgstr "Contenu dans la description" msgstr "Contenu dans la description"
#: agenda_culturel/models.py:1621 #: agenda_culturel/models.py:1639
msgid "Text contained in the description" msgid "Text contained in the description"
msgstr "Texte contenu dans la description" msgstr "Texte contenu dans la description"
#: agenda_culturel/models.py:1627 #: agenda_culturel/models.py:1645
msgid "Exact description extract" msgid "Exact description extract"
msgstr "Extrait exact de description" msgstr "Extrait exact de description"
#: agenda_culturel/models.py:1629 #: agenda_culturel/models.py:1647
msgid "" msgid ""
"If checked, the extract will be searched for in the description using the " "If checked, the extract will be searched for in the description using the "
"exact form (capitals, accents)." "exact form (capitals, accents)."
@ -743,19 +763,19 @@ msgstr ""
"Si coché, l'extrait sera recherché dans la description en utilisant la forme " "Si coché, l'extrait sera recherché dans la description en utilisant la forme "
"exacte (majuscules, accents)" "exacte (majuscules, accents)"
#: agenda_culturel/models.py:1635 #: agenda_culturel/models.py:1653
msgid "Contained in the location" msgid "Contained in the location"
msgstr "Contenu dans la localisation" msgstr "Contenu dans la localisation"
#: agenda_culturel/models.py:1636 #: agenda_culturel/models.py:1654
msgid "Text contained in the event location" msgid "Text contained in the event location"
msgstr "Texte contenu dans la localisation de l'événement" msgstr "Texte contenu dans la localisation de l'événement"
#: agenda_culturel/models.py:1642 #: agenda_culturel/models.py:1660
msgid "Exact location extract" msgid "Exact location extract"
msgstr "Extrait exact de localisation" msgstr "Extrait exact de localisation"
#: agenda_culturel/models.py:1644 #: agenda_culturel/models.py:1662
msgid "" msgid ""
"If checked, the extract will be searched for in the location using the exact " "If checked, the extract will be searched for in the location using the exact "
"form (capitals, accents)." "form (capitals, accents)."
@ -763,56 +783,56 @@ msgstr ""
"Si coché, l'extrait sera recherché dans la localisation en utilisant la " "Si coché, l'extrait sera recherché dans la localisation en utilisant la "
"forme exacte (majuscules, accents)" "forme exacte (majuscules, accents)"
#: agenda_culturel/models.py:1652 #: agenda_culturel/models.py:1670
msgid "Location from place" msgid "Location from place"
msgstr "Localisation depuis le lieu" msgstr "Localisation depuis le lieu"
#: agenda_culturel/models.py:1661 #: agenda_culturel/models.py:1679
msgid "Categorisation rule" msgid "Categorisation rule"
msgstr "Règle de catégorisation" msgstr "Règle de catégorisation"
#: agenda_culturel/models.py:1662 #: agenda_culturel/models.py:1680
msgid "Categorisation rules" msgid "Categorisation rules"
msgstr "Règles de catégorisation" msgstr "Règles de catégorisation"
#: agenda_culturel/models.py:1733 agenda_culturel/models.py:1765 #: agenda_culturel/models.py:1751 agenda_culturel/models.py:1783
msgid "Question" msgid "Question"
msgstr "Question" msgstr "Question"
#: agenda_culturel/models.py:1734 agenda_culturel/models.py:1772 #: agenda_culturel/models.py:1752 agenda_culturel/models.py:1790
msgid "Text that will be shown to moderators" msgid "Text that will be shown to moderators"
msgstr "Text tel que présenté aux modérateurices" msgstr "Text tel que présenté aux modérateurices"
#: agenda_culturel/models.py:1740 #: agenda_culturel/models.py:1758
msgid "Moderation question" msgid "Moderation question"
msgstr "Question de modération" msgstr "Question de modération"
#: agenda_culturel/models.py:1741 #: agenda_culturel/models.py:1759
msgid "Moderation questions" msgid "Moderation questions"
msgstr "Questions de modération" msgstr "Questions de modération"
#: agenda_culturel/models.py:1766 #: agenda_culturel/models.py:1784
msgid "Associated question from moderation" msgid "Associated question from moderation"
msgstr "Question associée pour la modération" msgstr "Question associée pour la modération"
#: agenda_culturel/models.py:1771 #: agenda_culturel/models.py:1789
msgid "Answer" msgid "Answer"
msgstr "Réponse" msgstr "Réponse"
#: agenda_culturel/models.py:1778 #: agenda_culturel/models.py:1796
msgid "Adds tags" msgid "Adds tags"
msgstr "Ajoute les étiquettes" msgstr "Ajoute les étiquettes"
#: agenda_culturel/models.py:1779 #: agenda_culturel/models.py:1797
msgid "A list of tags that will be added if you choose this answer." msgid "A list of tags that will be added if you choose this answer."
msgstr "" msgstr ""
"Une liste d'étiquettes qui seront ajoutées si vous choisissez cette réponse." "Une liste d'étiquettes qui seront ajoutées si vous choisissez cette réponse."
#: agenda_culturel/models.py:1785 #: agenda_culturel/models.py:1803
msgid "Removes tags" msgid "Removes tags"
msgstr "Retire les étiquettes" msgstr "Retire les étiquettes"
#: agenda_culturel/models.py:1786 #: agenda_culturel/models.py:1804
msgid "A list of tags that will be removed if you choose this answer." msgid "A list of tags that will be removed if you choose this answer."
msgstr "" msgstr ""
"Une liste d'étiquettes qui seront retirées si vous choisissez cette réponse." "Une liste d'étiquettes qui seront retirées si vous choisissez cette réponse."
@ -969,7 +989,7 @@ msgstr "L'import a été lancé"
msgid "Imports has been launched." msgid "Imports has been launched."
msgstr "Les imports ont été lancés" msgstr "Les imports ont été lancés"
#: agenda_culturel/views.py:1471 #: agenda_culturel/views.py:1472
msgid "Creation of a merged event has been successfully completed." msgid "Creation of a merged event has been successfully completed."
msgstr "Création d'un événement fusionné réalisée avec succès." msgstr "Création d'un événement fusionné réalisée avec succès."
@ -977,28 +997,23 @@ msgstr "Création d'un événement fusionné réalisée avec succès."
msgid "Events have been marked as unduplicated." msgid "Events have been marked as unduplicated."
msgstr "Les événements ont été marqués comme non dupliqués." msgstr "Les événements ont été marqués comme non dupliqués."
#: agenda_culturel/views.py:1524 #: agenda_culturel/views.py:1522
msgid "The selected event has been retained, while the other has been masked." msgid "The selected event has been set as representative"
msgstr "L'événement sélectionné a été retenu, l'autre a été masqué." msgstr "L'événement sélectionné a été défini comme representatif."
#: agenda_culturel/views.py:1531 #: agenda_culturel/views.py:1532
msgid ""
"The selected event has been retained, while the others havec been masked."
msgstr "L'événement sélectionné a été retenu, les autres ont été masqués."
#: agenda_culturel/views.py:1544
msgid "The event has been withdrawn from the group and made independent." msgid "The event has been withdrawn from the group and made independent."
msgstr "L'événement a été retiré du groupe et rendu indépendant." msgstr "L'événement a été retiré du groupe et rendu indépendant."
#: agenda_culturel/views.py:1577 #: agenda_culturel/views.py:1567
msgid "Cleaning up duplicates: {} item(s) fixed." msgid "Cleaning up duplicates: {} item(s) fixed."
msgstr "Nettoyage des dupliqués: {} élément(s) corrigé(s)." msgstr "Nettoyage des dupliqués: {} élément(s) corrigé(s)."
#: agenda_culturel/views.py:1624 #: agenda_culturel/views.py:1614
msgid "The event was successfully duplicated." msgid "The event was successfully duplicated."
msgstr "L'événement a été marqué dupliqué avec succès." msgstr "L'événement a été marqué dupliqué avec succès."
#: agenda_culturel/views.py:1632 #: agenda_culturel/views.py:1622
msgid "" msgid ""
"The event has been successfully flagged as a duplicate. The moderation team " "The event has been successfully flagged as a duplicate. The moderation team "
"will deal with your suggestion shortly." "will deal with your suggestion shortly."
@ -1006,32 +1021,32 @@ msgstr ""
"L'événement a été signalé comme dupliqué avec succès. Votre suggestion sera " "L'événement a été signalé comme dupliqué avec succès. Votre suggestion sera "
"prochainement prise en charge par l'équipe de modération." "prochainement prise en charge par l'équipe de modération."
#: agenda_culturel/views.py:1685 #: agenda_culturel/views.py:1675
msgid "The categorisation rule has been successfully modified." msgid "The categorisation rule has been successfully modified."
msgstr "La règle de catégorisation a été modifiée avec succès." msgstr "La règle de catégorisation a été modifiée avec succès."
#: agenda_culturel/views.py:1694 #: agenda_culturel/views.py:1684
msgid "The categorisation rule has been successfully deleted." msgid "The categorisation rule has been successfully deleted."
msgstr "La règle de catégorisation a été supprimée avec succès" msgstr "La règle de catégorisation a été supprimée avec succès"
#: agenda_culturel/views.py:1716 #: agenda_culturel/views.py:1706
msgid "The rules were successfully applied and 1 event was categorised." msgid "The rules were successfully applied and 1 event was categorised."
msgstr "" msgstr ""
"Les règles ont été appliquées avec succès et 1 événement a été catégorisé" "Les règles ont été appliquées avec succès et 1 événement a été catégorisé"
#: agenda_culturel/views.py:1723 #: agenda_culturel/views.py:1713
msgid "The rules were successfully applied and {} events were categorised." msgid "The rules were successfully applied and {} events were categorised."
msgstr "" msgstr ""
"Les règles ont été appliquées avec succès et {} événements ont été " "Les règles ont été appliquées avec succès et {} événements ont été "
"catégorisés" "catégorisés"
#: agenda_culturel/views.py:1730 agenda_culturel/views.py:1783 #: agenda_culturel/views.py:1720 agenda_culturel/views.py:1773
msgid "The rules were successfully applied and no events were categorised." msgid "The rules were successfully applied and no events were categorised."
msgstr "" msgstr ""
"Les règles ont été appliquées avec succès et aucun événement n'a été " "Les règles ont été appliquées avec succès et aucun événement n'a été "
"catégorisé" "catégorisé"
#: agenda_culturel/views.py:1769 #: agenda_culturel/views.py:1759
msgid "" msgid ""
"The rules were successfully applied and 1 event with default category was " "The rules were successfully applied and 1 event with default category was "
"categorised." "categorised."
@ -1039,7 +1054,7 @@ msgstr ""
"Les règles ont été appliquées avec succès et 1 événement avec catégorie par " "Les règles ont été appliquées avec succès et 1 événement avec catégorie par "
"défaut a été catégorisé" "défaut a été catégorisé"
#: agenda_culturel/views.py:1776 #: agenda_culturel/views.py:1766
msgid "" msgid ""
"The rules were successfully applied and {} events with default category were " "The rules were successfully applied and {} events with default category were "
"categorised." "categorised."
@ -1047,51 +1062,45 @@ msgstr ""
"Les règles ont été appliquées avec succès et {} événements avec catégorie " "Les règles ont été appliquées avec succès et {} événements avec catégorie "
"par défaut ont été catégorisés" "par défaut ont été catégorisés"
#: agenda_culturel/views.py:1823 #: agenda_culturel/views.py:1813
msgid "The moderation question has been created with success." msgid "The moderation question has been created with success."
msgstr "La question de modération a été créée avec succès." msgstr "La question de modération a été créée avec succès."
#: agenda_culturel/views.py:1949 agenda_culturel/views.py:2011 #: agenda_culturel/views.py:1939 agenda_culturel/views.py:2001
#: agenda_culturel/views.py:2049 #: agenda_culturel/views.py:2039
msgid "{} events have been updated." msgid "{} events have been updated."
msgstr "{} événements ont été mis à jour." msgstr "{} événements ont été mis à jour."
#: agenda_culturel/views.py:1952 agenda_culturel/views.py:2013 #: agenda_culturel/views.py:1942 agenda_culturel/views.py:2003
#: agenda_culturel/views.py:2052 #: agenda_culturel/views.py:2042
msgid "1 event has been updated." msgid "1 event has been updated."
msgstr "1 événement a été mis à jour" msgstr "1 événement a été mis à jour"
#: agenda_culturel/views.py:1954 agenda_culturel/views.py:2015 #: agenda_culturel/views.py:1944 agenda_culturel/views.py:2005
#: agenda_culturel/views.py:2054 #: agenda_culturel/views.py:2044
msgid "No events have been modified." msgid "No events have been modified."
msgstr "Aucun événement n'a été modifié." msgstr "Aucun événement n'a été modifié."
#: agenda_culturel/views.py:1963 #: agenda_culturel/views.py:1953
msgid "The place has been successfully updated." msgid "The place has been successfully updated."
msgstr "Le lieu a été modifié avec succès." msgstr "Le lieu a été modifié avec succès."
#: agenda_culturel/views.py:1972 #: agenda_culturel/views.py:1962
msgid "The place has been successfully created." msgid "The place has been successfully created."
msgstr "Le lieu a été créé avec succès." msgstr "Le lieu a été créé avec succès."
#: agenda_culturel/views.py:2037 #: agenda_culturel/views.py:2027
msgid "The selected place has been assigned to the event." msgid "The selected place has been assigned to the event."
msgstr "Le lieu sélectionné a été assigné à l'événement." msgstr "Le lieu sélectionné a été assigné à l'événement."
#: agenda_culturel/views.py:2041 #: agenda_culturel/views.py:2031
msgid "A new alias has been added to the selected place." msgid "A new alias has been added to the selected place."
msgstr "Un nouvel alias a été créé pour le lieu sélectionné." msgstr "Un nouvel alias a été créé pour le lieu sélectionné."
#: agenda_culturel/views.py:2097 #: agenda_culturel/views.py:2087
msgid "The tag has been successfully updated." msgid "The tag has been successfully updated."
msgstr "L'étiquette a été modifiée avec succès." msgstr "L'étiquette a été modifiée avec succès."
#: agenda_culturel/views.py:2104 #: agenda_culturel/views.py:2094
msgid "The tag has been successfully created." msgid "The tag has been successfully created."
msgstr "L'étiquette a été créée avec succès." msgstr "L'étiquette a été créée avec succès."
#~ msgid "Fixed"
#~ msgstr "Résolu"
#~ msgid "Not fixed"
#~ msgstr "Non résolu"

View File

@ -228,7 +228,10 @@ class DuplicatedEvents(models.Model):
return reverse("view_duplicate", kwargs={"pk": self.pk}) return reverse("view_duplicate", kwargs={"pk": self.pk})
def get_one_event(self): def get_one_event(self):
return self.event_set.representative return self.representative
def fixed(self):
return not self.representative is None
def merge_into(self, other): def merge_into(self, other):
# for all objects associated to this group # for all objects associated to this group
@ -285,7 +288,7 @@ class DuplicatedEvents(models.Model):
def fix_similar_entries(): def fix_similar_entries():
to_be_fixed = [] to_be_fixed = []
for d in DuplicatedEvents.objects.filter(representative__isnull=True).prefetch_related('event_set'): for d in DuplicatedEvents.not_fixed_qs().prefetch_related('event_set'):
comp = Event.get_comparison(d.event_set.all()) comp = Event.get_comparison(d.event_set.all())
similar = len([c for c in comp if not c["similar"]]) == 0 similar = len([c for c in comp if not c["similar"]]) == 0
if similar: if similar:
@ -301,6 +304,17 @@ class DuplicatedEvents(models.Model):
return nb return nb
def not_fixed_qs(qs=None, fixed=False):
if not qs:
qs = DuplicatedEvents.objects
qs = qs.annotate(nb_no_trash=Count("event", filter=~Q(event__status=Event.STATUS.TRASH)))
q = ~Q(representative__isnull=True)|Q(nb_no_trash__lte=1)
if fixed:
return qs.filter(q)
else:
return qs.exclude(q)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if self.representative and not self.representative in self.event_set.all(): if self.representative and not self.representative in self.event_set.all():
self.representative = None self.representative = None

View File

@ -119,7 +119,7 @@
</nav> </nav>
{% if user.is_authenticated %} {% if user.is_authenticated %}
<footer> <footer>
<a role="button" href="{% url 'fix_duplicate' event.other_versions.pk %}">Corriger {% picto_from_name "tool" %}</a> <a role="button" href="{% url 'fix_duplicate' event.other_versions.pk %}">{% if event.other_versions.fixed %}Modifier {% picto_from_name "edit" %}{% else %}Corriger {% picto_from_name "tool" %}{% endif %}</a>
</footer> </footer>
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -16,7 +16,7 @@ register = template.Library()
@register.simple_tag @register.simple_tag
def show_badge_duplicated(placement="top"): def show_badge_duplicated(placement="top"):
nb_duplicated = DuplicatedEvents.objects.filter(representative=None).count() nb_duplicated = DuplicatedEvents.not_fixed_qs().count()
if nb_duplicated != 0: if nb_duplicated != 0:
return mark_safe( return mark_safe(

View File

@ -1396,13 +1396,17 @@ def run_all_rimports(request, status=None):
class DuplicatedEventsFilter(django_filters.FilterSet): class DuplicatedEventsFilter(django_filters.FilterSet):
fixed = django_filters.BooleanFilter( fixed = django_filters.BooleanFilter(
field_name='representative', lookup_expr='isnull', exclude=True) label="Résolu",
field_name='representative', method="fixed_qs")
class Meta: class Meta:
model = DuplicatedEvents model = DuplicatedEvents
fields = [] fields = []
def fixed_qs(self, queryset, name, value):
return DuplicatedEvents.not_fixed_qs(queryset, value)
class DuplicatedEventsDetailView(LoginRequiredMixin, DetailView): class DuplicatedEventsDetailView(LoginRequiredMixin, DetailView):
model = DuplicatedEvents model = DuplicatedEvents
template_name = "agenda_culturel/duplicate.html" template_name = "agenda_culturel/duplicate.html"
@ -1480,16 +1484,17 @@ def merge_duplicate(request, pk):
["agenda_culturel.change_event", "agenda_culturel.change_duplicatedevents"] ["agenda_culturel.change_event", "agenda_culturel.change_duplicatedevents"]
) )
def fix_duplicate(request, pk): def fix_duplicate(request, pk):
edup = get_object_or_404(DuplicatedEvents, pk=pk) edup = get_object_or_404(DuplicatedEvents.objects.select_related(), pk=pk)
form = FixDuplicates(nb_events=edup.nb_duplicated())
if request.method == "POST": if request.method == "POST":
form = FixDuplicates(request.POST, nb_events=edup.nb_duplicated()) form = FixDuplicates(request.POST, edup=edup)
if form.is_valid(): if form.is_valid():
if form.is_action_no_duplicates(): if form.is_action_no_duplicates():
# all events are different
events = edup.get_duplicated() events = edup.get_duplicated()
# get redirection date
if len(events) == 0: if len(events) == 0:
date = None date = None
else: else:
@ -1501,6 +1506,7 @@ def fix_duplicate(request, pk):
date = s_event.start_day date = s_event.start_day
messages.success(request, _("Events have been marked as unduplicated.")) messages.success(request, _("Events have been marked as unduplicated."))
# delete the duplicated event (other_versions will be set to None on all events)
edup.delete() edup.delete()
if date is None: if date is None:
return HttpResponseRedirect(reverse_lazy("home")) return HttpResponseRedirect(reverse_lazy("home"))
@ -1510,44 +1516,32 @@ def fix_duplicate(request, pk):
) )
elif form.is_action_select(): elif form.is_action_select():
# one element has been selected to be the representative
selected = form.get_selected_event(edup) selected = form.get_selected_event(edup)
nb = edup.fix(selected) - 1 edup.fix(selected)
if nb == 1: messages.success(request, _("The selected event has been set as representative"))
messages.success(
request,
_(
"The selected event has been retained, while the other has been masked."
),
)
else:
messages.success(
request,
_(
"The selected event has been retained, while the others havec been masked."
),
)
return HttpResponseRedirect(edup.get_absolute_url()) return HttpResponseRedirect(edup.get_absolute_url())
elif form.is_action_remove(): elif form.is_action_remove():
# one element is removed from the set
event = form.get_selected_event(edup) event = form.get_selected_event(edup)
event.other_versions = None event.other_versions = None
if edup.representative == event: if edup.representative == event:
edup.representative = None edup.representative = None
event.save() event.save()
edup.save() edup.save()
messages.success( messages.success(request, _("The event has been withdrawn from the group and made independent."))
request,
_(
"The event has been withdrawn from the group and made independent."
),
)
if edup.nb_duplicated() == 1: if edup.nb_duplicated() == 1:
return HttpResponseRedirect(edup.get_absolute_url()) return HttpResponseRedirect(edup.get_absolute_url())
else: else:
form = FixDuplicates(nb_events=edup.nb_duplicated()) form = FixDuplicates(edup=edup)
else: else:
# otherwise, a new event will be created using a merging process
return HttpResponseRedirect( return HttpResponseRedirect(
reverse_lazy("merge_duplicate", args=[edup.pk]) reverse_lazy("merge_duplicate", args=[edup.pk])
) )
else:
form = FixDuplicates(edup=edup)
return render( return render(
request, request,