From 8f488cf7c53a31dd0d67d3e1c47b257c3778a2b9 Mon Sep 17 00:00:00 2001 From: Jean-Marie Favreau Date: Sun, 27 Apr 2025 23:12:10 +0200 Subject: [PATCH] =?UTF-8?q?On=20permet=20l'import=20des=20liens=20pr=C3=A9?= =?UTF-8?q?sents=20dans=20une=20page=20html=20coll=C3=A9e=20dans=20le=20fo?= =?UTF-8?q?rmulaire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agenda_culturel/celery.py | 19 +- src/agenda_culturel/forms.py | 6 +- .../locale/fr/LC_MESSAGES/django.po | 410 +++++++++--------- .../batchimportation_form.html | 34 +- .../templates/agenda_culturel/side-nav.html | 4 + .../views/import_batch_views.py | 37 +- 6 files changed, 289 insertions(+), 221 deletions(-) diff --git a/src/agenda_culturel/celery.py b/src/agenda_culturel/celery.py index 4478e57..77965a7 100644 --- a/src/agenda_culturel/celery.py +++ b/src/agenda_culturel/celery.py @@ -540,13 +540,20 @@ def import_events_from_urls( ): for ucat in urls_cat_tags: if ucat is not None: - url = ucat[0] - cat = ucat[1] - tags = ucat[2] + url = None + cat = None + tags = None + if isinstance(ucat, str): + url = ucat + elif isinstance(ucat, (list, tuple)): + url = ucat[0] + cat = ucat[1] + tags = ucat[2] - import_events_from_url.delay( - url, cat, tags, user_id=user_id, email=email, comments=comments - ) + if url is not None: + import_events_from_url.delay( + url, cat, tags, user_id=user_id, email=email, comments=comments + ) @app.task(base=ChromiumTask, bind=True) diff --git a/src/agenda_culturel/forms.py b/src/agenda_culturel/forms.py index 9c25b46..c8f3f60 100644 --- a/src/agenda_culturel/forms.py +++ b/src/agenda_culturel/forms.py @@ -537,10 +537,10 @@ class EventModerateForm(ModelForm): class BatchImportationForm(Form): required_css_class = "required" - json = CharField( - label="JSON", + data = CharField( + label=_("Data"), widget=Textarea(attrs={"rows": "10"}), - help_text=_("JSON in the format expected for the import."), + help_text=_("Supported formats: json, html."), required=True, ) diff --git a/src/agenda_culturel/locale/fr/LC_MESSAGES/django.po b/src/agenda_culturel/locale/fr/LC_MESSAGES/django.po index 4b33216..dafeb2e 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: 2025-04-27 10:08+0200\n" +"POT-Creation-Date: 2025-04-27 23:08+0200\n" "PO-Revision-Date: 2023-10-29 14:16+0000\n" "Last-Translator: Jean-Marie Favreau \n" "Language-Team: Jean-Marie Favreau \n" @@ -119,7 +119,7 @@ msgstr "" "directement. Les modérateurs peuvent choisir de le publier ou non." #: agenda_culturel/db_importer.py:376 agenda_culturel/db_importer.py:383 -#: agenda_culturel/models.py:2387 +#: agenda_culturel/models.py:2400 msgid "Warning" msgstr "Warning" @@ -200,12 +200,12 @@ msgstr "dernier créé d'abord" msgid "Imported from" msgstr "Importé depuis" -#: agenda_culturel/filters.py:478 agenda_culturel/models.py:872 -#: agenda_culturel/models.py:2686 +#: agenda_culturel/filters.py:478 agenda_culturel/models.py:867 +#: agenda_culturel/models.py:2699 msgid "Status" msgstr "Status" -#: agenda_culturel/filters.py:479 agenda_culturel/models.py:2449 +#: agenda_culturel/filters.py:479 agenda_culturel/models.py:2462 msgid "Closed" msgstr "Fermé" @@ -214,7 +214,7 @@ msgid "Open" msgstr "Ouvert" #: agenda_culturel/filters.py:483 agenda_culturel/filters.py:484 -#: agenda_culturel/models.py:2443 +#: agenda_culturel/models.py:2456 msgid "Spam" msgstr "Spam" @@ -222,7 +222,7 @@ msgstr "Spam" msgid "Non spam" msgstr "Non spam" -#: agenda_culturel/filters.py:489 agenda_culturel/models.py:2464 +#: agenda_culturel/filters.py:489 agenda_culturel/models.py:2477 msgid "Type" msgstr "Type" @@ -253,11 +253,11 @@ msgstr "" msgid "Your email" msgstr "Votre adresse email" -#: agenda_culturel/forms.py:168 agenda_culturel/models.py:2431 +#: agenda_culturel/forms.py:168 agenda_culturel/models.py:2444 msgid "Your email address" msgstr "Votre adresse email" -#: agenda_culturel/forms.py:174 agenda_culturel/models.py:2456 +#: agenda_culturel/forms.py:174 agenda_culturel/models.py:2469 msgid "Comments" msgstr "Commentaires" @@ -273,19 +273,19 @@ msgid "Receive notification of publication or leave a message for moderation" msgstr "Être notifié de la publication ou laisser un message à la modération" #: agenda_culturel/forms.py:212 agenda_culturel/models.py:312 -#: agenda_culturel/models.py:880 agenda_culturel/models.py:2610 -#: agenda_culturel/models.py:2721 +#: agenda_culturel/models.py:875 agenda_culturel/models.py:2623 +#: agenda_culturel/models.py:2734 msgid "Category" msgstr "Catégorie" #: agenda_culturel/forms.py:218 agenda_culturel/forms.py:251 #: agenda_culturel/forms.py:297 agenda_culturel/forms.py:481 -#: agenda_culturel/models.py:366 agenda_culturel/models.py:997 +#: agenda_culturel/models.py:366 agenda_culturel/models.py:992 msgid "Tags" msgstr "Étiquettes" #: agenda_culturel/forms.py:226 agenda_culturel/forms.py:646 -#: agenda_culturel/models.py:1127 +#: agenda_culturel/models.py:1117 msgid "Event" msgstr "Événement" @@ -328,13 +328,13 @@ msgstr "Cet événement est récurrent" msgid "Details" msgstr "Détails" -#: agenda_culturel/forms.py:387 agenda_culturel/models.py:909 -#: agenda_culturel/models.py:2585 +#: agenda_culturel/forms.py:387 agenda_culturel/models.py:904 +#: agenda_culturel/models.py:2598 msgid "Location" msgstr "Localisation" #: agenda_culturel/forms.py:392 agenda_culturel/models.py:110 -#: agenda_culturel/models.py:953 +#: agenda_culturel/models.py:948 msgid "Illustration" msgstr "Illustration" @@ -358,9 +358,13 @@ msgstr "L'heure de fin ne peut pas être avant l'heure de début." msgid "Select tags from existing ones." msgstr "Sélectionner des étiquettes depuis celles existantes." +#: agenda_culturel/forms.py:541 +msgid "Data" +msgstr "" + #: agenda_culturel/forms.py:543 -msgid "JSON in the format expected for the import." -msgstr "JSON dans le format attendu pour l'import" +msgid "Supported formats: json, html." +msgstr "" #: agenda_culturel/forms.py:565 msgid " (locally modified version)" @@ -408,8 +412,8 @@ msgstr "Valeur de la version sélectionnée" msgid "Apply category {} to the event {}" msgstr "Appliquer la catégorie {} à l'événement {}" -#: agenda_culturel/forms.py:872 agenda_culturel/models.py:697 -#: agenda_culturel/models.py:2773 +#: agenda_culturel/forms.py:872 agenda_culturel/models.py:692 +#: agenda_culturel/models.py:2786 msgid "Place" msgstr "Lieu" @@ -431,7 +435,7 @@ msgstr "" msgid "Header" msgstr "Entête" -#: agenda_culturel/forms.py:932 agenda_culturel/models.py:659 +#: agenda_culturel/forms.py:932 agenda_culturel/models.py:654 msgid "Address" msgstr "Adresse" @@ -447,7 +451,7 @@ msgstr "Informations" msgid "Add a comment" msgstr "Ajouter un commentaire" -#: agenda_culturel/forms.py:1018 agenda_culturel/models.py:2874 +#: agenda_culturel/forms.py:1018 agenda_culturel/models.py:2887 msgid "Period type" msgstr "Type de période" @@ -455,7 +459,7 @@ msgstr "Type de période" msgid "ICAL file" msgstr "Fichier ICAL" -#: agenda_culturel/import_tasks/extractor.py:226 +#: agenda_culturel/import_tasks/extractor.py:229 msgid "Unknown title" msgstr "Titre inconnu" @@ -561,9 +565,9 @@ msgid "User profiles" msgstr "" #: agenda_culturel/models.py:195 agenda_culturel/models.py:242 -#: agenda_culturel/models.py:321 agenda_culturel/models.py:616 -#: agenda_culturel/models.py:657 agenda_culturel/models.py:763 -#: agenda_culturel/models.py:2423 agenda_culturel/models.py:2535 +#: agenda_culturel/models.py:321 agenda_culturel/models.py:611 +#: agenda_culturel/models.py:652 agenda_culturel/models.py:758 +#: agenda_culturel/models.py:2436 agenda_culturel/models.py:2548 msgid "Name" msgstr "Nom" @@ -623,8 +627,8 @@ msgstr "Catégories" msgid "Tag name" msgstr "Nom de l'étiquette" -#: agenda_culturel/models.py:329 agenda_culturel/models.py:680 -#: agenda_culturel/models.py:779 agenda_culturel/models.py:936 +#: agenda_culturel/models.py:329 agenda_culturel/models.py:675 +#: agenda_culturel/models.py:774 agenda_culturel/models.py:931 msgid "Description" msgstr "Description" @@ -632,8 +636,8 @@ msgstr "Description" msgid "Description of the tag" msgstr "Description de l'étiquette" -#: agenda_culturel/models.py:336 agenda_culturel/models.py:2390 -#: agenda_culturel/models.py:2437 +#: agenda_culturel/models.py:336 agenda_culturel/models.py:2403 +#: agenda_culturel/models.py:2450 msgid "Message" msgstr "Message" @@ -696,50 +700,50 @@ msgstr "" msgid "Duplicated events" msgstr "Événements dupliqués" -#: agenda_culturel/models.py:617 +#: agenda_culturel/models.py:612 msgid "Name of the location" msgstr "Nom de la position" -#: agenda_culturel/models.py:628 +#: agenda_culturel/models.py:623 msgid "Main" msgstr "Principale" -#: agenda_culturel/models.py:630 +#: agenda_culturel/models.py:625 msgid "This location is one of the main locations (shown first higher values)." msgstr "" "Cette position est une position principale (affichage en premier des plus " "grandes valeurs)." -#: agenda_culturel/models.py:635 +#: agenda_culturel/models.py:630 msgid "Suggested distance (km)" msgstr "" -#: agenda_culturel/models.py:637 +#: agenda_culturel/models.py:632 msgid "" "If this distance is given, this location is part of the suggested filters." msgstr "" -#: agenda_culturel/models.py:646 +#: agenda_culturel/models.py:641 msgid "Reference location" msgstr "Position de référence" -#: agenda_culturel/models.py:647 +#: agenda_culturel/models.py:642 msgid "Reference locations" msgstr "Positions de référence" -#: agenda_culturel/models.py:657 +#: agenda_culturel/models.py:652 msgid "Name of the place" msgstr "Nom du lieu" -#: agenda_culturel/models.py:660 +#: agenda_culturel/models.py:655 msgid "Address of this place (without city name)" msgstr "Adresse de ce lieu (sans le nom de la ville)" -#: agenda_culturel/models.py:665 +#: agenda_culturel/models.py:660 msgid "Postcode" msgstr "Code postal" -#: agenda_culturel/models.py:667 +#: agenda_culturel/models.py:662 msgid "" "The post code is not displayed, but makes it easier to find an address when " "you enter it." @@ -747,23 +751,23 @@ msgstr "" "Le code postal ne sera pas affiché, mais facilite la recherche d'adresse au " "moment de la saisie." -#: agenda_culturel/models.py:672 +#: agenda_culturel/models.py:667 msgid "City" msgstr "Ville" -#: agenda_culturel/models.py:672 +#: agenda_culturel/models.py:667 msgid "City name" msgstr "Nom de la ville" -#: agenda_culturel/models.py:681 +#: agenda_culturel/models.py:676 msgid "Description of the place, including accessibility." msgstr "Description du lieu, inclus l'accessibilité." -#: agenda_culturel/models.py:688 +#: agenda_culturel/models.py:683 msgid "Alternative names" msgstr "Noms alternatifs" -#: agenda_culturel/models.py:690 +#: agenda_culturel/models.py:685 msgid "" "Alternative names or addresses used to match a place with the free-form " "location of an event." @@ -771,31 +775,31 @@ 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:698 +#: agenda_culturel/models.py:693 msgid "Places" msgstr "Lieux" -#: agenda_culturel/models.py:764 +#: agenda_culturel/models.py:759 msgid "Organisation name" msgstr "Nom de l'organisme" -#: agenda_culturel/models.py:771 +#: agenda_culturel/models.py:766 msgid "Website" msgstr "Site internet" -#: agenda_culturel/models.py:772 +#: agenda_culturel/models.py:767 msgid "Website of the organisation" msgstr "Site internet de l'organisme" -#: agenda_culturel/models.py:780 +#: agenda_culturel/models.py:775 msgid "Description of the organisation." msgstr "Description de l'organisme" -#: agenda_culturel/models.py:787 +#: agenda_culturel/models.py:782 msgid "Principal place" msgstr "Lieu principal" -#: agenda_culturel/models.py:789 +#: agenda_culturel/models.py:784 msgid "" "Place mainly associated with this organizer. Mainly used if there is a " "similarity in the name, to avoid redundant displays." @@ -803,75 +807,75 @@ msgstr "" "Lieu principalement associé à cette organisation. Principalement utilisé " "s'il y a une similarité de nom, pour éviter les affichages redondants." -#: agenda_culturel/models.py:797 +#: agenda_culturel/models.py:792 msgid "Organisation" msgstr "Organisme" -#: agenda_culturel/models.py:798 +#: agenda_culturel/models.py:793 msgid "Organisations" msgstr "Organismes" -#: agenda_culturel/models.py:809 agenda_culturel/models.py:2580 +#: agenda_culturel/models.py:804 agenda_culturel/models.py:2593 msgid "Published" msgstr "Publié" -#: agenda_culturel/models.py:810 +#: agenda_culturel/models.py:805 msgid "Draft" msgstr "Brouillon" -#: agenda_culturel/models.py:811 +#: agenda_culturel/models.py:806 msgid "Trash" msgstr "Corbeille" -#: agenda_culturel/models.py:821 +#: agenda_culturel/models.py:816 msgid "Author currently editing/moderating the event" msgstr "" -#: agenda_culturel/models.py:831 +#: agenda_culturel/models.py:826 msgid "Author of the event creation" msgstr "Auteur de la création de l'événement" -#: agenda_culturel/models.py:840 +#: agenda_culturel/models.py:835 msgid "Author of the last importation" msgstr "Auteur de la dernière importation" -#: agenda_culturel/models.py:849 +#: agenda_culturel/models.py:844 msgid "Author of the last modification" msgstr "Auteur de la dernière modification" -#: agenda_culturel/models.py:858 +#: agenda_culturel/models.py:853 msgid "Author of the last moderation" msgstr "Auteur de la dernière modération" -#: agenda_culturel/models.py:869 +#: agenda_culturel/models.py:864 msgid "Title" msgstr "Titre" -#: agenda_culturel/models.py:886 agenda_culturel/models.py:2859 +#: agenda_culturel/models.py:881 agenda_culturel/models.py:2872 msgid "Start day" msgstr "Date de début" -#: agenda_culturel/models.py:888 +#: agenda_culturel/models.py:883 msgid "Start time" msgstr "Heure de début" -#: agenda_culturel/models.py:894 agenda_culturel/models.py:2860 +#: agenda_culturel/models.py:889 agenda_culturel/models.py:2873 msgid "End day" msgstr "Date de fin" -#: agenda_culturel/models.py:898 +#: agenda_culturel/models.py:893 msgid "End time" msgstr "Heure de fin" -#: agenda_culturel/models.py:901 +#: agenda_culturel/models.py:896 msgid "Recurrence" msgstr "Récurrence" -#: agenda_culturel/models.py:915 +#: agenda_culturel/models.py:910 msgid "Location (free form)" msgstr "Localisation (forme libre)" -#: agenda_culturel/models.py:917 +#: agenda_culturel/models.py:912 msgid "" "Address of the event in case its not available in the already known places " "(free form)" @@ -879,11 +883,11 @@ msgstr "" "Adresse d'un événement si elle n'est pas déjà présente dans la liste des " "lieux disponibles (forme libre)" -#: agenda_culturel/models.py:926 +#: agenda_culturel/models.py:921 msgid "Local event" msgstr "Événement de portée locale" -#: agenda_culturel/models.py:928 +#: agenda_culturel/models.py:923 msgid "" "If the event is a local event, it will not be proposed by default in daily, " "weekly or monthly views, unless the user has explicitly indicated that he " @@ -893,11 +897,11 @@ msgstr "" "les vues quotidiennes, hebdomadaires ou mensuelles, sauf si l'utilisateur a " "explicitement indiqué qu'il souhaite voir ces événements." -#: agenda_culturel/models.py:944 +#: agenda_culturel/models.py:939 msgid "Organisers" msgstr "Organisations" -#: agenda_culturel/models.py:946 +#: agenda_culturel/models.py:941 msgid "" "list of event organisers. Organizers will only be displayed if one of them " "does not normally use the venue." @@ -905,259 +909,259 @@ msgstr "" "Liste des organisations de l'événements. Les organisations seront affichés " "uniquement si au moins un d'entre eux n'utilise pas habituellement le lieu." -#: agenda_culturel/models.py:960 +#: agenda_culturel/models.py:955 msgid "Illustration (URL)" msgstr "Illustration (URL)" -#: agenda_culturel/models.py:961 +#: agenda_culturel/models.py:956 msgid "External URL of the illustration image" msgstr "URL externe de l'image illustrative" -#: agenda_culturel/models.py:967 +#: agenda_culturel/models.py:962 msgid "Illustration description" msgstr "Description de l'illustration" -#: agenda_culturel/models.py:968 +#: agenda_culturel/models.py:963 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:976 +#: agenda_culturel/models.py:971 msgid "Importation source" msgstr "Source d'importation" -#: agenda_culturel/models.py:977 +#: agenda_culturel/models.py:972 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:983 +#: agenda_culturel/models.py:978 msgid "UUIDs" msgstr "UUIDs" -#: agenda_culturel/models.py:984 +#: agenda_culturel/models.py:979 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:990 +#: agenda_culturel/models.py:985 msgid "Online sources or ticketing" msgstr "Sources en ligne ou billetterie" -#: agenda_culturel/models.py:1004 +#: agenda_culturel/models.py:999 msgid "Other versions" msgstr "" -#: agenda_culturel/models.py:1128 +#: agenda_culturel/models.py:1118 msgid "Events" msgstr "Événements" -#: agenda_culturel/models.py:1289 +#: agenda_culturel/models.py:1302 msgid "recurrent import" msgstr "import récurrent" -#: agenda_culturel/models.py:1291 +#: agenda_culturel/models.py:1304 msgid "a non authenticated user" msgstr "un utilisateur non connecté" -#: agenda_culturel/models.py:1813 +#: agenda_culturel/models.py:1826 msgid "Your event has been published" msgstr "Ton événement a été publié" -#: agenda_culturel/models.py:1818 +#: agenda_culturel/models.py:1831 msgid "Your message has not been retained" msgstr "Ton événement n'a pas été retenu" -#: agenda_culturel/models.py:2378 +#: agenda_culturel/models.py:2391 msgid "From contributor" msgstr "D'un·e contributeurice" -#: agenda_culturel/models.py:2379 +#: agenda_culturel/models.py:2392 msgid "Import process" msgstr "Processus d'import" -#: agenda_culturel/models.py:2380 +#: agenda_culturel/models.py:2393 msgid "Update process" msgstr "Processus de mise à jour" -#: agenda_culturel/models.py:2381 +#: agenda_culturel/models.py:2394 msgid "Contact form" msgstr "Formulaire de contact" -#: agenda_culturel/models.py:2382 +#: agenda_culturel/models.py:2395 msgid "Event report" msgstr "Signalemet d'événement" -#: agenda_culturel/models.py:2385 +#: agenda_culturel/models.py:2398 msgid "From contributor (without message)" msgstr "D'un·e contributeurice (sans message)" -#: agenda_culturel/models.py:2391 +#: agenda_culturel/models.py:2404 msgid "Messages" msgstr "Messages" -#: agenda_culturel/models.py:2400 +#: agenda_culturel/models.py:2413 msgid "Subject" msgstr "Sujet" -#: agenda_culturel/models.py:2401 +#: agenda_culturel/models.py:2414 msgid "The subject of your message" msgstr "Sujet de votre message" -#: agenda_culturel/models.py:2407 +#: agenda_culturel/models.py:2420 msgid "Related event" msgstr "Événement associé" -#: agenda_culturel/models.py:2408 +#: agenda_culturel/models.py:2421 msgid "The message is associated with this event." msgstr "Le message est associé à cet événement." -#: agenda_culturel/models.py:2416 +#: agenda_culturel/models.py:2429 msgid "Author of the message" msgstr "Auteur du message" -#: agenda_culturel/models.py:2424 +#: agenda_culturel/models.py:2437 msgid "Your name" msgstr "Votre nom" -#: agenda_culturel/models.py:2430 +#: agenda_culturel/models.py:2443 msgid "Email address" msgstr "Adresse email" -#: agenda_culturel/models.py:2437 +#: agenda_culturel/models.py:2450 msgid "Your message" msgstr "Votre message" -#: agenda_culturel/models.py:2444 +#: agenda_culturel/models.py:2457 msgid "This message is a spam." msgstr "Ce message est un spam." -#: agenda_culturel/models.py:2451 +#: agenda_culturel/models.py:2464 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:2457 +#: agenda_culturel/models.py:2470 msgid "Comments on the message from the moderation team" msgstr "Commentaires sur ce message par l'équipe de modération" -#: agenda_culturel/models.py:2490 agenda_culturel/models.py:2668 +#: agenda_culturel/models.py:2503 agenda_culturel/models.py:2681 msgid "Recurrent import" msgstr "Import récurrent" -#: agenda_culturel/models.py:2491 +#: agenda_culturel/models.py:2504 msgid "Recurrent imports" msgstr "Imports récurrents" -#: agenda_culturel/models.py:2495 +#: agenda_culturel/models.py:2508 msgid "ical" msgstr "ical" -#: agenda_culturel/models.py:2496 +#: agenda_culturel/models.py:2509 msgid "ical no busy" msgstr "ical sans busy" -#: agenda_culturel/models.py:2497 +#: agenda_culturel/models.py:2510 msgid "ical no VC" msgstr "ical sans VC" -#: agenda_culturel/models.py:2498 +#: agenda_culturel/models.py:2511 msgid "ical naive timezone" msgstr "ical timezone naïve" -#: agenda_culturel/models.py:2499 +#: agenda_culturel/models.py:2512 msgid "lacoope.org" msgstr "lacoope.org" -#: agenda_culturel/models.py:2500 +#: agenda_culturel/models.py:2513 msgid "la comédie" msgstr "la comédie" -#: agenda_culturel/models.py:2501 +#: agenda_culturel/models.py:2514 msgid "le fotomat" msgstr "le fotomat" -#: agenda_culturel/models.py:2502 +#: agenda_culturel/models.py:2515 msgid "la puce à l'oreille" msgstr "la puce à loreille" -#: agenda_culturel/models.py:2503 +#: agenda_culturel/models.py:2516 msgid "Plugin wordpress MEC" msgstr "Plugin wordpress MEC" -#: agenda_culturel/models.py:2504 +#: agenda_culturel/models.py:2517 msgid "Événements d'une page FB" msgstr "Événements d'une page FB" -#: agenda_culturel/models.py:2505 +#: agenda_culturel/models.py:2518 msgid "Billetterie Clermont-Ferrand" msgstr "" -#: agenda_culturel/models.py:2506 +#: agenda_culturel/models.py:2519 msgid "Arachnée concert" msgstr "Arachnée concert" -#: agenda_culturel/models.py:2507 +#: agenda_culturel/models.py:2520 msgid "Le Rio" msgstr "Le Rio" -#: agenda_culturel/models.py:2508 +#: agenda_culturel/models.py:2521 msgid "La Raymonde" msgstr "La Raymone" -#: agenda_culturel/models.py:2509 +#: agenda_culturel/models.py:2522 msgid "Agenda apidae tourisme" msgstr "Agenda apidae tourisme" -#: agenda_culturel/models.py:2510 +#: agenda_culturel/models.py:2523 msgid "Agenda iguana (médiathèques)" msgstr "Agenda iguana (médiathèques)" -#: agenda_culturel/models.py:2511 +#: agenda_culturel/models.py:2524 msgid "Mille formes" msgstr "Mille Formes" -#: agenda_culturel/models.py:2512 +#: agenda_culturel/models.py:2525 msgid "Les Amis du Temps des Cerises" msgstr "Les Amis du Temps des Cerises" -#: agenda_culturel/models.py:2513 +#: agenda_culturel/models.py:2526 msgid "Mobilizon" msgstr "Mobilizon" -#: agenda_culturel/models.py:2514 +#: agenda_culturel/models.py:2527 msgid "Le caméléon" msgstr "" -#: agenda_culturel/models.py:2515 +#: agenda_culturel/models.py:2528 msgid "Echosciences" msgstr "" -#: agenda_culturel/models.py:2516 +#: agenda_culturel/models.py:2529 msgid "Hello Asso" msgstr "Hello Asso" -#: agenda_culturel/models.py:2519 +#: agenda_culturel/models.py:2532 msgid "simple" msgstr "simple" -#: agenda_culturel/models.py:2520 +#: agenda_culturel/models.py:2533 msgid "Headless Chromium" msgstr "chromium sans interface" -#: agenda_culturel/models.py:2523 +#: agenda_culturel/models.py:2536 msgid "Headless Chromium (pause)" msgstr "chromium sans interface (pause)" -#: agenda_culturel/models.py:2529 +#: agenda_culturel/models.py:2542 msgid "daily" msgstr "chaque jour" -#: agenda_culturel/models.py:2531 +#: agenda_culturel/models.py:2544 msgid "weekly" msgstr "chaque semaine" -#: agenda_culturel/models.py:2532 +#: agenda_culturel/models.py:2545 msgid "never" msgstr "jamais" -#: agenda_culturel/models.py:2537 +#: agenda_culturel/models.py:2550 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." @@ -1165,151 +1169,151 @@ 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:2544 +#: agenda_culturel/models.py:2557 msgid "Processor" msgstr "Processeur" -#: agenda_culturel/models.py:2550 +#: agenda_culturel/models.py:2563 msgid "Downloader" msgstr "Téléchargeur" -#: agenda_culturel/models.py:2557 +#: agenda_culturel/models.py:2570 msgid "Import recurrence" msgstr "Récurrence d'import" -#: agenda_culturel/models.py:2564 +#: agenda_culturel/models.py:2577 msgid "Source" msgstr "Source" -#: agenda_culturel/models.py:2565 +#: agenda_culturel/models.py:2578 msgid "URL of the source document" msgstr "URL du document source" -#: agenda_culturel/models.py:2570 +#: agenda_culturel/models.py:2583 msgid "Browsable url" msgstr "URL navigable" -#: agenda_culturel/models.py:2572 +#: agenda_culturel/models.py:2585 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:2581 +#: agenda_culturel/models.py:2594 msgid "Status of each imported event (published or draft)" msgstr "Status de chaque événement importé (publié ou brouillon)" -#: agenda_culturel/models.py:2586 +#: agenda_culturel/models.py:2599 msgid "Address for each imported event" msgstr "Adresse de chaque événement importé" -#: agenda_culturel/models.py:2593 +#: agenda_culturel/models.py:2606 msgid "Force location" msgstr "Focer la localisation" -#: agenda_culturel/models.py:2594 +#: agenda_culturel/models.py:2607 msgid "force location even if another is detected." msgstr "Forcer la localisation même si une autre a été détectée." -#: agenda_culturel/models.py:2600 +#: agenda_culturel/models.py:2613 msgid "Organiser" msgstr "Organisation" -#: agenda_culturel/models.py:2601 +#: agenda_culturel/models.py:2614 msgid "Organiser of each imported event" msgstr "Organisme à l'origine de chaque événement importé" -#: agenda_culturel/models.py:2611 +#: agenda_culturel/models.py:2624 msgid "Category of each imported event" msgstr "Catégorie de chaque événement importé" -#: agenda_culturel/models.py:2619 +#: agenda_culturel/models.py:2632 msgid "Tags for each imported event" msgstr "Étiquettes de chaque événement importé" -#: agenda_culturel/models.py:2620 +#: agenda_culturel/models.py:2633 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:2649 +#: agenda_culturel/models.py:2662 msgid "Running" msgstr "En cours" -#: agenda_culturel/models.py:2650 +#: agenda_culturel/models.py:2663 msgid "Canceled" msgstr "Annulé" -#: agenda_culturel/models.py:2651 +#: agenda_culturel/models.py:2664 msgid "Success" msgstr "Succès" -#: agenda_culturel/models.py:2652 +#: agenda_culturel/models.py:2665 msgid "Failed" msgstr "Erreur" -#: agenda_culturel/models.py:2655 +#: agenda_culturel/models.py:2668 msgid "Batch importation" msgstr "Importation par lot" -#: agenda_culturel/models.py:2656 +#: agenda_culturel/models.py:2669 msgid "Batch importations" msgstr "Importations par lot" -#: agenda_culturel/models.py:2669 +#: agenda_culturel/models.py:2682 msgid "Reference to the recurrent import processing" msgstr "Référence du processus d'import récurrent" -#: agenda_culturel/models.py:2677 +#: agenda_culturel/models.py:2690 msgid "URL (if not recurrent import)" msgstr "URL (si pas d'import récurrent)" -#: agenda_culturel/models.py:2678 +#: agenda_culturel/models.py:2691 msgid "Source URL if no RecurrentImport is associated." msgstr "URL source si aucun import récurrent n'est associé" -#: agenda_culturel/models.py:2693 +#: agenda_culturel/models.py:2706 msgid "Error message" msgstr "Votre message" -#: agenda_culturel/models.py:2697 +#: agenda_culturel/models.py:2710 msgid "Number of collected events" msgstr "Nombre d'événements collectés" -#: agenda_culturel/models.py:2700 +#: agenda_culturel/models.py:2713 msgid "Number of imported events" msgstr "Nombre d'événements importés" -#: agenda_culturel/models.py:2703 +#: agenda_culturel/models.py:2716 msgid "Number of updated events" msgstr "Nombre d'événements mis à jour" -#: agenda_culturel/models.py:2706 +#: agenda_culturel/models.py:2719 msgid "Number of removed events" msgstr "Nombre d'événements supprimés" -#: agenda_culturel/models.py:2714 +#: agenda_culturel/models.py:2727 msgid "Weight" msgstr "Poids" -#: agenda_culturel/models.py:2715 +#: agenda_culturel/models.py:2728 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:2722 +#: agenda_culturel/models.py:2735 msgid "Category applied to the event" msgstr "Catégorie appliquée à l'événement" -#: agenda_culturel/models.py:2727 +#: agenda_culturel/models.py:2740 msgid "Contained in the title" msgstr "Contenu dans le titre" -#: agenda_culturel/models.py:2728 +#: agenda_culturel/models.py:2741 msgid "Text contained in the event title" msgstr "Texte contenu dans le titre de l'événement" -#: agenda_culturel/models.py:2734 +#: agenda_culturel/models.py:2747 msgid "Exact title extract" msgstr "Extrait exact du titre" -#: agenda_culturel/models.py:2736 +#: agenda_culturel/models.py:2749 msgid "" "If checked, the extract will be searched for in the title using the exact " "form (capitals, accents)." @@ -1317,19 +1321,19 @@ msgstr "" "Si coché, l'extrait sera recherché dans le titre en utilisant la forme " "exacte (majuscules, accents)" -#: agenda_culturel/models.py:2742 +#: agenda_culturel/models.py:2755 msgid "Contained in the description" msgstr "Contenu dans la description" -#: agenda_culturel/models.py:2743 +#: agenda_culturel/models.py:2756 msgid "Text contained in the description" msgstr "Texte contenu dans la description" -#: agenda_culturel/models.py:2749 +#: agenda_culturel/models.py:2762 msgid "Exact description extract" msgstr "Extrait exact de description" -#: agenda_culturel/models.py:2751 +#: agenda_culturel/models.py:2764 msgid "" "If checked, the extract will be searched for in the description using the " "exact form (capitals, accents)." @@ -1337,19 +1341,19 @@ msgstr "" "Si coché, l'extrait sera recherché dans la description en utilisant la forme " "exacte (majuscules, accents)" -#: agenda_culturel/models.py:2757 +#: agenda_culturel/models.py:2770 msgid "Contained in the location" msgstr "Contenu dans la localisation" -#: agenda_culturel/models.py:2758 +#: agenda_culturel/models.py:2771 msgid "Text contained in the event location" msgstr "Texte contenu dans la localisation de l'événement" -#: agenda_culturel/models.py:2764 +#: agenda_culturel/models.py:2777 msgid "Exact location extract" msgstr "Extrait exact de localisation" -#: agenda_culturel/models.py:2766 +#: agenda_culturel/models.py:2779 msgid "" "If checked, the extract will be searched for in the location using the exact " "form (capitals, accents)." @@ -1357,51 +1361,51 @@ msgstr "" "Si coché, l'extrait sera recherché dans la localisation en utilisant la " "forme exacte (majuscules, accents)" -#: agenda_culturel/models.py:2774 +#: agenda_culturel/models.py:2787 msgid "Location from place" msgstr "Localisation depuis le lieu" -#: agenda_culturel/models.py:2783 +#: agenda_culturel/models.py:2796 msgid "Categorisation rule" msgstr "Règle de catégorisation" -#: agenda_culturel/models.py:2784 +#: agenda_culturel/models.py:2797 msgid "Categorisation rules" msgstr "Règles de catégorisation" -#: agenda_culturel/models.py:2858 +#: agenda_culturel/models.py:2871 msgid "Period name" msgstr "Nom de la période" -#: agenda_culturel/models.py:2863 +#: agenda_culturel/models.py:2876 msgid "Special period" msgstr "Période remarquable" -#: agenda_culturel/models.py:2864 +#: agenda_culturel/models.py:2877 msgid "Special periods" msgstr "Périodes remarquables" -#: agenda_culturel/models.py:2870 +#: agenda_culturel/models.py:2883 msgid "public holidays" msgstr "Jour férié" -#: agenda_culturel/models.py:2871 +#: agenda_culturel/models.py:2884 msgid "school vacations" msgstr "Vacances scolaires" -#: agenda_culturel/models.py:2889 +#: agenda_culturel/models.py:2902 msgid "The end date must be after or equal to the start date." msgstr "La date de fin doit être après ou identique à la date de début." -#: agenda_culturel/models.py:2897 +#: agenda_culturel/models.py:2910 msgid " on " msgstr " du " -#: agenda_culturel/models.py:2900 +#: agenda_culturel/models.py:2913 msgid " from " msgstr " du " -#: agenda_culturel/models.py:2900 +#: agenda_culturel/models.py:2913 msgid " to " msgstr " au " @@ -1651,15 +1655,19 @@ msgstr "Le cache a été vidé avec succès." msgid "Your user profile has been successfully modified." msgstr "Votre profil utilisateur a été modifié avec succès." -#: agenda_culturel/views/import_batch_views.py:77 -msgid "The import has been run successfully." -msgstr "L'import a été lancé avec succès" +#: agenda_culturel/views/import_batch_views.py:83 +msgid "The import from json has been run successfully." +msgstr "L'import depuis json a été lancé avec succès" -#: agenda_culturel/views/import_batch_views.py:99 +#: agenda_culturel/views/import_batch_views.py:90 +msgid "The import from html ({} detected links) has been run successfully." +msgstr "L'import depuis html ({} liens détectés) a été lancé avec succès" + +#: agenda_culturel/views/import_batch_views.py:113 msgid "The import has been canceled." msgstr "L'import a été annulé" -#: agenda_culturel/views/import_batch_views.py:122 +#: agenda_culturel/views/import_batch_views.py:136 msgid "The orphan event update has been launched." msgstr "La mise à jour de l'événement orphelin a été lancée." diff --git a/src/agenda_culturel/templates/agenda_culturel/batchimportation_form.html b/src/agenda_culturel/templates/agenda_culturel/batchimportation_form.html index 074e5fb..76cec0d 100644 --- a/src/agenda_culturel/templates/agenda_culturel/batchimportation_form.html +++ b/src/agenda_culturel/templates/agenda_culturel/batchimportation_form.html @@ -4,12 +4,30 @@ {% block og_title %}Importation manuelle{% endblock %} {% endblock %} {% block content %} -

Importation manuelle

-
-
- {% csrf_token %} - {{ form.as_p }} - -
-
+
+
+
+

Importation manuelle

+
+

+ Le formulaire ci-dessous permet d'importer des événements par lot. Deux formats sont actuellement disponibles : +

+
    +
  • + Format json : format structuré tel qu'attendu par l'importateur. Voir la documentation sur le wiki du projet. +
  • +
  • + Format html : forme libre, où tous les liens qui sont considérés comme reconnus par l'outil d'import principal seront importés. + Cette fonctionnalité peut être utile quand on veut importer plus que les 8 événements détectés par défaut lors d'un import Facebook. Pour cela, se rendre sur la page de la liste + d'événements, enregistrer le html de la page (clic droit, enregistrer sous), puis copier le contenu de ce fichier html ci-dessous. +
  • +
+
+ {% csrf_token %} + {{ form.as_p }} + +
+
+ {% include "agenda_culturel/side-nav.html" with current="manual-import" %} +
{% endblock %} diff --git a/src/agenda_culturel/templates/agenda_culturel/side-nav.html b/src/agenda_culturel/templates/agenda_culturel/side-nav.html index 79c93b1..15625b8 100644 --- a/src/agenda_culturel/templates/agenda_culturel/side-nav.html +++ b/src/agenda_culturel/templates/agenda_culturel/side-nav.html @@ -70,6 +70,10 @@ Historiques des importations +
  • + Import manuel +
  • {% endif %} {% if perms.agenda_culturel.view_recurrentimport %}
  • diff --git a/src/agenda_culturel/views/import_batch_views.py b/src/agenda_culturel/views/import_batch_views.py index 6b4b5c0..9609fe1 100644 --- a/src/agenda_culturel/views/import_batch_views.py +++ b/src/agenda_culturel/views/import_batch_views.py @@ -10,9 +10,12 @@ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from ..celery import app as celery_app, update_orphan_pure_import_events -from ..celery import import_events_from_json +from ..celery import import_events_from_json, import_events_from_urls from ..forms import BatchImportationForm from ..models import Event, BatchImportation, RecurrentImport +from ..import_tasks.extractor import Extractor +from bs4 import BeautifulSoup +import json @login_required(login_url="/accounts/login/") @@ -72,9 +75,37 @@ def add_import(request): form = BatchImportationForm(request.POST) if form.is_valid(): - import_events_from_json.delay(form.data["json"]) + try: + # try to load data as a json file + json.loads(form.data["data"]) + # if data is a json, load it + import_events_from_json.delay(form.data["data"]) + messages.success( + request, _("The import from json has been run successfully.") + ) + except ValueError: + # otherwise, consider it as html, extract all urls, and import them + soup = BeautifulSoup(form.data["data"], "html.parser") + urls = list( + set( + [ + a["href"] + for a in soup.find_all("a", href=True) + if Extractor.is_known_url_default_extractors(a["href"]) + ] + ) + ) + # then import events from url + import_events_from_urls.delay( + urls, user_id=request.user.pk if request.user else None + ) + messages.success( + request, + _( + "The import from html ({} detected links) has been run successfully." + ).format(len(urls)), + ) - messages.success(request, _("The import has been run successfully.")) return HttpResponseRedirect(reverse_lazy("imports")) return render(request, "agenda_culturel/batchimportation_form.html", {"form": form})