From 28ca7b1b0358a168a838ea2a6500ab03c956353a Mon Sep 17 00:00:00 2001 From: Jean-Marie Favreau Date: Fri, 8 Nov 2024 16:23:23 +0100 Subject: [PATCH] Consolidation de la structure des doublons --- src/agenda_culturel/forms.py | 54 +-- .../locale/fr/LC_MESSAGES/django.po | 405 +++++++++--------- src/agenda_culturel/models.py | 18 +- .../templates/agenda_culturel/page-event.html | 2 +- .../templatetags/duplicated_extra.py | 2 +- src/agenda_culturel/views.py | 46 +- 6 files changed, 264 insertions(+), 263 deletions(-) diff --git a/src/agenda_culturel/forms.py b/src/agenda_culturel/forms.py index 1525750..3504042 100644 --- a/src/agenda_culturel/forms.py +++ b/src/agenda_culturel/forms.py @@ -154,49 +154,33 @@ class FixDuplicates(Form): action = ChoiceField() 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) - if nb_events == 2: - choices = [("NotDuplicates", "Ces événements sont différents")] - choices += [ - ( - "SelectA", - "Ces événements sont identiques, on conserve A et on masque B", - ) - ] - choices += [ - ( - "SelectB", - "Ces événements sont identiques, on conserve B et on masque A", - ) - ] - choices += [ - ("Merge", "Ces événements sont identiques, créé une nouvelle version par fusion") - ] - else: - choices = [("NotDuplicates", "Ces événements sont tous différents")] - for i in auc[0:nb_events]: + choices = [] + for i, e in enumerate(events): + if e.status != Event.STATUS.TRASH: + il = auc[i] choices += [ ( - "Remove" + i, - "L'événement " - + i - + " n'est pas identique aux autres, on le rend indépendant", + "Select" + il, + _("These inputs represent the same event, and {} is selected as the representative version.").format(il) ) ] - for i in auc[0:nb_events]: + choices += [ + ("Merge", _("These entries represent the same event, and a new one is created by merging them.")) + ] + for i, e in enumerate(events): + if e.status != Event.STATUS.TRASH: + il = auc[i] choices += [ ( - "Select" + i, - "Ces événements sont identiques, on conserve " - + i - + " et on masque les autres", - ) + "Remove" + il, + _("event {} is different from the others, we make it independent").format(il)) ] - 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 @@ -248,7 +232,7 @@ class MergeDuplicates(Form): super().__init__(*args, **kwargs) 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(): diff --git a/src/agenda_culturel/locale/fr/LC_MESSAGES/django.po b/src/agenda_culturel/locale/fr/LC_MESSAGES/django.po index 8f531c0..791913e 100644 --- a/src/agenda_culturel/locale/fr/LC_MESSAGES/django.po +++ b/src/agenda_culturel/locale/fr/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: agenda_culturel\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" "Last-Translator: Jean-Marie Favreau \n" "Language-Team: Jean-Marie Favreau \n" @@ -91,8 +91,8 @@ msgid "Evening" msgstr "Soir" #: agenda_culturel/forms.py:44 agenda_culturel/models.py:165 -#: agenda_culturel/models.py:191 agenda_culturel/models.py:417 -#: agenda_culturel/models.py:1494 agenda_culturel/models.py:1599 +#: agenda_culturel/models.py:191 agenda_culturel/models.py:440 +#: agenda_culturel/models.py:1512 agenda_culturel/models.py:1617 msgid "Category" 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." 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 {}" msgstr "Appliquer la catégorie {} à l'événement {}" -#: agenda_culturel/forms.py:421 agenda_culturel/models.py:341 -#: agenda_culturel/models.py:1651 +#: agenda_culturel/forms.py:405 agenda_culturel/models.py:364 +#: agenda_culturel/models.py:1669 msgid "Place" msgstr "Lieu" -#: agenda_culturel/forms.py:423 +#: agenda_culturel/forms.py:407 msgid "Create a missing place" msgstr "Créer un lieu manquant" -#: agenda_culturel/forms.py:433 +#: agenda_culturel/forms.py:417 msgid "Add \"{}\" to the aliases of the place" 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" msgstr "" "Lors de l'enregistrement, utiliser des alias pour détecter tous les " "événements correspondants dont la place est manquante." #: agenda_culturel/models.py:49 agenda_culturel/models.py:94 -#: agenda_culturel/models.py:172 agenda_culturel/models.py:303 -#: agenda_culturel/models.py:320 agenda_culturel/models.py:1366 -#: agenda_culturel/models.py:1440 +#: agenda_culturel/models.py:172 agenda_culturel/models.py:326 +#: agenda_culturel/models.py:343 agenda_culturel/models.py:1384 +#: agenda_culturel/models.py:1458 msgid "Name" msgstr "Nom" @@ -199,7 +227,7 @@ msgstr "Catégories" msgid "Tag name" 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" msgstr "Description" @@ -237,51 +265,51 @@ msgstr "" msgid "Duplicated events" msgstr "Événements dupliqués" -#: agenda_culturel/models.py:303 +#: agenda_culturel/models.py:326 msgid "Name of the location" msgstr "Nom de la position" -#: agenda_culturel/models.py:306 +#: agenda_culturel/models.py:329 msgid "Main" msgstr "Principale" -#: agenda_culturel/models.py:307 +#: agenda_culturel/models.py:330 msgid "This location is one of the main locations (shown first)." msgstr "Cette position est une position principale (affichée en premier)." -#: agenda_culturel/models.py:312 +#: agenda_culturel/models.py:335 msgid "Reference location" msgstr "Position de référence" -#: agenda_culturel/models.py:313 +#: agenda_culturel/models.py:336 msgid "Reference locations" msgstr "Positions de référence" -#: agenda_culturel/models.py:320 +#: agenda_culturel/models.py:343 msgid "Name of the place" msgstr "Nom du lieu" -#: agenda_culturel/models.py:322 +#: agenda_culturel/models.py:345 msgid "Address" msgstr "Adresse" -#: agenda_culturel/models.py:323 +#: agenda_culturel/models.py:346 msgid "Address of this place (without city name)" msgstr "Adresse de ce lieu (sans le nom de la ville)" -#: agenda_culturel/models.py:327 +#: agenda_culturel/models.py:350 msgid "City" msgstr "Ville" -#: agenda_culturel/models.py:327 +#: agenda_culturel/models.py:350 msgid "City name" msgstr "Nom de la ville" -#: agenda_culturel/models.py:332 +#: agenda_culturel/models.py:355 msgid "Alternative names" msgstr "Noms alternatifs" -#: agenda_culturel/models.py:334 +#: agenda_culturel/models.py:357 msgid "" "Alternative names or addresses used to match a place with the free-form " "location of an event." @@ -289,77 +317,77 @@ msgstr "" "Noms et adresses alternatives qui seront utilisées pour associer une adresse " "avec la localisation en forme libre d'un événement" -#: agenda_culturel/models.py:342 +#: agenda_culturel/models.py:365 msgid "Places" msgstr "Lieux" -#: agenda_culturel/models.py:395 agenda_culturel/models.py:1481 +#: agenda_culturel/models.py:418 agenda_culturel/models.py:1499 msgid "Published" msgstr "Publié" -#: agenda_culturel/models.py:396 +#: agenda_culturel/models.py:419 msgid "Draft" msgstr "Brouillon" -#: agenda_culturel/models.py:397 +#: agenda_culturel/models.py:420 msgid "Trash" msgstr "Corbeille" -#: agenda_culturel/models.py:408 +#: agenda_culturel/models.py:431 msgid "Title" msgstr "Titre" -#: agenda_culturel/models.py:408 +#: agenda_culturel/models.py:431 msgid "Short title" 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" msgstr "Status" -#: agenda_culturel/models.py:418 +#: agenda_culturel/models.py:441 msgid "Category of the event" msgstr "Catégorie de l'événement" -#: agenda_culturel/models.py:425 +#: agenda_culturel/models.py:448 msgid "Day of the event" 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" msgstr "Heure de début" -#: agenda_culturel/models.py:435 +#: agenda_culturel/models.py:458 msgid "End day of the event" 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." msgstr "" "Date de fin de l'événement, uniquement nécessaire s'il est différent du " "premier jour de l'événement" -#: agenda_culturel/models.py:443 +#: agenda_culturel/models.py:466 msgid "Final time" msgstr "Heure de fin" -#: agenda_culturel/models.py:447 +#: agenda_culturel/models.py:470 msgid "Recurrence" 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" msgstr "Localisation" -#: agenda_culturel/models.py:453 +#: agenda_culturel/models.py:476 msgid "Address of the event" msgstr "Adresse de l'événement" -#: agenda_culturel/models.py:459 +#: agenda_culturel/models.py:482 msgid "Location (free form)" msgstr "Localisation (forme libre)" -#: agenda_culturel/models.py:461 +#: agenda_culturel/models.py:484 msgid "" "Address of the event in case its not available in the already known places " "(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 " "lieux disponible (forme libre)" -#: agenda_culturel/models.py:471 +#: agenda_culturel/models.py:494 msgid "General description of the event" msgstr "Description générale de l'événement" -#: agenda_culturel/models.py:477 +#: agenda_culturel/models.py:500 msgid "Illustration (local image)" msgstr "Illustration (image locale)" -#: agenda_culturel/models.py:478 +#: agenda_culturel/models.py:501 msgid "Illustration image stored in the agenda server" msgstr "Image d'illustration stockée sur le serveur de l'agenda" -#: agenda_culturel/models.py:485 +#: agenda_culturel/models.py:508 msgid "Illustration" msgstr "Illustration" -#: agenda_culturel/models.py:486 +#: agenda_culturel/models.py:509 msgid "URL of the illustration image" msgstr "URL de l'image illustrative" -#: agenda_culturel/models.py:492 +#: agenda_culturel/models.py:515 msgid "Illustration description" 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" msgstr "Texte alternatif utiliser par les lecteurs d'écrans pour l'image" -#: agenda_culturel/models.py:500 -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 +#: agenda_culturel/models.py:524 msgid "Importation source" msgstr "Source d'importation" -#: agenda_culturel/models.py:510 +#: agenda_culturel/models.py:525 msgid "Importation source used to detect removed entries." 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" msgstr "UUIDs" -#: agenda_culturel/models.py:517 +#: agenda_culturel/models.py:532 msgid "UUIDs from import to detect duplicated entries." 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" msgstr "URLs" -#: agenda_culturel/models.py:524 +#: agenda_culturel/models.py:539 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é." -#: agenda_culturel/models.py:531 +#: agenda_culturel/models.py:546 msgid "Tags" msgstr "Étiquettes" -#: agenda_culturel/models.py:532 +#: agenda_culturel/models.py:547 msgid "A list of tags that describe the event." msgstr "Une liste d'étiquettes décrivant l'événement" -#: agenda_culturel/models.py:539 -msgid "Possibly duplicated" -msgstr "Possibles doublons" +#: agenda_culturel/models.py:554 +msgid "Other versions" +msgstr "" -#: agenda_culturel/models.py:604 +#: agenda_culturel/models.py:619 msgid "Event" msgstr "Événement" -#: agenda_culturel/models.py:605 +#: agenda_culturel/models.py:620 msgid "Events" msgstr "Événements" -#: agenda_culturel/models.py:1357 +#: agenda_culturel/models.py:1375 msgid "Contact message" msgstr "Message de contact" -#: agenda_culturel/models.py:1358 +#: agenda_culturel/models.py:1376 msgid "Contact messages" msgstr "Messages de contact" -#: agenda_culturel/models.py:1361 +#: agenda_culturel/models.py:1379 msgid "Subject" msgstr "Sujet" -#: agenda_culturel/models.py:1362 +#: agenda_culturel/models.py:1380 msgid "The subject of your message" msgstr "Sujet de votre message" -#: agenda_culturel/models.py:1367 +#: agenda_culturel/models.py:1385 msgid "Your name" msgstr "Votre nom" -#: agenda_culturel/models.py:1373 +#: agenda_culturel/models.py:1391 msgid "Email address" msgstr "Adresse email" -#: agenda_culturel/models.py:1374 +#: agenda_culturel/models.py:1392 msgid "Your email address" msgstr "Votre adresse email" -#: agenda_culturel/models.py:1379 +#: agenda_culturel/models.py:1397 msgid "Message" msgstr "Message" -#: agenda_culturel/models.py:1379 +#: agenda_culturel/models.py:1397 msgid "Your 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" msgstr "Spam" -#: agenda_culturel/models.py:1385 +#: agenda_culturel/models.py:1403 msgid "This message is a 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" 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" 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" msgstr "Commentaires" -#: agenda_culturel/models.py:1398 +#: agenda_culturel/models.py:1416 msgid "Comments on the message from the moderation team" 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" msgstr "Import récurrent" -#: agenda_culturel/models.py:1411 +#: agenda_culturel/models.py:1429 msgid "Recurrent imports" msgstr "Imports récurrents" -#: agenda_culturel/models.py:1415 +#: agenda_culturel/models.py:1433 msgid "ical" msgstr "ical" -#: agenda_culturel/models.py:1416 +#: agenda_culturel/models.py:1434 msgid "ical no busy" msgstr "ical sans busy" -#: agenda_culturel/models.py:1417 +#: agenda_culturel/models.py:1435 msgid "ical no VC" msgstr "ical sans VC" -#: agenda_culturel/models.py:1418 +#: agenda_culturel/models.py:1436 msgid "lacoope.org" msgstr "lacoope.org" -#: agenda_culturel/models.py:1419 +#: agenda_culturel/models.py:1437 msgid "la comédie" msgstr "la comédie" -#: agenda_culturel/models.py:1420 +#: agenda_culturel/models.py:1438 msgid "le fotomat" msgstr "le fotomat" -#: agenda_culturel/models.py:1421 +#: agenda_culturel/models.py:1439 msgid "la puce à l'oreille" msgstr "la puce à loreille" -#: agenda_culturel/models.py:1422 +#: agenda_culturel/models.py:1440 msgid "Plugin wordpress MEC" msgstr "Plugin wordpress MEC" -#: agenda_culturel/models.py:1423 +#: agenda_culturel/models.py:1441 msgid "É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" msgstr "la cour des 3 coquins" -#: agenda_culturel/models.py:1425 +#: agenda_culturel/models.py:1443 msgid "Arachnée concert" msgstr "Arachnée concert" -#: agenda_culturel/models.py:1428 +#: agenda_culturel/models.py:1446 msgid "simple" msgstr "simple" -#: agenda_culturel/models.py:1429 +#: agenda_culturel/models.py:1447 msgid "Headless Chromium" msgstr "chromium sans interface" -#: agenda_culturel/models.py:1430 +#: agenda_culturel/models.py:1448 msgid "Headless Chromium (pause)" msgstr "chromium sans interface (pause)" -#: agenda_culturel/models.py:1435 +#: agenda_culturel/models.py:1453 msgid "daily" msgstr "chaque jour" -#: agenda_culturel/models.py:1437 +#: agenda_culturel/models.py:1455 msgid "weekly" msgstr "chaque semaine" -#: agenda_culturel/models.py:1442 +#: agenda_culturel/models.py:1460 msgid "" "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." @@ -587,135 +607,135 @@ msgstr "" "Nom de l'import récurrent. Attention à choisir un nom compréhensible, car il " "sera public, et affiché sur la page à propos du site." -#: agenda_culturel/models.py:1449 +#: agenda_culturel/models.py:1467 msgid "Processor" msgstr "Processeur" -#: agenda_culturel/models.py:1452 +#: agenda_culturel/models.py:1470 msgid "Downloader" msgstr "Téléchargeur" -#: agenda_culturel/models.py:1459 +#: agenda_culturel/models.py:1477 msgid "Import recurrence" msgstr "Récurrence d'import" -#: agenda_culturel/models.py:1466 +#: agenda_culturel/models.py:1484 msgid "Source" msgstr "Source" -#: agenda_culturel/models.py:1467 +#: agenda_culturel/models.py:1485 msgid "URL of the source document" msgstr "URL du document source" -#: agenda_culturel/models.py:1471 +#: agenda_culturel/models.py:1489 msgid "Browsable url" 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." 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)" 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" msgstr "Adresse de chaque événement importé" -#: agenda_culturel/models.py:1495 +#: agenda_culturel/models.py:1513 msgid "Category of each imported event" msgstr "Catégorie de chaque événement importé" -#: agenda_culturel/models.py:1503 +#: agenda_culturel/models.py:1521 msgid "Tags for each imported event" 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." msgstr "Une liste d'étiquettes décrivant chaque événement importé" -#: agenda_culturel/models.py:1533 +#: agenda_culturel/models.py:1551 msgid "Running" msgstr "En cours" -#: agenda_culturel/models.py:1534 +#: agenda_culturel/models.py:1552 msgid "Canceled" msgstr "Annulé" -#: agenda_culturel/models.py:1535 +#: agenda_culturel/models.py:1553 msgid "Success" msgstr "Succès" -#: agenda_culturel/models.py:1536 +#: agenda_culturel/models.py:1554 msgid "Failed" msgstr "Erreur" -#: agenda_culturel/models.py:1539 +#: agenda_culturel/models.py:1557 msgid "Batch importation" msgstr "Importation par lot" -#: agenda_culturel/models.py:1540 +#: agenda_culturel/models.py:1558 msgid "Batch importations" msgstr "Importations par lot" -#: agenda_culturel/models.py:1548 +#: agenda_culturel/models.py:1566 msgid "Reference to the recurrent import processing" 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)" 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." msgstr "URL source si aucun import récurrent n'est associé" -#: agenda_culturel/models.py:1571 +#: agenda_culturel/models.py:1589 msgid "Error message" msgstr "Votre message" -#: agenda_culturel/models.py:1575 +#: agenda_culturel/models.py:1593 msgid "Number of collected events" msgstr "Nombre d'événements collectés" -#: agenda_culturel/models.py:1578 +#: agenda_culturel/models.py:1596 msgid "Number of imported events" msgstr "Nombre d'événements importés" -#: agenda_culturel/models.py:1581 +#: agenda_culturel/models.py:1599 msgid "Number of updated events" msgstr "Nombre d'événements mis à jour" -#: agenda_culturel/models.py:1584 +#: agenda_culturel/models.py:1602 msgid "Number of removed events" msgstr "Nombre d'événements supprimés" -#: agenda_culturel/models.py:1592 +#: agenda_culturel/models.py:1610 msgid "Weight" msgstr "Poids" -#: agenda_culturel/models.py:1593 +#: agenda_culturel/models.py:1611 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" -#: agenda_culturel/models.py:1600 +#: agenda_culturel/models.py:1618 msgid "Category applied to the event" msgstr "Catégorie appliquée à l'événement" -#: agenda_culturel/models.py:1605 +#: agenda_culturel/models.py:1623 msgid "Contained in the title" msgstr "Contenu dans le titre" -#: agenda_culturel/models.py:1606 +#: agenda_culturel/models.py:1624 msgid "Text contained in the event title" msgstr "Texte contenu dans le titre de l'événement" -#: agenda_culturel/models.py:1612 +#: agenda_culturel/models.py:1630 msgid "Exact title extract" msgstr "Extrait exact du titre" -#: agenda_culturel/models.py:1614 +#: agenda_culturel/models.py:1632 msgid "" "If checked, the extract will be searched for in the title using the exact " "form (capitals, accents)." @@ -723,19 +743,19 @@ msgstr "" "Si coché, l'extrait sera recherché dans le titre en utilisant la forme " "exacte (majuscules, accents)" -#: agenda_culturel/models.py:1620 +#: agenda_culturel/models.py:1638 msgid "Contained in the description" msgstr "Contenu dans la description" -#: agenda_culturel/models.py:1621 +#: agenda_culturel/models.py:1639 msgid "Text contained in the description" msgstr "Texte contenu dans la description" -#: agenda_culturel/models.py:1627 +#: agenda_culturel/models.py:1645 msgid "Exact description extract" msgstr "Extrait exact de description" -#: agenda_culturel/models.py:1629 +#: agenda_culturel/models.py:1647 msgid "" "If checked, the extract will be searched for in the description using the " "exact form (capitals, accents)." @@ -743,19 +763,19 @@ msgstr "" "Si coché, l'extrait sera recherché dans la description en utilisant la forme " "exacte (majuscules, accents)" -#: agenda_culturel/models.py:1635 +#: agenda_culturel/models.py:1653 msgid "Contained in the location" msgstr "Contenu dans la localisation" -#: agenda_culturel/models.py:1636 +#: agenda_culturel/models.py:1654 msgid "Text contained in the event location" msgstr "Texte contenu dans la localisation de l'événement" -#: agenda_culturel/models.py:1642 +#: agenda_culturel/models.py:1660 msgid "Exact location extract" msgstr "Extrait exact de localisation" -#: agenda_culturel/models.py:1644 +#: agenda_culturel/models.py:1662 msgid "" "If checked, the extract will be searched for in the location using the exact " "form (capitals, accents)." @@ -763,56 +783,56 @@ msgstr "" "Si coché, l'extrait sera recherché dans la localisation en utilisant la " "forme exacte (majuscules, accents)" -#: agenda_culturel/models.py:1652 +#: agenda_culturel/models.py:1670 msgid "Location from place" msgstr "Localisation depuis le lieu" -#: agenda_culturel/models.py:1661 +#: agenda_culturel/models.py:1679 msgid "Categorisation rule" msgstr "Règle de catégorisation" -#: agenda_culturel/models.py:1662 +#: agenda_culturel/models.py:1680 msgid "Categorisation rules" 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" 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" msgstr "Text tel que présenté aux modérateurices" -#: agenda_culturel/models.py:1740 +#: agenda_culturel/models.py:1758 msgid "Moderation question" msgstr "Question de modération" -#: agenda_culturel/models.py:1741 +#: agenda_culturel/models.py:1759 msgid "Moderation questions" msgstr "Questions de modération" -#: agenda_culturel/models.py:1766 +#: agenda_culturel/models.py:1784 msgid "Associated question from moderation" msgstr "Question associée pour la modération" -#: agenda_culturel/models.py:1771 +#: agenda_culturel/models.py:1789 msgid "Answer" msgstr "Réponse" -#: agenda_culturel/models.py:1778 +#: agenda_culturel/models.py:1796 msgid "Adds tags" 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." msgstr "" "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" 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." msgstr "" "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." 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." 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." msgstr "Les événements ont été marqués comme non dupliqués." -#: agenda_culturel/views.py:1524 -msgid "The selected event has been retained, while the other has been masked." -msgstr "L'événement sélectionné a été retenu, l'autre a été masqué." +#: agenda_culturel/views.py:1522 +msgid "The selected event has been set as representative" +msgstr "L'événement sélectionné a été défini comme representatif." -#: agenda_culturel/views.py:1531 -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 +#: agenda_culturel/views.py:1532 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." -#: agenda_culturel/views.py:1577 +#: agenda_culturel/views.py:1567 msgid "Cleaning up duplicates: {} item(s) fixed." 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." msgstr "L'événement a été marqué dupliqué avec succès." -#: agenda_culturel/views.py:1632 +#: agenda_culturel/views.py:1622 msgid "" "The event has been successfully flagged as a duplicate. The moderation team " "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 " "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." 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." 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." msgstr "" "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." msgstr "" "Les règles ont été appliquées avec succès et {} événements ont été " "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." msgstr "" "Les règles ont été appliquées avec succès et aucun événement n'a été " "catégorisé" -#: agenda_culturel/views.py:1769 +#: agenda_culturel/views.py:1759 msgid "" "The rules were successfully applied and 1 event with default category was " "categorised." @@ -1039,7 +1054,7 @@ msgstr "" "Les règles ont été appliquées avec succès et 1 événement avec catégorie par " "défaut a été catégorisé" -#: agenda_culturel/views.py:1776 +#: agenda_culturel/views.py:1766 msgid "" "The rules were successfully applied and {} events with default category were " "categorised." @@ -1047,51 +1062,45 @@ msgstr "" "Les règles ont été appliquées avec succès et {} événements avec catégorie " "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." 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:2049 +#: agenda_culturel/views.py:1939 agenda_culturel/views.py:2001 +#: agenda_culturel/views.py:2039 msgid "{} events have been updated." msgstr "{} événements ont été mis à jour." -#: agenda_culturel/views.py:1952 agenda_culturel/views.py:2013 -#: agenda_culturel/views.py:2052 +#: agenda_culturel/views.py:1942 agenda_culturel/views.py:2003 +#: agenda_culturel/views.py:2042 msgid "1 event has been updated." msgstr "1 événement a été mis à jour" -#: agenda_culturel/views.py:1954 agenda_culturel/views.py:2015 -#: agenda_culturel/views.py:2054 +#: agenda_culturel/views.py:1944 agenda_culturel/views.py:2005 +#: agenda_culturel/views.py:2044 msgid "No events have been modified." 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." 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." 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." 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." 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." 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." msgstr "L'étiquette a été créée avec succès." - -#~ msgid "Fixed" -#~ msgstr "Résolu" - -#~ msgid "Not fixed" -#~ msgstr "Non résolu" diff --git a/src/agenda_culturel/models.py b/src/agenda_culturel/models.py index b98dc87..5512533 100644 --- a/src/agenda_culturel/models.py +++ b/src/agenda_culturel/models.py @@ -228,7 +228,10 @@ class DuplicatedEvents(models.Model): return reverse("view_duplicate", kwargs={"pk": self.pk}) 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): # for all objects associated to this group @@ -285,7 +288,7 @@ class DuplicatedEvents(models.Model): def fix_similar_entries(): 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()) similar = len([c for c in comp if not c["similar"]]) == 0 if similar: @@ -301,6 +304,17 @@ class DuplicatedEvents(models.Model): 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): if self.representative and not self.representative in self.event_set.all(): self.representative = None diff --git a/src/agenda_culturel/templates/agenda_culturel/page-event.html b/src/agenda_culturel/templates/agenda_culturel/page-event.html index 3174d00..8cef71c 100644 --- a/src/agenda_culturel/templates/agenda_culturel/page-event.html +++ b/src/agenda_culturel/templates/agenda_culturel/page-event.html @@ -119,7 +119,7 @@ {% if user.is_authenticated %} {% endif %} {% endif %} diff --git a/src/agenda_culturel/templatetags/duplicated_extra.py b/src/agenda_culturel/templatetags/duplicated_extra.py index dfb2de3..775f4eb 100644 --- a/src/agenda_culturel/templatetags/duplicated_extra.py +++ b/src/agenda_culturel/templatetags/duplicated_extra.py @@ -16,7 +16,7 @@ register = template.Library() @register.simple_tag 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: return mark_safe( diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 2e195e4..bc04bd1 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -1396,12 +1396,16 @@ def run_all_rimports(request, status=None): class DuplicatedEventsFilter(django_filters.FilterSet): fixed = django_filters.BooleanFilter( - field_name='representative', lookup_expr='isnull', exclude=True) + label="Résolu", + field_name='representative', method="fixed_qs") class Meta: model = DuplicatedEvents fields = [] + + def fixed_qs(self, queryset, name, value): + return DuplicatedEvents.not_fixed_qs(queryset, value) class DuplicatedEventsDetailView(LoginRequiredMixin, DetailView): model = DuplicatedEvents @@ -1480,16 +1484,17 @@ def merge_duplicate(request, pk): ["agenda_culturel.change_event", "agenda_culturel.change_duplicatedevents"] ) def fix_duplicate(request, pk): - edup = get_object_or_404(DuplicatedEvents, pk=pk) - form = FixDuplicates(nb_events=edup.nb_duplicated()) + edup = get_object_or_404(DuplicatedEvents.objects.select_related(), pk=pk) 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_action_no_duplicates(): + # all events are different events = edup.get_duplicated() + # get redirection date if len(events) == 0: date = None else: @@ -1501,6 +1506,7 @@ def fix_duplicate(request, pk): date = s_event.start_day 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() if date is None: return HttpResponseRedirect(reverse_lazy("home")) @@ -1510,44 +1516,32 @@ def fix_duplicate(request, pk): ) elif form.is_action_select(): + # one element has been selected to be the representative selected = form.get_selected_event(edup) - nb = edup.fix(selected) - 1 - if nb == 1: - 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." - ), - ) + edup.fix(selected) + messages.success(request, _("The selected event has been set as representative")) return HttpResponseRedirect(edup.get_absolute_url()) elif form.is_action_remove(): + # one element is removed from the set event = form.get_selected_event(edup) event.other_versions = None if edup.representative == event: edup.representative = None event.save() edup.save() - messages.success( - request, - _( - "The event has been withdrawn from the group and made independent." - ), - ) + messages.success(request, _("The event has been withdrawn from the group and made independent.")) if edup.nb_duplicated() == 1: return HttpResponseRedirect(edup.get_absolute_url()) else: - form = FixDuplicates(nb_events=edup.nb_duplicated()) + form = FixDuplicates(edup=edup) else: + # otherwise, a new event will be created using a merging process return HttpResponseRedirect( reverse_lazy("merge_duplicate", args=[edup.pk]) ) + else: + form = FixDuplicates(edup=edup) + return render( request,