Ajout d'un mécanisme d'import par batches (pour l'instant pas connecté au celery)
This commit is contained in:
		@@ -8,7 +8,7 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: agenda_culturel\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2023-12-16 20:13+0000\n"
 | 
			
		||||
"POT-Creation-Date: 2023-12-23 08:38+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2023-10-29 14:16+0000\n"
 | 
			
		||||
"Last-Translator: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
 | 
			
		||||
"Language-Team: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
 | 
			
		||||
@@ -17,262 +17,290 @@ msgstr ""
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/forms.py:36
 | 
			
		||||
msgid "The start date cannot be earler than today."
 | 
			
		||||
msgstr "La date de début ne peut pas être avant aujourd'hui."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/forms.py:46
 | 
			
		||||
#: agenda_culturel/forms.py:37
 | 
			
		||||
msgid "The end date must be after the start date."
 | 
			
		||||
msgstr "La date de fin doit être après la date de début."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/forms.py:48
 | 
			
		||||
msgid "The end date cannot be earler than today."
 | 
			
		||||
msgstr "La date de fin ne peut pas être avant aujourd'hui."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/forms.py:63
 | 
			
		||||
#: agenda_culturel/forms.py:52
 | 
			
		||||
msgid "The end time cannot be earlier than the start time."
 | 
			
		||||
msgstr "L'heure de fin ne peut pas être avant l'heure de début."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:19 agenda_culturel/models.py:48
 | 
			
		||||
#: agenda_culturel/models.py:183
 | 
			
		||||
#: agenda_culturel/models.py:23 agenda_culturel/models.py:52
 | 
			
		||||
#: agenda_culturel/models.py:211
 | 
			
		||||
msgid "Name"
 | 
			
		||||
msgstr "Nom"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:19 agenda_culturel/models.py:48
 | 
			
		||||
#: agenda_culturel/models.py:23 agenda_culturel/models.py:52
 | 
			
		||||
msgid "Category name"
 | 
			
		||||
msgstr "Nom de la catégorie"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:20
 | 
			
		||||
#: agenda_culturel/models.py:24
 | 
			
		||||
msgid "Content"
 | 
			
		||||
msgstr "Contenu"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:20
 | 
			
		||||
#: agenda_culturel/models.py:24
 | 
			
		||||
msgid "Text as shown to the visitors"
 | 
			
		||||
msgstr "Text tel que présenté aux visiteureuses"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:21
 | 
			
		||||
#: agenda_culturel/models.py:25
 | 
			
		||||
msgid "URL path"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:21
 | 
			
		||||
#: agenda_culturel/models.py:25
 | 
			
		||||
msgid "URL path where the content is included."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:49
 | 
			
		||||
#: agenda_culturel/models.py:53
 | 
			
		||||
msgid "Alternative Name"
 | 
			
		||||
msgstr "Nom alternatif"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:49
 | 
			
		||||
#: agenda_culturel/models.py:53
 | 
			
		||||
msgid "Alternative name used with a time period"
 | 
			
		||||
msgstr "Nom alternatif utilisé avec une période de temps"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:50
 | 
			
		||||
#: agenda_culturel/models.py:54
 | 
			
		||||
msgid "Short name"
 | 
			
		||||
msgstr "Nom court"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:50
 | 
			
		||||
#: agenda_culturel/models.py:54
 | 
			
		||||
msgid "Short name of the category"
 | 
			
		||||
msgstr "Nom court de la catégorie"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:51
 | 
			
		||||
#: agenda_culturel/models.py:55
 | 
			
		||||
msgid "Color"
 | 
			
		||||
msgstr "Couleur"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:51
 | 
			
		||||
#: agenda_culturel/models.py:55
 | 
			
		||||
msgid "Color used as background for the category"
 | 
			
		||||
msgstr "Couleur utilisée comme fond de la catégorie"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:88 agenda_culturel/models.py:105
 | 
			
		||||
#: agenda_culturel/models.py:92 agenda_culturel/models.py:109
 | 
			
		||||
msgid "Category"
 | 
			
		||||
msgstr "Catégorie"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:89
 | 
			
		||||
#: agenda_culturel/models.py:93
 | 
			
		||||
msgid "Categories"
 | 
			
		||||
msgstr "Catégories"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:94
 | 
			
		||||
#: agenda_culturel/models.py:98
 | 
			
		||||
msgid "Published"
 | 
			
		||||
msgstr "Publié"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:95
 | 
			
		||||
#: agenda_culturel/models.py:99
 | 
			
		||||
msgid "Draft"
 | 
			
		||||
msgstr "Brouillon"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:96
 | 
			
		||||
#: agenda_culturel/models.py:100
 | 
			
		||||
msgid "Trash"
 | 
			
		||||
msgstr "Corbeille"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:101
 | 
			
		||||
#: agenda_culturel/models.py:105
 | 
			
		||||
msgid "Title"
 | 
			
		||||
msgstr "Titre"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:101
 | 
			
		||||
#: agenda_culturel/models.py:105
 | 
			
		||||
msgid "Short title"
 | 
			
		||||
msgstr "Titre court"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:103
 | 
			
		||||
#: agenda_culturel/models.py:107 agenda_culturel/models.py:238
 | 
			
		||||
msgid "Status"
 | 
			
		||||
msgstr "Status"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:105
 | 
			
		||||
#: agenda_culturel/models.py:109
 | 
			
		||||
msgid "Category of the event"
 | 
			
		||||
msgstr "Catégorie de l'événement"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:107
 | 
			
		||||
#: agenda_culturel/models.py:111
 | 
			
		||||
msgid "Day of the event"
 | 
			
		||||
msgstr "Date de l'événement"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:108
 | 
			
		||||
#: agenda_culturel/models.py:112
 | 
			
		||||
msgid "Starting time"
 | 
			
		||||
msgstr "Heure de début"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:110
 | 
			
		||||
#: agenda_culturel/models.py:114
 | 
			
		||||
msgid "End day of the event"
 | 
			
		||||
msgstr "Fin de l'événement"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:110
 | 
			
		||||
#: agenda_culturel/models.py:114
 | 
			
		||||
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:111
 | 
			
		||||
#: agenda_culturel/models.py:115
 | 
			
		||||
msgid "Final time"
 | 
			
		||||
msgstr "Heure de fin"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:113
 | 
			
		||||
#: agenda_culturel/models.py:117
 | 
			
		||||
msgid "Location"
 | 
			
		||||
msgstr "Localisation"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:113
 | 
			
		||||
#: agenda_culturel/models.py:117
 | 
			
		||||
msgid "Address of the event"
 | 
			
		||||
msgstr "Adresse de l'événement"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:115
 | 
			
		||||
#: agenda_culturel/models.py:119
 | 
			
		||||
msgid "Description"
 | 
			
		||||
msgstr "Description"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:115
 | 
			
		||||
#: agenda_culturel/models.py:119
 | 
			
		||||
msgid "General description of the event"
 | 
			
		||||
msgstr "Description générale de l'événement"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:117
 | 
			
		||||
#: agenda_culturel/models.py:121
 | 
			
		||||
msgid "Illustration (local image)"
 | 
			
		||||
msgstr "Illustration (image locale)"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:117
 | 
			
		||||
#: agenda_culturel/models.py:121
 | 
			
		||||
msgid "Illustration image stored in the agenda server"
 | 
			
		||||
msgstr "Image d'illustration stockée sur le serveur de l'agenda"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:119
 | 
			
		||||
#: agenda_culturel/models.py:123
 | 
			
		||||
msgid "Illustration"
 | 
			
		||||
msgstr "Illustration"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:119
 | 
			
		||||
#: agenda_culturel/models.py:123
 | 
			
		||||
msgid "URL of the illustration image"
 | 
			
		||||
msgstr "URL de l'image illustrative"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:120
 | 
			
		||||
#: agenda_culturel/models.py:124
 | 
			
		||||
msgid "Illustration description"
 | 
			
		||||
msgstr "Description de l'illustration"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:120
 | 
			
		||||
#: agenda_culturel/models.py:124
 | 
			
		||||
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:122
 | 
			
		||||
#: agenda_culturel/models.py:126
 | 
			
		||||
msgid "URLs"
 | 
			
		||||
msgstr "URLs"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:122
 | 
			
		||||
#: agenda_culturel/models.py:126
 | 
			
		||||
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:124
 | 
			
		||||
#: agenda_culturel/models.py:128
 | 
			
		||||
msgid "Tags"
 | 
			
		||||
msgstr "Étiquettes"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:124
 | 
			
		||||
#: agenda_culturel/models.py:128
 | 
			
		||||
msgid "A list of tags that describe the event."
 | 
			
		||||
msgstr "Une liste d'étiquettes décrivant l'événement"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:149
 | 
			
		||||
#: agenda_culturel/models.py:158
 | 
			
		||||
msgid "Event"
 | 
			
		||||
msgstr "Événement"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:150
 | 
			
		||||
#: agenda_culturel/models.py:159
 | 
			
		||||
msgid "Events"
 | 
			
		||||
msgstr "Événements"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:182
 | 
			
		||||
#: agenda_culturel/models.py:210
 | 
			
		||||
msgid "Subject"
 | 
			
		||||
msgstr "Sujet"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:182
 | 
			
		||||
#: agenda_culturel/models.py:210
 | 
			
		||||
msgid "The subject of your message"
 | 
			
		||||
msgstr "Sujet de votre message"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:183
 | 
			
		||||
#: agenda_culturel/models.py:211
 | 
			
		||||
msgid "Your name"
 | 
			
		||||
msgstr "Votre nom"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:184
 | 
			
		||||
#: agenda_culturel/models.py:212
 | 
			
		||||
msgid "Email address"
 | 
			
		||||
msgstr "Adresse email"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:184
 | 
			
		||||
#: agenda_culturel/models.py:212
 | 
			
		||||
msgid "Your email address"
 | 
			
		||||
msgstr "Votre adresse email"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:185
 | 
			
		||||
#: agenda_culturel/models.py:213
 | 
			
		||||
msgid "Message"
 | 
			
		||||
msgstr "Message"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:185
 | 
			
		||||
#: agenda_culturel/models.py:213
 | 
			
		||||
msgid "Your message"
 | 
			
		||||
msgstr "Votre message"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:189 agenda_culturel/views.py:334
 | 
			
		||||
#: agenda_culturel/models.py:217 agenda_culturel/views.py:341
 | 
			
		||||
msgid "Closed"
 | 
			
		||||
msgstr "Fermé"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:189
 | 
			
		||||
#: agenda_culturel/models.py:217
 | 
			
		||||
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:190
 | 
			
		||||
#: agenda_culturel/models.py:218
 | 
			
		||||
msgid "Comments"
 | 
			
		||||
msgstr "Commentaires"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:190
 | 
			
		||||
#: agenda_culturel/models.py:218
 | 
			
		||||
msgid "Comments on the message from the moderation team"
 | 
			
		||||
msgstr "Commentaires sur ce message par l'équipe de modération"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/settings/base.py:128
 | 
			
		||||
#: agenda_culturel/models.py:227
 | 
			
		||||
msgid "Running"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:228
 | 
			
		||||
msgid "Canceled"
 | 
			
		||||
msgstr "Annulé"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:229
 | 
			
		||||
msgid "Success"
 | 
			
		||||
msgstr "Succès"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:230
 | 
			
		||||
msgid "Failed"
 | 
			
		||||
msgstr "Erreur"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:235
 | 
			
		||||
msgid "Source"
 | 
			
		||||
msgstr "Source"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:235
 | 
			
		||||
msgid "URL of the source document"
 | 
			
		||||
msgstr "URL du document source"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:236
 | 
			
		||||
msgid "Browsable url"
 | 
			
		||||
msgstr "URL navigable"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/models.py:236
 | 
			
		||||
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/settings/base.py:134
 | 
			
		||||
msgid "English"
 | 
			
		||||
msgstr "anglais"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/settings/base.py:129
 | 
			
		||||
#: agenda_culturel/settings/base.py:135
 | 
			
		||||
msgid "French"
 | 
			
		||||
msgstr "français"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:182
 | 
			
		||||
#: agenda_culturel/views.py:188
 | 
			
		||||
msgid "The static content has been successfully updated."
 | 
			
		||||
msgstr "Le contenu statique a été modifié avec succès."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:188
 | 
			
		||||
#: agenda_culturel/views.py:194
 | 
			
		||||
msgid "The event has been successfully modified."
 | 
			
		||||
msgstr "L'événement a été modifié avec succès."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:199
 | 
			
		||||
#: agenda_culturel/views.py:205
 | 
			
		||||
msgid "The event has been successfully deleted."
 | 
			
		||||
msgstr "L'événement a été supprimé avec succès"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:237
 | 
			
		||||
#: agenda_culturel/views.py:222
 | 
			
		||||
msgid "The status has been successfully modified."
 | 
			
		||||
msgstr "Le status a été modifié avec succès."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:244
 | 
			
		||||
msgid "The event is saved."
 | 
			
		||||
msgstr "L'événement est enregistré."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:240
 | 
			
		||||
#: agenda_culturel/views.py:247
 | 
			
		||||
msgid ""
 | 
			
		||||
"The event has been submitted and will be published as soon as it has been "
 | 
			
		||||
"validated by the moderation team."
 | 
			
		||||
@@ -280,7 +308,7 @@ msgstr ""
 | 
			
		||||
"L'événement a été soumis et sera publié dès qu'il aura été validé par "
 | 
			
		||||
"l'équipe de modération."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:270
 | 
			
		||||
#: agenda_culturel/views.py:277
 | 
			
		||||
msgid ""
 | 
			
		||||
"The event has been successfully extracted, and you can now submit it after "
 | 
			
		||||
"modifying it if necessary."
 | 
			
		||||
@@ -288,7 +316,7 @@ msgstr ""
 | 
			
		||||
"L'événement a été extrait avec succès, vous pouvez maintenant le soumettre "
 | 
			
		||||
"après l'avoir modifié au besoin."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:274
 | 
			
		||||
#: agenda_culturel/views.py:281
 | 
			
		||||
msgid ""
 | 
			
		||||
"Unable to extract an event from the proposed URL. Please use the form below "
 | 
			
		||||
"to submit the event."
 | 
			
		||||
@@ -296,12 +324,12 @@ msgstr ""
 | 
			
		||||
"Impossible d'extraire un événement depuis l'URL proposée. Veuillez utiliser "
 | 
			
		||||
"le formulaire ci-dessous pour soumettre l'événement."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:283
 | 
			
		||||
#: agenda_culturel/views.py:290
 | 
			
		||||
msgid "This URL has already been submitted, and you can find the event below."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Cette URL a déjà été soumise, et vous trouverez l'événement ci-dessous."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:287
 | 
			
		||||
#: agenda_culturel/views.py:294
 | 
			
		||||
msgid ""
 | 
			
		||||
"This URL has already been submitted, but has not been selected for "
 | 
			
		||||
"publication by the moderation team."
 | 
			
		||||
@@ -309,26 +337,34 @@ msgstr ""
 | 
			
		||||
"Cette URL a déjà été soumise, mais n'a pas été retenue par l'équipe de "
 | 
			
		||||
"modération pour la publication."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:289
 | 
			
		||||
#: agenda_culturel/views.py:296
 | 
			
		||||
msgid "This URL has already been submitted and is awaiting moderation."
 | 
			
		||||
msgstr "Cette URL a déjà été soumise, et est en attente de modération"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:311
 | 
			
		||||
#: agenda_culturel/views.py:318
 | 
			
		||||
msgid "Your message has been sent successfully."
 | 
			
		||||
msgstr "L'événement a été supprimé avec succès"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:319
 | 
			
		||||
#: agenda_culturel/views.py:326
 | 
			
		||||
msgid "The contact message properties has been successfully modified."
 | 
			
		||||
msgstr "Les propriétés du message de contact ont été modifié avec succès."
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:334
 | 
			
		||||
#: agenda_culturel/views.py:341
 | 
			
		||||
msgid "Open"
 | 
			
		||||
msgstr "Ouvert"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:374
 | 
			
		||||
#: agenda_culturel/views.py:381
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Rechercher"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:491
 | 
			
		||||
msgid "The import has been run successfully."
 | 
			
		||||
msgstr "L'import a été lancé avec succès"
 | 
			
		||||
 | 
			
		||||
#: agenda_culturel/views.py:507
 | 
			
		||||
msgid "The import has been canceled."
 | 
			
		||||
msgstr "L'import a été annulé"
 | 
			
		||||
 | 
			
		||||
msgid "Add another"
 | 
			
		||||
msgstr "Ajouter un autre"
 | 
			
		||||
 | 
			
		||||
@@ -336,4 +372,4 @@ msgid "Browse..."
 | 
			
		||||
msgstr "Naviguer..."
 | 
			
		||||
 | 
			
		||||
msgid "No file selected."
 | 
			
		||||
msgstr "Pas de fichier sélectionné."
 | 
			
		||||
msgstr "Pas de fichier sélectionné."
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								src/agenda_culturel/migrations/0011_batchimportation.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/agenda_culturel/migrations/0011_batchimportation.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
# Generated by Django 4.2.7 on 2023-12-23 08:01
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('agenda_culturel', '0010_alter_contactmessage_comments'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='BatchImportation',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('created_date', models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                ('source', models.URLField(blank=True, help_text='URL of the source document', max_length=1024, null=True, verbose_name='Source')),
 | 
			
		||||
                ('browsable_url', models.URLField(blank=True, help_text='URL of the corresponding document that will be shown to visitors.', max_length=1024, null=True, verbose_name='Browsable url')),
 | 
			
		||||
                ('running', models.BooleanField(default=True, help_text='This batch importation is still running', verbose_name='Running')),
 | 
			
		||||
                ('success', models.BooleanField(default=False, help_text='This batch importation successfully finished', verbose_name='Success')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
# Generated by Django 4.2.7 on 2023-12-23 08:21
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('agenda_culturel', '0011_batchimportation'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(
 | 
			
		||||
            model_name='batchimportation',
 | 
			
		||||
            name='running',
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.RemoveField(
 | 
			
		||||
            model_name='batchimportation',
 | 
			
		||||
            name='success',
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='batchimportation',
 | 
			
		||||
            name='status',
 | 
			
		||||
            field=models.CharField(choices=[('running', 'Running'), ('canceled', 'Canceled'), ('success', 'Success'), ('failed', 'Failed')], default='running', max_length=20, verbose_name='Status'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -219,3 +219,20 @@ class ContactMessage(models.Model):
 | 
			
		||||
 | 
			
		||||
    def nb_open_contactmessages():
 | 
			
		||||
        return ContactMessage.objects.filter(closed=False).count()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BatchImportation(models.Model):
 | 
			
		||||
 | 
			
		||||
    class STATUS(models.TextChoices): 
 | 
			
		||||
        RUNNING = "running", _("Running")
 | 
			
		||||
        CANCELED = "canceled", _("Canceled")
 | 
			
		||||
        SUCCESS = "success", _("Success")
 | 
			
		||||
        FAILED = "failed", _("Failed")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    created_date = models.DateTimeField(auto_now_add=True)
 | 
			
		||||
 | 
			
		||||
    source = models.URLField(verbose_name=_('Source'), help_text=_("URL of the source document"), max_length=1024, blank=True, null=True)
 | 
			
		||||
    browsable_url = models.URLField(verbose_name=_('Browsable url'), help_text=_("URL of the corresponding document that will be shown to visitors."), max_length=1024, blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
    status = models.CharField(_("Status"), max_length=20, choices=STATUS.choices, default=STATUS.RUNNING)
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
{% extends "agenda_culturel/page.html" %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
 | 
			
		||||
{% block title %}Importation par lot{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 | 
			
		||||
<h1>Importation par lot</h1>
 | 
			
		||||
 | 
			
		||||
<article>
 | 
			
		||||
    <form method="post">{% csrf_token %}
 | 
			
		||||
        {{ form.as_p }}
 | 
			
		||||
        <p>
 | 
			
		||||
            <label for="id_json">JSON (facultatif) :</label>
 | 
			
		||||
            <textarea id="id_json" name="json" rows="10"></textarea>
 | 
			
		||||
            <span class="helptext">JSON au format attendu pour l'import. Si le JSON est fourni ici, on ne lancera pas une récupération depuis l'URL donnée en paramètre.</span>
 | 
			
		||||
          </p>
 | 
			
		||||
        
 | 
			
		||||
        <input type="submit" value="Envoyer">
 | 
			
		||||
    </form>
 | 
			
		||||
</article>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -0,0 +1,25 @@
 | 
			
		||||
{% extends "agenda_culturel/page.html" %}
 | 
			
		||||
 | 
			
		||||
{% block title %}Supprimer {{ object.title }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 | 
			
		||||
<article>
 | 
			
		||||
    <header>
 | 
			
		||||
        <h1>Annulation de l'import {{ object.id }} ({{ object.created_date }})</h1>
 | 
			
		||||
    </header>
 | 
			
		||||
    <form method="post">{% csrf_token %}
 | 
			
		||||
        <p>Êtes-vous sûr·e de vouloir annuler l'importation « {{ object.id }} » ?</p>
 | 
			
		||||
        {{ form }}
 | 
			
		||||
        
 | 
			
		||||
        <footer>
 | 
			
		||||
            <div class="grid">
 | 
			
		||||
                <a href="{{ cancel_url }}" role="button" class="secondary">Annuler</a>
 | 
			
		||||
                <input type="submit" value="Confirmer">
 | 
			
		||||
            </div>
 | 
			
		||||
        </footer>
 | 
			
		||||
    </form>
 | 
			
		||||
</article>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/agenda_culturel/templates/agenda_culturel/imports.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/agenda_culturel/templates/agenda_culturel/imports.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
{% extends "agenda_culturel/page.html" %}
 | 
			
		||||
 | 
			
		||||
{% block title %}Importations par lot{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% load utils_extra %}
 | 
			
		||||
{% load cat_extra %}
 | 
			
		||||
{% block entete_header %}
 | 
			
		||||
    {% css_categories %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="grid two-columns">
 | 
			
		||||
<article>
 | 
			
		||||
    <header>
 | 
			
		||||
        <a class="slide-buttons" href="{% url 'add_import'%}" role="button">Nouvel import</a>
 | 
			
		||||
        <h1>Importations par lot</h1>
 | 
			
		||||
    </header>
 | 
			
		||||
 | 
			
		||||
    <table role="grid">
 | 
			
		||||
        <thead>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <th>Identifiant</th>
 | 
			
		||||
                <th>Date</th>
 | 
			
		||||
                <th>Status</th>
 | 
			
		||||
                <th>Action</th>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </thead>
 | 
			
		||||
        <tbody>
 | 
			
		||||
    {% for obj in paginator_filter %}
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>{{ obj.id }}</a></td>
 | 
			
		||||
            <td>{{ obj.created_date }}</td>
 | 
			
		||||
            <td>{{ obj.status }}</td>
 | 
			
		||||
            <td>{% if obj.status == "running" %}<a href="{% url 'cancel_import' obj.id %}">Annuler</a>{% endif %}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
        </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
<footer>
 | 
			
		||||
    <span>
 | 
			
		||||
        {% if paginator_filter.has_previous %}
 | 
			
		||||
            <a href="?page=1" role="button">« premier</a>
 | 
			
		||||
            <a href="?page={{ paginator_filter.previous_page_number }}" role="button">précédent</a>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
 | 
			
		||||
        <span>
 | 
			
		||||
            Page {{ paginator_filter.number }} sur {{ paginator_filter.paginator.num_pages }}
 | 
			
		||||
        </span>
 | 
			
		||||
 | 
			
		||||
        {% if paginator_filter.has_next %}
 | 
			
		||||
            <a href="?page={{ paginator_filter.next_page_number }}" role="button">suivant</a>
 | 
			
		||||
            <a href="?page={{ paginator_filter.paginator.num_pages }}" role="button">dernier »</a>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
    </span>
 | 
			
		||||
</footer>
 | 
			
		||||
</article>
 | 
			
		||||
 | 
			
		||||
{% include "agenda_culturel/side-nav.html" with current="imports" %}
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
                <li><a {% if current == "moderation" %}class="selected" {% endif %}href="{% url 'moderation' %}">Derniers événements soumis</a>{% show_badges_events %}</li>
 | 
			
		||||
                <li><a {% if current == "tags" %}class="selected" {% endif %}href="{% url 'view_all_tags' %}">Toutes les étiquettes</a></li>
 | 
			
		||||
                <li><a {% if current == "contactmessages" %}class="selected" {% endif %}href="{% url 'contactmessages' %}">Messages de contact</a>{% show_badge_contactmessages %}</li>
 | 
			
		||||
                <li><a {% if current == "imports" %}class="selected" {% endif %}href="{% url 'imports' %}">Importations par lot</a>{% show_badge_contactmessages %}</li>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </nav>
 | 
			
		||||
    </article>
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,9 @@ urlpatterns = [
 | 
			
		||||
    path('contact', ContactMessageCreateView.as_view(), name='contact'),
 | 
			
		||||
    path('contactmessages', contactmessages, name='contactmessages'),
 | 
			
		||||
    path('contactmessage/<int:pk>', ContactMessageUpdateView.as_view(), name='contactmessage'),
 | 
			
		||||
    path("imports/", imports, name="imports"),
 | 
			
		||||
    path("imports/add", BatchImportationCreateView.as_view(), name="add_import"),
 | 
			
		||||
    path("imports/<int:pk>/cancel", cancel_import, name="cancel_import"),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
if settings.DEBUG:
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import urllib
 | 
			
		||||
 | 
			
		||||
from .forms import EventSubmissionForm, EventForm
 | 
			
		||||
 | 
			
		||||
from .models import Event, Category, StaticContent, ContactMessage
 | 
			
		||||
from .models import Event, Category, StaticContent, ContactMessage, BatchImportation
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
from enum import StrEnum
 | 
			
		||||
from datetime import date, timedelta
 | 
			
		||||
@@ -219,6 +219,7 @@ def change_status_event(request, pk, status):
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        event.status = Event.STATUS(status)
 | 
			
		||||
        event.save(update_fields=["status"])
 | 
			
		||||
        messages.success(request, _("The status has been successfully modified."))
 | 
			
		||||
 | 
			
		||||
        if request.user.is_authenticated:
 | 
			
		||||
            return HttpResponseRedirect(event.get_absolute_url())
 | 
			
		||||
@@ -460,3 +461,54 @@ def event_search(request, full=False):
 | 
			
		||||
 | 
			
		||||
def event_search_full(request):
 | 
			
		||||
    return event_search(request, True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#########################
 | 
			
		||||
## batch importations
 | 
			
		||||
#########################
 | 
			
		||||
 | 
			
		||||
@login_required(login_url="/accounts/login/")
 | 
			
		||||
def imports(request):
 | 
			
		||||
    paginator = Paginator(BatchImportation.objects.all().order_by("-created_date"), 10)
 | 
			
		||||
    page = request.GET.get('page')
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        response = paginator.page(page)
 | 
			
		||||
    except PageNotAnInteger:
 | 
			
		||||
        response = paginator.page(1)
 | 
			
		||||
    except EmptyPage:
 | 
			
		||||
        response = paginator.page(paginator.num_pages)
 | 
			
		||||
 | 
			
		||||
    return render(request, 'agenda_culturel/imports.html', {'paginator_filter': response} )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BatchImportationCreateView(SuccessMessageMixin, LoginRequiredMixin, CreateView):
 | 
			
		||||
    model = BatchImportation
 | 
			
		||||
    fields = ['source', 'browsable_url']
 | 
			
		||||
 | 
			
		||||
    success_url = reverse_lazy('imports')
 | 
			
		||||
    success_message = _('The import has been run successfully.')
 | 
			
		||||
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        # TODO run a celery script
 | 
			
		||||
 | 
			
		||||
        return super().form_valid(form)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@login_required(login_url="/accounts/login/")
 | 
			
		||||
def cancel_import(request, pk):
 | 
			
		||||
    import_process = get_object_or_404(BatchImportation, pk=pk)
 | 
			
		||||
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        # TODO cancel the celery import
 | 
			
		||||
        
 | 
			
		||||
        import_process.status = BatchImportation.STATUS.CANCELED
 | 
			
		||||
        import_process.save(update_fields=["status"])
 | 
			
		||||
 | 
			
		||||
        messages.success(request, _("The import has been canceled."))
 | 
			
		||||
        return HttpResponseRedirect(reverse_lazy("imports"))
 | 
			
		||||
    else:
 | 
			
		||||
        cancel_url = reverse_lazy("imports")
 | 
			
		||||
        return render(request, 'agenda_culturel/cancel_import_confirm.html', {"object": import_process, "cancel_url": cancel_url})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user