Ajout de la gestion des lieux
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
from django.forms import ModelForm, ValidationError, TextInput, Form, URLField, MultipleHiddenInput, Textarea, CharField, ChoiceField, RadioSelect, MultipleChoiceField, BooleanField, HiddenInput
|
from django.forms import ModelForm, ValidationError, TextInput, Form, URLField, MultipleHiddenInput, Textarea, CharField, ChoiceField, RadioSelect, MultipleChoiceField, BooleanField, HiddenInput, ModelChoiceField
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from django_better_admin_arrayfield.forms.widgets import DynamicArrayWidget
|
from django_better_admin_arrayfield.forms.widgets import DynamicArrayWidget
|
||||||
|
|
||||||
from .models import Event, BatchImportation, RecurrentImport, CategorisationRule, ModerationAnswer, ModerationQuestion
|
from .models import Event, BatchImportation, RecurrentImport, CategorisationRule, ModerationAnswer, ModerationQuestion, Place
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from string import ascii_uppercase as auc
|
from string import ascii_uppercase as auc
|
||||||
from .templatetags.utils_extra import int_to_abc
|
from .templatetags.utils_extra import int_to_abc
|
||||||
@@ -283,8 +283,6 @@ class CategorisationForm(Form):
|
|||||||
if '_' not in f:
|
if '_' not in f:
|
||||||
if f + '_cat' in args[0]:
|
if f + '_cat' in args[0]:
|
||||||
events.append((Event.objects.get(pk=int(f)), args[0][f + '_cat']))
|
events.append((Event.objects.get(pk=int(f)), args[0][f + '_cat']))
|
||||||
|
|
||||||
# TODO
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
for e, c in events:
|
for e, c in events:
|
||||||
@@ -294,3 +292,48 @@ class CategorisationForm(Form):
|
|||||||
def get_validated(self):
|
def get_validated(self):
|
||||||
return [(e, self.cleaned_data.get(e + '_cat')) for e in self.fields if '_' not in e and self.cleaned_data.get(e)]
|
return [(e, self.cleaned_data.get(e + '_cat')) for e in self.fields if '_' not in e and self.cleaned_data.get(e)]
|
||||||
|
|
||||||
|
|
||||||
|
class EventAddPlaceForm(Form):
|
||||||
|
|
||||||
|
place = ModelChoiceField(label=_("Place"), queryset=Place.objects.all(), empty_label=_("Create a missing place"), required=False)
|
||||||
|
add_alias = BooleanField(initial=True, required=False)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.instance = kwargs.pop('instance', False)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
if self.instance.location:
|
||||||
|
self.fields["add_alias"].label = _("Add \"{}\" to the aliases of the place").format(self.instance.location)
|
||||||
|
else:
|
||||||
|
self.fields.pop("add_alias")
|
||||||
|
|
||||||
|
def modified_event(self):
|
||||||
|
return self.cleaned_data.get('place')
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
if self.cleaned_data.get("place"):
|
||||||
|
place = self.cleaned_data.get("place")
|
||||||
|
self.instance.exact_location = place
|
||||||
|
self.instance.save()
|
||||||
|
if self.cleaned_data.get('add_alias'):
|
||||||
|
place.aliases.append(self.instance.location)
|
||||||
|
place.save()
|
||||||
|
|
||||||
|
return self.instance
|
||||||
|
|
||||||
|
class PlaceForm(ModelForm):
|
||||||
|
apply_to_all = BooleanField(initial=True, label=_('On saving, use aliases to detect all matching events with missing place'), required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Place
|
||||||
|
fields = '__all__'
|
||||||
|
widgets = {
|
||||||
|
'location': TextInput()
|
||||||
|
}
|
||||||
|
|
||||||
|
def as_grid(self):
|
||||||
|
return mark_safe('<div class="grid"><div>' + super().as_p() + '</div><div><div class="map-widget">' +
|
||||||
|
'<div id="map_location" style="width: 100%; aspect-ratio: 16/9"></div></div></div></div>')
|
||||||
|
|
||||||
|
|
||||||
|
def apply(self):
|
||||||
|
return self.cleaned_data.get("apply_to_all")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: agenda_culturel\n"
|
"Project-Id-Version: agenda_culturel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-04-26 14:59+0000\n"
|
"POT-Creation-Date: 2024-04-27 16:25+0000\n"
|
||||||
"PO-Revision-Date: 2023-10-29 14:16+0000\n"
|
"PO-Revision-Date: 2023-10-29 14:16+0000\n"
|
||||||
"Last-Translator: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
|
"Last-Translator: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
|
||||||
"Language-Team: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
|
"Language-Team: Jean-Marie Favreau <jeanmarie.favreau@free.fr>\n"
|
||||||
@@ -29,19 +29,35 @@ msgstr "L'heure de fin ne peut pas être avant l'heure de début."
|
|||||||
msgid "JSON in the format expected for the import."
|
msgid "JSON in the format expected for the import."
|
||||||
msgstr "JSON dans le format attendu pour l'import"
|
msgstr "JSON dans le format attendu pour l'import"
|
||||||
|
|
||||||
#: agenda_culturel/forms.py:291
|
#: agenda_culturel/forms.py:289
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Category of the event"
|
|
||||||
msgid "Apply category {} to the event {}"
|
msgid "Apply category {} to the event {}"
|
||||||
msgstr "Catégorie de l'événement"
|
msgstr "Appliquer la catégorie {} à l'événement {}"
|
||||||
|
|
||||||
|
#: agenda_culturel/forms.py:298 agenda_culturel/models.py:170
|
||||||
|
msgid "Place"
|
||||||
|
msgstr "Lieu"
|
||||||
|
|
||||||
|
#: agenda_culturel/forms.py:298
|
||||||
|
msgid "Create a missing place"
|
||||||
|
msgstr "Créer un lieu manquant"
|
||||||
|
|
||||||
|
#: agenda_culturel/forms.py:305
|
||||||
|
msgid "Add \"{}\" to the aliases of the place"
|
||||||
|
msgstr "Ajouter « {} » aux alias du lieu"
|
||||||
|
|
||||||
|
#: agenda_culturel/forms.py:324
|
||||||
|
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/import_tasks/generic_extractors.py:151
|
#: agenda_culturel/import_tasks/generic_extractors.py:151
|
||||||
msgid "Cannot extract event from url {}"
|
msgid "Cannot extract event from url {}"
|
||||||
msgstr "Impossible d'extraire l'événement depuis l'url {}"
|
msgstr "Impossible d'extraire l'événement depuis l'url {}"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:39 agenda_culturel/models.py:68
|
#: agenda_culturel/models.py:39 agenda_culturel/models.py:68
|
||||||
#: agenda_culturel/models.py:162 agenda_culturel/models.py:753
|
#: agenda_culturel/models.py:162 agenda_culturel/models.py:770
|
||||||
#: agenda_culturel/models.py:792
|
#: agenda_culturel/models.py:809
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
|
|
||||||
@@ -89,8 +105,8 @@ msgstr "Couleur"
|
|||||||
msgid "Color used as background for the category"
|
msgid "Color used as background for the category"
|
||||||
msgstr "Couleur utilisée comme fond de la catégorie"
|
msgstr "Couleur utilisée comme fond de la catégorie"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:115 agenda_culturel/models.py:195
|
#: agenda_culturel/models.py:115 agenda_culturel/models.py:205
|
||||||
#: agenda_culturel/models.py:804 agenda_culturel/models.py:855
|
#: agenda_culturel/models.py:821 agenda_culturel/models.py:872
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
msgstr "Catégorie"
|
msgstr "Catégorie"
|
||||||
|
|
||||||
@@ -107,14 +123,22 @@ msgid "Address"
|
|||||||
msgstr "Adresse"
|
msgstr "Adresse"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:163
|
#: agenda_culturel/models.py:163
|
||||||
msgid "Address of this place"
|
msgid "Address of this place (without city name)"
|
||||||
msgstr "Adresse de ce lieu"
|
msgstr "Adresse de ce lieu (sans le nom de la ville)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:166
|
#: agenda_culturel/models.py:164
|
||||||
|
msgid "City"
|
||||||
|
msgstr "Ville"
|
||||||
|
|
||||||
|
#: agenda_culturel/models.py:164
|
||||||
|
msgid "City name"
|
||||||
|
msgstr "Nom de la ville"
|
||||||
|
|
||||||
|
#: agenda_culturel/models.py:167
|
||||||
msgid "Alternative names"
|
msgid "Alternative names"
|
||||||
msgstr "Noms alternatifs"
|
msgstr "Noms alternatifs"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:166
|
#: agenda_culturel/models.py:167
|
||||||
msgid ""
|
msgid ""
|
||||||
"Alternative names or addresses used to match a place with the free-form "
|
"Alternative names or addresses used to match a place with the free-form "
|
||||||
"location of an event."
|
"location of an event."
|
||||||
@@ -122,81 +146,77 @@ msgstr ""
|
|||||||
"Noms et adresses alternatives qui seront utilisées pour associer une adresse "
|
"Noms et adresses alternatives qui seront utilisées pour associer une adresse "
|
||||||
"avec la localisation en forme libre d'un événement"
|
"avec la localisation en forme libre d'un événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:169
|
#: agenda_culturel/models.py:171
|
||||||
msgid "Place"
|
|
||||||
msgstr "Lieu"
|
|
||||||
|
|
||||||
#: agenda_culturel/models.py:170
|
|
||||||
msgid "Places"
|
msgid "Places"
|
||||||
msgstr "Lieux"
|
msgstr "Lieux"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:179 agenda_culturel/models.py:802
|
#: agenda_culturel/models.py:189 agenda_culturel/models.py:819
|
||||||
msgid "Published"
|
msgid "Published"
|
||||||
msgstr "Publié"
|
msgstr "Publié"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:180
|
#: agenda_culturel/models.py:190
|
||||||
msgid "Draft"
|
msgid "Draft"
|
||||||
msgstr "Brouillon"
|
msgstr "Brouillon"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:181
|
#: agenda_culturel/models.py:191
|
||||||
msgid "Trash"
|
msgid "Trash"
|
||||||
msgstr "Corbeille"
|
msgstr "Corbeille"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:191
|
#: agenda_culturel/models.py:201
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titre"
|
msgstr "Titre"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:191
|
#: agenda_culturel/models.py:201
|
||||||
msgid "Short title"
|
msgid "Short title"
|
||||||
msgstr "Titre court"
|
msgstr "Titre court"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:193 agenda_culturel/models.py:839
|
#: agenda_culturel/models.py:203 agenda_culturel/models.py:856
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:195
|
#: agenda_culturel/models.py:205
|
||||||
msgid "Category of the event"
|
msgid "Category of the event"
|
||||||
msgstr "Catégorie de l'événement"
|
msgstr "Catégorie de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:197
|
#: agenda_culturel/models.py:207
|
||||||
msgid "Day of the event"
|
msgid "Day of the event"
|
||||||
msgstr "Date de l'événement"
|
msgstr "Date de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:198
|
#: agenda_culturel/models.py:208
|
||||||
msgid "Starting time"
|
msgid "Starting time"
|
||||||
msgstr "Heure de début"
|
msgstr "Heure de début"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:200
|
#: agenda_culturel/models.py:210
|
||||||
msgid "End day of the event"
|
msgid "End day of the event"
|
||||||
msgstr "Fin de l'événement"
|
msgstr "Fin de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:200
|
#: agenda_culturel/models.py:210
|
||||||
msgid "End day of the event, only required if different from the start day."
|
msgid "End day of the event, only required if different from the start day."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Date de fin de l'événement, uniquement nécessaire s'il est différent du "
|
"Date de fin de l'événement, uniquement nécessaire s'il est différent du "
|
||||||
"premier jour de l'événement"
|
"premier jour de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:201
|
#: agenda_culturel/models.py:211
|
||||||
msgid "Final time"
|
msgid "Final time"
|
||||||
msgstr "Heure de fin"
|
msgstr "Heure de fin"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:203
|
#: agenda_culturel/models.py:213
|
||||||
msgid "Recurrence"
|
msgid "Recurrence"
|
||||||
msgstr "Récurrence"
|
msgstr "Récurrence"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:205 agenda_culturel/models.py:803
|
#: agenda_culturel/models.py:215 agenda_culturel/models.py:820
|
||||||
msgid "Location"
|
msgid "Location"
|
||||||
msgstr "Localisation"
|
msgstr "Localisation"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:205
|
#: agenda_culturel/models.py:215
|
||||||
msgid "Address of the event"
|
msgid "Address of the event"
|
||||||
msgstr "Adresse de l'événement"
|
msgstr "Adresse de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:206
|
#: agenda_culturel/models.py:216
|
||||||
msgid "Location (free form)"
|
msgid "Location (free form)"
|
||||||
msgstr "Localisation (forme libre)"
|
msgstr "Localisation (forme libre)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:206
|
#: agenda_culturel/models.py:216
|
||||||
msgid ""
|
msgid ""
|
||||||
"Address of the event in case its not available in the already known places "
|
"Address of the event in case its not available in the already known places "
|
||||||
"(free form)"
|
"(free form)"
|
||||||
@@ -204,189 +224,187 @@ msgstr ""
|
|||||||
"Addresse d'un événement si elle n'est pas déjà présente dans la liste des "
|
"Addresse d'un événement si elle n'est pas déjà présente dans la liste des "
|
||||||
"lieux disponible (forme libre)"
|
"lieux disponible (forme libre)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:208
|
#: agenda_culturel/models.py:218
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Description"
|
msgstr "Description"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:208
|
#: agenda_culturel/models.py:218
|
||||||
msgid "General description of the event"
|
msgid "General description of the event"
|
||||||
msgstr "Description générale de l'événement"
|
msgstr "Description générale de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:210
|
#: agenda_culturel/models.py:220
|
||||||
msgid "Illustration (local image)"
|
msgid "Illustration (local image)"
|
||||||
msgstr "Illustration (image locale)"
|
msgstr "Illustration (image locale)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:210
|
#: agenda_culturel/models.py:220
|
||||||
msgid "Illustration image stored in the agenda server"
|
msgid "Illustration image stored in the agenda server"
|
||||||
msgstr "Image d'illustration stockée sur le serveur de l'agenda"
|
msgstr "Image d'illustration stockée sur le serveur de l'agenda"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:212
|
#: agenda_culturel/models.py:222
|
||||||
msgid "Illustration"
|
msgid "Illustration"
|
||||||
msgstr "Illustration"
|
msgstr "Illustration"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:212
|
#: agenda_culturel/models.py:222
|
||||||
msgid "URL of the illustration image"
|
msgid "URL of the illustration image"
|
||||||
msgstr "URL de l'image illustrative"
|
msgstr "URL de l'image illustrative"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:213
|
#: agenda_culturel/models.py:223
|
||||||
msgid "Illustration description"
|
msgid "Illustration description"
|
||||||
msgstr "Description de l'illustration"
|
msgstr "Description de l'illustration"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:213
|
#: agenda_culturel/models.py:223
|
||||||
msgid "Alternative text used by screen readers for the image"
|
msgid "Alternative text used by screen readers for the image"
|
||||||
msgstr "Texte alternatif utiliser par les lecteurs d'écrans pour l'image"
|
msgstr "Texte alternatif utiliser par les lecteurs d'écrans pour l'image"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:215
|
#: agenda_culturel/models.py:225
|
||||||
msgid "Importation source"
|
msgid "Importation source"
|
||||||
msgstr "Source d'importation"
|
msgstr "Source d'importation"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:215
|
#: agenda_culturel/models.py:225
|
||||||
msgid "Importation source used to detect removed entries."
|
msgid "Importation source used to detect removed entries."
|
||||||
msgstr "Source d'importation utilisée pour détecter les éléments supprimés/"
|
msgstr "Source d'importation utilisée pour détecter les éléments supprimés/"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:216
|
#: agenda_culturel/models.py:226
|
||||||
msgid "UUIDs"
|
msgid "UUIDs"
|
||||||
msgstr "UUIDs"
|
msgstr "UUIDs"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:216
|
#: agenda_culturel/models.py:226
|
||||||
msgid "UUIDs from import to detect duplicated entries."
|
msgid "UUIDs from import to detect duplicated entries."
|
||||||
msgstr "UUIDs utilisés pendant l'import pour détecter les entrées dupliquées"
|
msgstr "UUIDs utilisés pendant l'import pour détecter les entrées dupliquées"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:217
|
#: agenda_culturel/models.py:227
|
||||||
msgid "URLs"
|
msgid "URLs"
|
||||||
msgstr "URLs"
|
msgstr "URLs"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:217
|
#: agenda_culturel/models.py:227
|
||||||
msgid "List of all the urls where this event can be found."
|
msgid "List of all the urls where this event can be found."
|
||||||
msgstr "Liste de toutes les urls où l'événement peut être trouvé."
|
msgstr "Liste de toutes les urls où l'événement peut être trouvé."
|
||||||
|
|
||||||
#: agenda_culturel/models.py:219
|
#: agenda_culturel/models.py:229
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Étiquettes"
|
msgstr "Étiquettes"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:219
|
#: agenda_culturel/models.py:229
|
||||||
msgid "A list of tags that describe the event."
|
msgid "A list of tags that describe the event."
|
||||||
msgstr "Une liste d'étiquettes décrivant l'événement"
|
msgstr "Une liste d'étiquettes décrivant l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:221
|
#: agenda_culturel/models.py:231
|
||||||
msgid "Possibly duplicated"
|
msgid "Possibly duplicated"
|
||||||
msgstr "Possibles doublons"
|
msgstr "Possibles doublons"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:262
|
#: agenda_culturel/models.py:272
|
||||||
msgid "Event"
|
msgid "Event"
|
||||||
msgstr "Événement"
|
msgstr "Événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:263
|
#: agenda_culturel/models.py:273
|
||||||
msgid "Events"
|
msgid "Events"
|
||||||
msgstr "Événements"
|
msgstr "Événements"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:749
|
#: agenda_culturel/models.py:766
|
||||||
msgid "Contact message"
|
msgid "Contact message"
|
||||||
msgstr "Message de contact"
|
msgstr "Message de contact"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:750
|
#: agenda_culturel/models.py:767
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Your message"
|
|
||||||
msgid "Contact messages"
|
msgid "Contact messages"
|
||||||
msgstr "Messages de contact"
|
msgstr "Messages de contact"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:752
|
#: agenda_culturel/models.py:769
|
||||||
msgid "Subject"
|
msgid "Subject"
|
||||||
msgstr "Sujet"
|
msgstr "Sujet"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:752
|
#: agenda_culturel/models.py:769
|
||||||
msgid "The subject of your message"
|
msgid "The subject of your message"
|
||||||
msgstr "Sujet de votre message"
|
msgstr "Sujet de votre message"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:753
|
#: agenda_culturel/models.py:770
|
||||||
msgid "Your name"
|
msgid "Your name"
|
||||||
msgstr "Votre nom"
|
msgstr "Votre nom"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:754
|
#: agenda_culturel/models.py:771
|
||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Adresse email"
|
msgstr "Adresse email"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:754
|
#: agenda_culturel/models.py:771
|
||||||
msgid "Your email address"
|
msgid "Your email address"
|
||||||
msgstr "Votre adresse email"
|
msgstr "Votre adresse email"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:755
|
#: agenda_culturel/models.py:772
|
||||||
msgid "Message"
|
msgid "Message"
|
||||||
msgstr "Message"
|
msgstr "Message"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:755
|
#: agenda_culturel/models.py:772
|
||||||
msgid "Your message"
|
msgid "Your message"
|
||||||
msgstr "Votre message"
|
msgstr "Votre message"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:759 agenda_culturel/views.py:462
|
#: agenda_culturel/models.py:776 agenda_culturel/views.py:470
|
||||||
msgid "Closed"
|
msgid "Closed"
|
||||||
msgstr "Fermé"
|
msgstr "Fermé"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:759
|
#: agenda_culturel/models.py:776
|
||||||
msgid "this message has been processed and no longer needs to be handled"
|
msgid "this message has been processed and no longer needs to be handled"
|
||||||
msgstr "Ce message a été traité et ne nécessite plus d'être pris en charge"
|
msgstr "Ce message a été traité et ne nécessite plus d'être pris en charge"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:760
|
#: agenda_culturel/models.py:777
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Commentaires"
|
msgstr "Commentaires"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:760
|
#: agenda_culturel/models.py:777
|
||||||
msgid "Comments on the message from the moderation team"
|
msgid "Comments on the message from the moderation team"
|
||||||
msgstr "Commentaires sur ce message par l'équipe de modération"
|
msgstr "Commentaires sur ce message par l'équipe de modération"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:770 agenda_culturel/models.py:837
|
#: agenda_culturel/models.py:787 agenda_culturel/models.py:854
|
||||||
msgid "Recurrent import"
|
msgid "Recurrent import"
|
||||||
msgstr "Import récurrent"
|
msgstr "Import récurrent"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:771
|
#: agenda_culturel/models.py:788
|
||||||
msgid "Recurrent imports"
|
msgid "Recurrent imports"
|
||||||
msgstr "Imports récurrents"
|
msgstr "Imports récurrents"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:775
|
#: agenda_culturel/models.py:792
|
||||||
msgid "ical"
|
msgid "ical"
|
||||||
msgstr "ical"
|
msgstr "ical"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:776
|
#: agenda_culturel/models.py:793
|
||||||
msgid "ical no busy"
|
msgid "ical no busy"
|
||||||
msgstr "ical sans busy"
|
msgstr "ical sans busy"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:777
|
#: agenda_culturel/models.py:794
|
||||||
msgid "ical no VC"
|
msgid "ical no VC"
|
||||||
msgstr "ical sans VC"
|
msgstr "ical sans VC"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:778
|
#: agenda_culturel/models.py:795
|
||||||
msgid "lacoope.org"
|
msgid "lacoope.org"
|
||||||
msgstr "lacoope.org"
|
msgstr "lacoope.org"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:779
|
#: agenda_culturel/models.py:796
|
||||||
msgid "la comédie"
|
msgid "la comédie"
|
||||||
msgstr "la comédie"
|
msgstr "la comédie"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:780
|
#: agenda_culturel/models.py:797
|
||||||
msgid "le fotomat"
|
msgid "le fotomat"
|
||||||
msgstr "le fotomat"
|
msgstr "le fotomat"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:781
|
#: agenda_culturel/models.py:798
|
||||||
msgid "la puce à loreille"
|
msgid "la puce à loreille"
|
||||||
msgstr "la puce à loreille"
|
msgstr "la puce à loreille"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:784
|
#: agenda_culturel/models.py:801
|
||||||
msgid "simple"
|
msgid "simple"
|
||||||
msgstr "simple"
|
msgstr "simple"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:785
|
#: agenda_culturel/models.py:802
|
||||||
msgid "Headless Chromium"
|
msgid "Headless Chromium"
|
||||||
msgstr "chromium sans interface"
|
msgstr "chromium sans interface"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:789
|
#: agenda_culturel/models.py:806
|
||||||
msgid "daily"
|
msgid "daily"
|
||||||
msgstr "chaque jour"
|
msgstr "chaque jour"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:790
|
#: agenda_culturel/models.py:807
|
||||||
msgid "weekly"
|
msgid "weekly"
|
||||||
msgstr "chaque semaine"
|
msgstr "chaque semaine"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:792
|
#: agenda_culturel/models.py:809
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recurrent import name. Be careful to choose a name that is easy to "
|
"Recurrent import name. Be careful to choose a name that is easy to "
|
||||||
"understand, as it will be public and displayed on the sites About page."
|
"understand, as it will be public and displayed on the sites About page."
|
||||||
@@ -394,127 +412,127 @@ msgstr ""
|
|||||||
"Nom de l'import récurrent. Attention à choisir un nom compréhensible, car il "
|
"Nom de l'import récurrent. Attention à choisir un nom compréhensible, car il "
|
||||||
"sera public, et affiché sur la page à propos du site."
|
"sera public, et affiché sur la page à propos du site."
|
||||||
|
|
||||||
#: agenda_culturel/models.py:793
|
#: agenda_culturel/models.py:810
|
||||||
msgid "Processor"
|
msgid "Processor"
|
||||||
msgstr "Processeur"
|
msgstr "Processeur"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:794
|
#: agenda_culturel/models.py:811
|
||||||
msgid "Downloader"
|
msgid "Downloader"
|
||||||
msgstr "Téléchargeur"
|
msgstr "Téléchargeur"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:796
|
#: agenda_culturel/models.py:813
|
||||||
msgid "Import recurrence"
|
msgid "Import recurrence"
|
||||||
msgstr "Récurrence d'import"
|
msgstr "Récurrence d'import"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:799
|
#: agenda_culturel/models.py:816
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "Source"
|
msgstr "Source"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:799
|
#: agenda_culturel/models.py:816
|
||||||
msgid "URL of the source document"
|
msgid "URL of the source document"
|
||||||
msgstr "URL du document source"
|
msgstr "URL du document source"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:800
|
#: agenda_culturel/models.py:817
|
||||||
msgid "Browsable url"
|
msgid "Browsable url"
|
||||||
msgstr "URL navigable"
|
msgstr "URL navigable"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:800
|
#: agenda_culturel/models.py:817
|
||||||
msgid "URL of the corresponding document that will be shown to visitors."
|
msgid "URL of the corresponding document that will be shown to visitors."
|
||||||
msgstr "URL correspondant au document et qui sera montrée aux visiteurs"
|
msgstr "URL correspondant au document et qui sera montrée aux visiteurs"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:802
|
#: agenda_culturel/models.py:819
|
||||||
msgid "Status of each imported event (published or draft)"
|
msgid "Status of each imported event (published or draft)"
|
||||||
msgstr "Status de chaque événement importé (publié ou brouillon)"
|
msgstr "Status de chaque événement importé (publié ou brouillon)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:803
|
#: agenda_culturel/models.py:820
|
||||||
msgid "Address for each imported event"
|
msgid "Address for each imported event"
|
||||||
msgstr "Adresse de chaque événement importé"
|
msgstr "Adresse de chaque événement importé"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:804
|
#: agenda_culturel/models.py:821
|
||||||
msgid "Category of each imported event"
|
msgid "Category of each imported event"
|
||||||
msgstr "Catégorie de chaque événement importé"
|
msgstr "Catégorie de chaque événement importé"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:805
|
#: agenda_culturel/models.py:822
|
||||||
msgid "Tags for each imported event"
|
msgid "Tags for each imported event"
|
||||||
msgstr "Étiquettes de chaque événement importé"
|
msgstr "Étiquettes de chaque événement importé"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:805
|
#: agenda_culturel/models.py:822
|
||||||
msgid "A list of tags that describe each imported event."
|
msgid "A list of tags that describe each imported event."
|
||||||
msgstr "Une liste d'étiquettes décrivant chaque événement importé"
|
msgstr "Une liste d'étiquettes décrivant chaque événement importé"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:824
|
#: agenda_culturel/models.py:841
|
||||||
msgid "Running"
|
msgid "Running"
|
||||||
msgstr "En cours"
|
msgstr "En cours"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:825
|
#: agenda_culturel/models.py:842
|
||||||
msgid "Canceled"
|
msgid "Canceled"
|
||||||
msgstr "Annulé"
|
msgstr "Annulé"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:826
|
#: agenda_culturel/models.py:843
|
||||||
msgid "Success"
|
msgid "Success"
|
||||||
msgstr "Succès"
|
msgstr "Succès"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:827
|
#: agenda_culturel/models.py:844
|
||||||
msgid "Failed"
|
msgid "Failed"
|
||||||
msgstr "Erreur"
|
msgstr "Erreur"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:830
|
#: agenda_culturel/models.py:847
|
||||||
msgid "Batch importation"
|
msgid "Batch importation"
|
||||||
msgstr "Importation par lot"
|
msgstr "Importation par lot"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:831
|
#: agenda_culturel/models.py:848
|
||||||
msgid "Batch importations"
|
msgid "Batch importations"
|
||||||
msgstr "Importations par lot"
|
msgstr "Importations par lot"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:837
|
#: agenda_culturel/models.py:854
|
||||||
msgid "Reference to the recurrent import processing"
|
msgid "Reference to the recurrent import processing"
|
||||||
msgstr "Référence du processus d'import récurrent"
|
msgstr "Référence du processus d'import récurrent"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:841
|
#: agenda_culturel/models.py:858
|
||||||
msgid "Error message"
|
msgid "Error message"
|
||||||
msgstr "Votre message"
|
msgstr "Votre message"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:843
|
#: agenda_culturel/models.py:860
|
||||||
msgid "Number of collected events"
|
msgid "Number of collected events"
|
||||||
msgstr "Nombre d'événements collectés"
|
msgstr "Nombre d'événements collectés"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:844
|
#: agenda_culturel/models.py:861
|
||||||
msgid "Number of imported events"
|
msgid "Number of imported events"
|
||||||
msgstr "Nombre d'événements importés"
|
msgstr "Nombre d'événements importés"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:845
|
#: agenda_culturel/models.py:862
|
||||||
msgid "Number of updated events"
|
msgid "Number of updated events"
|
||||||
msgstr "Nombre d'événements mis à jour"
|
msgstr "Nombre d'événements mis à jour"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:846
|
#: agenda_culturel/models.py:863
|
||||||
msgid "Number of removed events"
|
msgid "Number of removed events"
|
||||||
msgstr "Nombre d'événements supprimés"
|
msgstr "Nombre d'événements supprimés"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:853
|
#: agenda_culturel/models.py:870
|
||||||
msgid "Weight"
|
msgid "Weight"
|
||||||
msgstr "Poids"
|
msgstr "Poids"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:853
|
#: agenda_culturel/models.py:870
|
||||||
msgid "The lower is the weight, the earlier the filter is applied"
|
msgid "The lower is the weight, the earlier the filter is applied"
|
||||||
msgstr "Plus le poids est léger, plus le filtre sera appliqué tôt"
|
msgstr "Plus le poids est léger, plus le filtre sera appliqué tôt"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:855
|
#: agenda_culturel/models.py:872
|
||||||
msgid "Category applied to the event"
|
msgid "Category applied to the event"
|
||||||
msgstr "Catégorie appliquée à l'événement"
|
msgstr "Catégorie appliquée à l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:857
|
#: agenda_culturel/models.py:874
|
||||||
msgid "Contained in the title"
|
msgid "Contained in the title"
|
||||||
msgstr "Contenu dans le titre"
|
msgstr "Contenu dans le titre"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:857
|
#: agenda_culturel/models.py:874
|
||||||
msgid "Text contained in the event title"
|
msgid "Text contained in the event title"
|
||||||
msgstr "Texte contenu dans le titre de l'événement"
|
msgstr "Texte contenu dans le titre de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:858
|
#: agenda_culturel/models.py:875
|
||||||
msgid "Exact title extract"
|
msgid "Exact title extract"
|
||||||
msgstr "Extrait exact du titre"
|
msgstr "Extrait exact du titre"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:858
|
#: agenda_culturel/models.py:875
|
||||||
msgid ""
|
msgid ""
|
||||||
"If checked, the extract will be searched for in the title using the exact "
|
"If checked, the extract will be searched for in the title using the exact "
|
||||||
"form (capitals, accents)."
|
"form (capitals, accents)."
|
||||||
@@ -522,19 +540,19 @@ msgstr ""
|
|||||||
"Si coché, l'extrait sera recherché dans le titre en utilisant la forme "
|
"Si coché, l'extrait sera recherché dans le titre en utilisant la forme "
|
||||||
"exacte (majuscules, accents)"
|
"exacte (majuscules, accents)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:860
|
#: agenda_culturel/models.py:877
|
||||||
msgid "Contained in the description"
|
msgid "Contained in the description"
|
||||||
msgstr "Contenu dans la description"
|
msgstr "Contenu dans la description"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:860
|
#: agenda_culturel/models.py:877
|
||||||
msgid "Text contained in the description"
|
msgid "Text contained in the description"
|
||||||
msgstr "Texte contenu dans la description"
|
msgstr "Texte contenu dans la description"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:861
|
#: agenda_culturel/models.py:878
|
||||||
msgid "Exact description extract"
|
msgid "Exact description extract"
|
||||||
msgstr "Extrait exact de description"
|
msgstr "Extrait exact de description"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:861
|
#: agenda_culturel/models.py:878
|
||||||
msgid ""
|
msgid ""
|
||||||
"If checked, the extract will be searched for in the description using the "
|
"If checked, the extract will be searched for in the description using the "
|
||||||
"exact form (capitals, accents)."
|
"exact form (capitals, accents)."
|
||||||
@@ -542,19 +560,19 @@ msgstr ""
|
|||||||
"Si coché, l'extrait sera recherché dans la description en utilisant la forme "
|
"Si coché, l'extrait sera recherché dans la description en utilisant la forme "
|
||||||
"exacte (majuscules, accents)"
|
"exacte (majuscules, accents)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:863
|
#: agenda_culturel/models.py:880
|
||||||
msgid "Contained in the location"
|
msgid "Contained in the location"
|
||||||
msgstr "Contenu dans la localisation"
|
msgstr "Contenu dans la localisation"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:863
|
#: agenda_culturel/models.py:880
|
||||||
msgid "Text contained in the event location"
|
msgid "Text contained in the event location"
|
||||||
msgstr "Texte contenu dans la localisation de l'événement"
|
msgstr "Texte contenu dans la localisation de l'événement"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:864
|
#: agenda_culturel/models.py:881
|
||||||
msgid "Exact location extract"
|
msgid "Exact location extract"
|
||||||
msgstr "Extrait exact de localisation"
|
msgstr "Extrait exact de localisation"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:864
|
#: agenda_culturel/models.py:881
|
||||||
msgid ""
|
msgid ""
|
||||||
"If checked, the extract will be searched for in the location using the exact "
|
"If checked, the extract will be searched for in the location using the exact "
|
||||||
"form (capitals, accents)."
|
"form (capitals, accents)."
|
||||||
@@ -562,52 +580,52 @@ msgstr ""
|
|||||||
"Si coché, l'extrait sera recherché dans la localisation en utilisant la "
|
"Si coché, l'extrait sera recherché dans la localisation en utilisant la "
|
||||||
"forme exacte (majuscules, accents)"
|
"forme exacte (majuscules, accents)"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:867
|
#: agenda_culturel/models.py:884
|
||||||
msgid "Categorisation rule"
|
msgid "Categorisation rule"
|
||||||
msgstr "Règle de catégorisation"
|
msgstr "Règle de catégorisation"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:868
|
#: agenda_culturel/models.py:885
|
||||||
msgid "Categorisation rules"
|
msgid "Categorisation rules"
|
||||||
msgstr "Règles de catégorisation"
|
msgstr "Règles de catégorisation"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:924 agenda_culturel/models.py:945
|
#: agenda_culturel/models.py:941 agenda_culturel/models.py:962
|
||||||
msgid "Question"
|
msgid "Question"
|
||||||
msgstr "Question"
|
msgstr "Question"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:924 agenda_culturel/models.py:947
|
#: agenda_culturel/models.py:941 agenda_culturel/models.py:964
|
||||||
msgid "Text that will be shown to moderators"
|
msgid "Text that will be shown to moderators"
|
||||||
msgstr "Text tel que présenté aux modérateurices"
|
msgstr "Text tel que présenté aux modérateurices"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:927
|
#: agenda_culturel/models.py:944
|
||||||
msgid "Moderation question"
|
msgid "Moderation question"
|
||||||
msgstr "Question de modération"
|
msgstr "Question de modération"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:928
|
#: agenda_culturel/models.py:945
|
||||||
msgid "Moderation questions"
|
msgid "Moderation questions"
|
||||||
msgstr "Questions de modération"
|
msgstr "Questions de modération"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:945
|
#: agenda_culturel/models.py:962
|
||||||
msgid "Associated question from moderation"
|
msgid "Associated question from moderation"
|
||||||
msgstr "Question associée pour la modération"
|
msgstr "Question associée pour la modération"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:947
|
#: agenda_culturel/models.py:964
|
||||||
msgid "Answer"
|
msgid "Answer"
|
||||||
msgstr "Réponse"
|
msgstr "Réponse"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:949
|
#: agenda_culturel/models.py:966
|
||||||
msgid "Adds tags"
|
msgid "Adds tags"
|
||||||
msgstr "Ajoute les étiquettes"
|
msgstr "Ajoute les étiquettes"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:949
|
#: agenda_culturel/models.py:966
|
||||||
msgid "A list of tags that will be added if you choose this answer."
|
msgid "A list of tags that will be added if you choose this answer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Une liste d'étiquettes qui seront ajoutées si vous choisissez cette réponse."
|
"Une liste d'étiquettes qui seront ajoutées si vous choisissez cette réponse."
|
||||||
|
|
||||||
#: agenda_culturel/models.py:950
|
#: agenda_culturel/models.py:967
|
||||||
msgid "Removes tags"
|
msgid "Removes tags"
|
||||||
msgstr "Retire les étiquettes"
|
msgstr "Retire les étiquettes"
|
||||||
|
|
||||||
#: agenda_culturel/models.py:950
|
#: agenda_culturel/models.py:967
|
||||||
msgid "A list of tags that will be removed if you choose this answer."
|
msgid "A list of tags that will be removed if you choose this answer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Une liste d'étiquettes qui seront retirées si vous choisissez cette réponse."
|
"Une liste d'étiquettes qui seront retirées si vous choisissez cette réponse."
|
||||||
@@ -620,27 +638,27 @@ msgstr "anglais"
|
|||||||
msgid "French"
|
msgid "French"
|
||||||
msgstr "français"
|
msgstr "français"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:261
|
#: agenda_culturel/views.py:269
|
||||||
msgid "The static content has been successfully updated."
|
msgid "The static content has been successfully updated."
|
||||||
msgstr "Le contenu statique a été modifié avec succès."
|
msgstr "Le contenu statique a été modifié avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:268 agenda_culturel/views.py:303
|
#: agenda_culturel/views.py:276 agenda_culturel/views.py:311
|
||||||
msgid "The event has been successfully modified."
|
msgid "The event has been successfully modified."
|
||||||
msgstr "L'événement a été modifié avec succès."
|
msgstr "L'événement a été modifié avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:280
|
#: agenda_culturel/views.py:288
|
||||||
msgid "The event has been successfully deleted."
|
msgid "The event has been successfully deleted."
|
||||||
msgstr "L'événement a été supprimé avec succès"
|
msgstr "L'événement a été supprimé avec succès"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:329
|
#: agenda_culturel/views.py:337
|
||||||
msgid "The status has been successfully modified."
|
msgid "The status has been successfully modified."
|
||||||
msgstr "Le status a été modifié avec succès."
|
msgstr "Le status a été modifié avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:351
|
#: agenda_culturel/views.py:359
|
||||||
msgid "The event is saved."
|
msgid "The event is saved."
|
||||||
msgstr "L'événement est enregistré."
|
msgstr "L'événement est enregistré."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:354
|
#: agenda_culturel/views.py:362
|
||||||
msgid ""
|
msgid ""
|
||||||
"The event has been submitted and will be published as soon as it has been "
|
"The event has been submitted and will be published as soon as it has been "
|
||||||
"validated by the moderation team."
|
"validated by the moderation team."
|
||||||
@@ -648,7 +666,7 @@ msgstr ""
|
|||||||
"L'événement a été soumis et sera publié dès qu'il aura été validé par "
|
"L'événement a été soumis et sera publié dès qu'il aura été validé par "
|
||||||
"l'équipe de modération."
|
"l'équipe de modération."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:391
|
#: agenda_culturel/views.py:399
|
||||||
msgid ""
|
msgid ""
|
||||||
"The event has been successfully extracted, and you can now submit it after "
|
"The event has been successfully extracted, and you can now submit it after "
|
||||||
"modifying it if necessary."
|
"modifying it if necessary."
|
||||||
@@ -656,7 +674,7 @@ msgstr ""
|
|||||||
"L'événement a été extrait avec succès, vous pouvez maintenant le soumettre "
|
"L'événement a été extrait avec succès, vous pouvez maintenant le soumettre "
|
||||||
"après l'avoir modifié au besoin."
|
"après l'avoir modifié au besoin."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:395
|
#: agenda_culturel/views.py:403
|
||||||
msgid ""
|
msgid ""
|
||||||
"Unable to extract an event from the proposed URL. Please use the form below "
|
"Unable to extract an event from the proposed URL. Please use the form below "
|
||||||
"to submit the event."
|
"to submit the event."
|
||||||
@@ -664,16 +682,16 @@ msgstr ""
|
|||||||
"Impossible d'extraire un événement depuis l'URL proposée. Veuillez utiliser "
|
"Impossible d'extraire un événement depuis l'URL proposée. Veuillez utiliser "
|
||||||
"le formulaire ci-dessous pour soumettre l'événement."
|
"le formulaire ci-dessous pour soumettre l'événement."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:404
|
#: agenda_culturel/views.py:412
|
||||||
msgid "This URL has already been submitted, and you can find the event below."
|
msgid "This URL has already been submitted, and you can find the event below."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Cette URL a déjà été soumise, et vous trouverez l'événement ci-dessous."
|
"Cette URL a déjà été soumise, et vous trouverez l'événement ci-dessous."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:408
|
#: agenda_culturel/views.py:416
|
||||||
msgid "This URL has already been submitted and is awaiting moderation."
|
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"
|
msgstr "Cette URL a déjà été soumise, et est en attente de modération"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:410
|
#: agenda_culturel/views.py:418
|
||||||
msgid ""
|
msgid ""
|
||||||
"This URL has already been submitted, but has not been selected for "
|
"This URL has already been submitted, but has not been selected for "
|
||||||
"publication by the moderation team."
|
"publication by the moderation team."
|
||||||
@@ -681,51 +699,51 @@ msgstr ""
|
|||||||
"Cette URL a déjà été soumise, mais n'a pas été retenue par l'équipe de "
|
"Cette URL a déjà été soumise, mais n'a pas été retenue par l'équipe de "
|
||||||
"modération pour la publication."
|
"modération pour la publication."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:432
|
#: agenda_culturel/views.py:440
|
||||||
msgid "Your message has been sent successfully."
|
msgid "Your message has been sent successfully."
|
||||||
msgstr "Votre message a été envoyé avec succès."
|
msgstr "Votre message a été envoyé avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:447
|
#: agenda_culturel/views.py:455
|
||||||
msgid "The contact message properties has been successfully modified."
|
msgid "The contact message properties has been successfully modified."
|
||||||
msgstr "Les propriétés du message de contact ont été modifié avec succès."
|
msgstr "Les propriétés du message de contact ont été modifié avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:462
|
#: agenda_culturel/views.py:470
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Ouvert"
|
msgstr "Ouvert"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:504
|
#: agenda_culturel/views.py:512
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Rechercher"
|
msgstr "Rechercher"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:639
|
#: agenda_culturel/views.py:647
|
||||||
msgid "The import has been run successfully."
|
msgid "The import has been run successfully."
|
||||||
msgstr "L'import a été lancé avec succès"
|
msgstr "L'import a été lancé avec succès"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:656
|
#: agenda_culturel/views.py:664
|
||||||
msgid "The import has been canceled."
|
msgid "The import has been canceled."
|
||||||
msgstr "L'import a été annulé"
|
msgstr "L'import a été annulé"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:693
|
#: agenda_culturel/views.py:701
|
||||||
msgid "The recurrent import has been successfully modified."
|
msgid "The recurrent import has been successfully modified."
|
||||||
msgstr "L'import récurrent a été modifié avec succès."
|
msgstr "L'import récurrent a été modifié avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:700
|
#: agenda_culturel/views.py:708
|
||||||
msgid "The recurrent import has been successfully deleted."
|
msgid "The recurrent import has been successfully deleted."
|
||||||
msgstr "L'import récurrent a été supprimé avec succès"
|
msgstr "L'import récurrent a été supprimé avec succès"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:731
|
#: agenda_culturel/views.py:739
|
||||||
msgid "The import has been launched."
|
msgid "The import has been launched."
|
||||||
msgstr "L'import a été lancé"
|
msgstr "L'import a été lancé"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:791
|
#: agenda_culturel/views.py:799
|
||||||
msgid "The merge has been successfully completed."
|
msgid "The merge has been successfully completed."
|
||||||
msgstr "La fusion a été réalisée avec succès."
|
msgstr "La fusion a été réalisée avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:821
|
#: agenda_culturel/views.py:829
|
||||||
msgid "Events have been marked as unduplicated."
|
msgid "Events have been marked as unduplicated."
|
||||||
msgstr "Les événements ont été marqués comme non dupliqués."
|
msgstr "Les événements ont été marqués comme non dupliqués."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:838
|
#: agenda_culturel/views.py:846
|
||||||
msgid ""
|
msgid ""
|
||||||
"The selected event has been retained, while the other has been moved to the "
|
"The selected event has been retained, while the other has been moved to the "
|
||||||
"recycle bin."
|
"recycle bin."
|
||||||
@@ -733,7 +751,7 @@ msgstr ""
|
|||||||
"L'événement sélectionné a été conservé, l'autre a été déplacé dans la "
|
"L'événement sélectionné a été conservé, l'autre a été déplacé dans la "
|
||||||
"corbeille."
|
"corbeille."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:840
|
#: agenda_culturel/views.py:848
|
||||||
msgid ""
|
msgid ""
|
||||||
"The selected event has been retained, while the others have been moved to "
|
"The selected event has been retained, while the others have been moved to "
|
||||||
"the recycle bin."
|
"the recycle bin."
|
||||||
@@ -741,15 +759,15 @@ msgstr ""
|
|||||||
"L'événement sélectionné a été conservé, les autres ont été déplacés dans la "
|
"L'événement sélectionné a été conservé, les autres ont été déplacés dans la "
|
||||||
"corbeille."
|
"corbeille."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:846
|
#: agenda_culturel/views.py:854
|
||||||
msgid "The event has been withdrawn from the group and made independent."
|
msgid "The event has been withdrawn from the group and made independent."
|
||||||
msgstr "L'événement a été retiré du groupe et rendu indépendant."
|
msgstr "L'événement a été retiré du groupe et rendu indépendant."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:893
|
#: agenda_culturel/views.py:901
|
||||||
msgid "The event was successfully duplicated."
|
msgid "The event was successfully duplicated."
|
||||||
msgstr "L'événement a été marqué dupliqué avec succès."
|
msgstr "L'événement a été marqué dupliqué avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:896
|
#: agenda_culturel/views.py:904
|
||||||
msgid ""
|
msgid ""
|
||||||
"The event has been successfully flagged as a duplicate. The moderation team "
|
"The event has been successfully flagged as a duplicate. The moderation team "
|
||||||
"will deal with your suggestion shortly."
|
"will deal with your suggestion shortly."
|
||||||
@@ -757,35 +775,63 @@ msgstr ""
|
|||||||
"L'événement a été signalé comme dupliqué avec succès. Votre suggestion sera "
|
"L'événement a été signalé comme dupliqué avec succès. Votre suggestion sera "
|
||||||
"prochainement prise en charge par l'équipe de modération."
|
"prochainement prise en charge par l'équipe de modération."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:935
|
#: agenda_culturel/views.py:943
|
||||||
msgid "The categorisation rule has been successfully modified."
|
msgid "The categorisation rule has been successfully modified."
|
||||||
msgstr "La règle de catégorisation a été modifiée avec succès."
|
msgstr "La règle de catégorisation a été modifiée avec succès."
|
||||||
|
|
||||||
#: agenda_culturel/views.py:942
|
#: agenda_culturel/views.py:950
|
||||||
msgid "The categorisation rule has been successfully deleted."
|
msgid "The categorisation rule has been successfully deleted."
|
||||||
msgstr "La règle de catégorisation a été supprimée avec succès"
|
msgstr "La règle de catégorisation a été supprimée avec succès"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:962 agenda_culturel/views.py:991
|
#: agenda_culturel/views.py:970 agenda_culturel/views.py:999
|
||||||
msgid "The rules were successfully applied and 1 event was categorised."
|
msgid "The rules were successfully applied and 1 event was categorised."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les règles ont été appliquées avec succès et 1 événement a été catégorisé"
|
"Les règles ont été appliquées avec succès et 1 événement a été catégorisé"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:964 agenda_culturel/views.py:993
|
#: agenda_culturel/views.py:972 agenda_culturel/views.py:1001
|
||||||
msgid "The rules were successfully applied and {} events were categorised."
|
msgid "The rules were successfully applied and {} events were categorised."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les règles ont été appliquées avec succès et {} événements ont été "
|
"Les règles ont été appliquées avec succès et {} événements ont été "
|
||||||
"catégorisés"
|
"catégorisés"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:966 agenda_culturel/views.py:995
|
#: agenda_culturel/views.py:974 agenda_culturel/views.py:1003
|
||||||
msgid "The rules were successfully applied and no events were categorised."
|
msgid "The rules were successfully applied and no events were categorised."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les règles ont été appliquées avec succès et aucun événement n'a été "
|
"Les règles ont été appliquées avec succès et aucun événement n'a été "
|
||||||
"catégorisé"
|
"catégorisé"
|
||||||
|
|
||||||
#: agenda_culturel/views.py:1023
|
#: agenda_culturel/views.py:1031
|
||||||
msgid "The moderation question has been created with success."
|
msgid "The moderation question has been created with success."
|
||||||
msgstr "La question de modération a été créée avec succès."
|
msgstr "La question de modération a été créée avec succès."
|
||||||
|
|
||||||
|
#: agenda_culturel/views.py:1123 agenda_culturel/views.py:1178
|
||||||
|
msgid "{} events have been updated."
|
||||||
|
msgstr "{} événements ont été mis à jour."
|
||||||
|
|
||||||
|
#: agenda_culturel/views.py:1125 agenda_culturel/views.py:1180
|
||||||
|
msgid "1 event has been updated."
|
||||||
|
msgstr "1 événement a été mis à jour"
|
||||||
|
|
||||||
|
#: agenda_culturel/views.py:1127 agenda_culturel/views.py:1182
|
||||||
|
msgid "No events have been modified."
|
||||||
|
msgstr "Aucun événement n'a été modifié."
|
||||||
|
|
||||||
|
#: agenda_culturel/views.py:1135
|
||||||
|
msgid "The place has been successfully updated."
|
||||||
|
msgstr "Le lieu a été modifié avec succès."
|
||||||
|
|
||||||
|
#: agenda_culturel/views.py:1142
|
||||||
|
msgid "The place has been successfully created."
|
||||||
|
msgstr "Le lieu a été créé avec succès."
|
||||||
|
|
||||||
|
#: agenda_culturel/views.py:1201
|
||||||
|
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:1203
|
||||||
|
msgid "A new alias has been added to the selected place. "
|
||||||
|
msgstr "Un nouvel alias a été créé pour le lieu sélectionné. "
|
||||||
|
|
||||||
msgid "Recurrent import name"
|
msgid "Recurrent import name"
|
||||||
msgstr "Nome de l'import récurrent"
|
msgstr "Nome de l'import récurrent"
|
||||||
|
|
||||||
|
|||||||
19
src/agenda_culturel/migrations/0057_alter_place_aliases.py
Normal file
19
src/agenda_culturel/migrations/0057_alter_place_aliases.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 4.2.7 on 2024-04-27 07:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django_better_admin_arrayfield.models.fields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('agenda_culturel', '0056_place_alter_event_location_event_exact_location'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='place',
|
||||||
|
name='aliases',
|
||||||
|
field=django_better_admin_arrayfield.models.fields.ArrayField(base_field=models.CharField(max_length=512), blank=True, help_text='Alternative names or addresses used to match a place with the free-form location of an event.', null=True, size=None, verbose_name='Alternative names'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Generated by Django 4.2.7 on 2024-04-27 15:55
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('agenda_culturel', '0057_alter_place_aliases'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='place',
|
||||||
|
name='city',
|
||||||
|
field=models.CharField(default='', help_text='City name', verbose_name='City'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='place',
|
||||||
|
name='address',
|
||||||
|
field=models.CharField(help_text='Address of this place (without city name)', verbose_name='Address'),
|
||||||
|
),
|
||||||
|
]
|
||||||
23
src/agenda_culturel/migrations/0059_auto_20240427_1829.py
Normal file
23
src/agenda_culturel/migrations/0059_auto_20240427_1829.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 4.2.7 on 2024-04-27 16:29
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
from django.contrib.auth.management import create_permissions
|
||||||
|
from django.contrib.auth.models import Group, Permission
|
||||||
|
|
||||||
|
def update_groups_permissions(apps, schema_editor):
|
||||||
|
|
||||||
|
all_perms = Permission.objects.all()
|
||||||
|
|
||||||
|
# set permissions for moderators
|
||||||
|
moderator_perms = [i for i in all_perms if i.content_type.app_label == 'agenda_culturel' and i.content_type.model in ['place']]
|
||||||
|
Group.objects.get(name="Moderator").permissions.add(*moderator_perms)
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('agenda_culturel', '0058_place_city_alter_place_address'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(update_groups_permissions),
|
||||||
|
]
|
||||||
@@ -160,8 +160,9 @@ class DuplicatedEvents(models.Model):
|
|||||||
|
|
||||||
class Place(models.Model):
|
class Place(models.Model):
|
||||||
name = models.CharField(verbose_name=_('Name'), help_text=_('Name of the place'))
|
name = models.CharField(verbose_name=_('Name'), help_text=_('Name of the place'))
|
||||||
address = models.CharField(verbose_name=_('Address'), help_text=_('Address of this place'))
|
address = models.CharField(verbose_name=_('Address'), help_text=_('Address of this place (without city name)'))
|
||||||
location = PlainLocationField(based_fields=['name', 'address'], zoom=12)
|
city = models.CharField(verbose_name=_('City'), help_text=_('City name'))
|
||||||
|
location = PlainLocationField(based_fields=['name', 'address', 'city'], zoom=12)
|
||||||
|
|
||||||
aliases = ArrayField(models.CharField(max_length=512), verbose_name=_('Alternative names'), help_text=_("Alternative names or addresses used to match a place with the free-form location of an event."), blank=True, null=True)
|
aliases = ArrayField(models.CharField(max_length=512), verbose_name=_('Alternative names'), help_text=_("Alternative names or addresses used to match a place with the free-form location of an event."), blank=True, null=True)
|
||||||
|
|
||||||
@@ -175,6 +176,11 @@ class Place(models.Model):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("view_place", kwargs={"pk": self.pk})
|
return reverse("view_place", kwargs={"pk": self.pk})
|
||||||
|
|
||||||
|
def nb_events(self):
|
||||||
|
return Event.objects.filter(exact_location=self).count()
|
||||||
|
|
||||||
|
def match(self, event):
|
||||||
|
return event.location in self.aliases
|
||||||
|
|
||||||
|
|
||||||
class Event(models.Model):
|
class Event(models.Model):
|
||||||
@@ -396,9 +402,16 @@ class Event(models.Model):
|
|||||||
if self.image and not self.local_image:
|
if self.image and not self.local_image:
|
||||||
self.download_image()
|
self.download_image()
|
||||||
|
|
||||||
# try to detect category
|
|
||||||
if self.is_in_importation_process():
|
if self.is_in_importation_process():
|
||||||
|
# try to detect category
|
||||||
CategorisationRule.apply_rules(self)
|
CategorisationRule.apply_rules(self)
|
||||||
|
# try to detect location
|
||||||
|
if not self.exact_location:
|
||||||
|
for p in Place.objects.all():
|
||||||
|
if p.match(self):
|
||||||
|
logger.warning("Found a place for an imported event: " + p.name)
|
||||||
|
self.exact_location = p
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
|||||||
@@ -308,6 +308,10 @@ header .title {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
article form label {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
article#filters {
|
article#filters {
|
||||||
.buttons-filter {
|
.buttons-filter {
|
||||||
float: right;
|
float: right;
|
||||||
@@ -839,3 +843,11 @@ table .buttons {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.missing-data {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters #id_city {
|
||||||
|
columns: 4;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
{% if event.exact_location %}
|
||||||
|
{% if nolink %}
|
||||||
|
{{ event.exact_location.name }}, {{ event.exact_location.city }}
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'view_place' event.exact_location.pk %}">{{ event.exact_location.name }}, {{ event.exact_location.city }}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if perms.agenda_culturel.change_event and perms.agenda_culturel.change_place %}
|
||||||
|
<a href="{% url 'add_place_to_event' event.pk %}" class="missing-data">{{ event.location }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ event.location }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
@@ -18,6 +18,9 @@
|
|||||||
{% for s in filter.get_status_names %}
|
{% for s in filter.get_status_names %}
|
||||||
{{ s }}
|
{{ s }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% for c in filter.get_cities %}
|
||||||
|
{{ c }}
|
||||||
|
{% endfor %}
|
||||||
{{ filter.get_recurrence_filtering }}
|
{{ filter.get_recurrence_filtering }}
|
||||||
{% else %}
|
{% else %}
|
||||||
Filtrer
|
Filtrer
|
||||||
|
|||||||
@@ -52,6 +52,9 @@
|
|||||||
{% if perms.agenda_culturel.change_duplicatedevents %}
|
{% if perms.agenda_culturel.change_duplicatedevents %}
|
||||||
{% show_badge_duplicated "bottom" %}
|
{% show_badge_duplicated "bottom" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if perms.agenda_culturel.change_place and perms.agenda_culturel.change_event %}
|
||||||
|
{% show_badge_unknown_places "bottom" %}
|
||||||
|
{% endif %}
|
||||||
{% if perms.agenda_culturel.view_contactmessage %}
|
{% if perms.agenda_culturel.view_contactmessage %}
|
||||||
{% show_badge_contactmessages "bottom" %}
|
{% show_badge_contactmessages "bottom" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -10,8 +10,16 @@
|
|||||||
<header>
|
<header>
|
||||||
<h1>Suppression du lieu {{ object.name }}</h1>
|
<h1>Suppression du lieu {{ object.name }}</h1>
|
||||||
</header>
|
</header>
|
||||||
<form method="post">{% csrf_token %}
|
{% with nb_events=object.nb_events %}
|
||||||
|
{% if nb_events > 0 %}
|
||||||
|
<p class="message warning"><strong>Attention :</strong> {{ nb_events }} événement{{ nb_events|pluralize }}
|
||||||
|
{% if nb_events > 1 %}sont enregistrés{% else %}est enregistré{% endif %} dans ce lieu.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
<p>Êtes-vous sûr·e de vouloir supprimer le lieu « {{ object.name }} ({{ object.pk }}) » situé à l'adresse {{ object.address }}, et de coordonnées {{ object.location }} ?</p>
|
<p>Êtes-vous sûr·e de vouloir supprimer le lieu « {{ object.name }} ({{ object.pk }}) » situé à l'adresse {{ object.address }}, et de coordonnées {{ object.location }} ?</p>
|
||||||
|
|
||||||
|
<form method="post">{% csrf_token %}
|
||||||
|
|
||||||
{{ form }}
|
{{ form }}
|
||||||
<div class="grid buttons">
|
<div class="grid buttons">
|
||||||
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{{ object.get_absolute_url }}{% endif %}" role="button" class="secondary">Annuler</a>
|
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{{ object.get_absolute_url }}{% endif %}" role="button" class="secondary">Annuler</a>
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
{% if perms.agenda_culturel.change_place %}
|
{% if perms.agenda_culturel.change_place %}
|
||||||
<a href="{% url 'view_places' %}" role="button">< Tous les lieux</a>
|
<a href="{% url 'view_places' %}" role="button">< Tous les lieux</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="slide-buttons">
|
|
||||||
{% if perms.agenda_culturel.change_place %}
|
{% if perms.agenda_culturel.change_place %}
|
||||||
|
<div class="slide-buttons">
|
||||||
<a href="{% url 'edit_place' place.pk %}" role="button">Modifier {% picto_from_name "edit-3" %}</a>
|
<a href="{% url 'edit_place' place.pk %}" role="button">Modifier {% picto_from_name "edit-3" %}</a>
|
||||||
<a href="{% url 'delete_place' place.pk %}" role="button">Supprimer {% picto_from_name "trash-2" %}</a>
|
<a href="{% url 'delete_place' place.pk %}" role="button">Supprimer {% picto_from_name "trash-2" %}</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -36,8 +36,13 @@
|
|||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div>
|
<div>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Adresse :</strong> {{ object.address }}</li>
|
<li><strong>Adresse :</strong> {{ object.address }}, {{ object.city }}</li>
|
||||||
<li><strong>Coordonnée GPS :</strong> <a href="geo:{{ object.location }}">{{ object.location }}</a></li>
|
<li><strong>Coordonnée GPS :</strong> <a href="geo:{{ object.location }}">{{ object.location }}</a></li>
|
||||||
|
{% if object.nb_events > 0 %}
|
||||||
|
<li><strong>Nombre d'événements :</strong> {{ object.nb_events }}</li>
|
||||||
|
{% else %}
|
||||||
|
<li><em>Aucun événement n'est enregistré dans ce lieu</em></li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
{% if object.aliases|length > 0 %}
|
{% if object.aliases|length > 0 %}
|
||||||
|
|||||||
@@ -18,13 +18,20 @@
|
|||||||
|
|
||||||
<h1>{% if form.instance.pk %}Modification{% else %}Création{% endif %} d'un lieu</h1>
|
<h1>{% if form.instance.pk %}Modification{% else %}Création{% endif %} d'un lieu</h1>
|
||||||
<article>
|
<article>
|
||||||
|
{% if event %}
|
||||||
|
<p>Création d'un lieu depuis l'événement « {{ event }} » (voir en bas de page le détail de l'événement).</p>
|
||||||
|
{% endif %}
|
||||||
<form method="post">{% csrf_token %}
|
<form method="post">{% csrf_token %}
|
||||||
{{ form.as_p }}
|
{{ form.as_grid }}
|
||||||
<div class="grid buttons">
|
<div class="grid buttons">
|
||||||
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{{ object.get_absolute_url }}{% endif %}" role="button" class="secondary">Annuler</a>
|
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{{ object.get_absolute_url }}{% endif %}" role="button" class="secondary">Annuler</a>
|
||||||
<input type="submit" value="Envoyer">
|
<input type="submit" value="Envoyer">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
{% if event %}
|
||||||
|
<h2>Description du lieu :</h2>
|
||||||
|
{% include "agenda_culturel/single-event/event-single-inc.html" with event=event noedit=1 %}
|
||||||
|
{% endif %}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -12,7 +12,10 @@
|
|||||||
<div class="grid two-columns">
|
<div class="grid two-columns">
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<a class="slide-buttons" href="{% url 'add_place' %}" role="button">Ajouter {% picto_from_name "plus-circle" %}</a>
|
<div class="slide-buttons">
|
||||||
|
<a href="{% url 'fix_unknown_places' %}" role="button" data-tooltip="Utiliser les alias des lieux pour les associer aux événements sans lieu">Détecter par alias {% picto_from_name "link" %}</a>
|
||||||
|
<a href="{% url 'add_place' %}" role="button">Ajouter {% picto_from_name "plus-circle" %}</a>
|
||||||
|
</div>
|
||||||
<h1>Lieux</h1>
|
<h1>Lieux</h1>
|
||||||
</header>
|
</header>
|
||||||
{% if object_list %}
|
{% if object_list %}
|
||||||
@@ -26,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h2>Lieu #{{ place.pk }} : {{ place.name }}</h2>
|
<h2>Lieu #{{ place.pk }} : {{ place.name }}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Adresse :</strong> {{ place.address }}</li>
|
<li><strong>Adresse :</strong> {{ place.address }}, {{ place.city }}</li>
|
||||||
<li><strong>Coordonnée GPS :</strong> {{ place.location }}</li>
|
<li><strong>Coordonnée GPS :</strong> {{ place.location }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% if place.aliases|length > 0 %}
|
{% if place.aliases|length > 0 %}
|
||||||
@@ -34,6 +37,11 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<p><em>Ce lieu n'a pas d'alias défini</em></p>
|
<p><em>Ce lieu n'a pas d'alias défini</em></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if place.nb_events > 0 %}
|
||||||
|
<p><strong>Nombre d'événements :</strong> {{ place.nb_events }}</p>
|
||||||
|
{% else %}
|
||||||
|
<p><em>Aucun événement n'est enregistré dans ce lieu</em></p>
|
||||||
|
{% endif %}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
{% extends "agenda_culturel/page.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block title %}Ajouter un lieu à {{ object.title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block entete_header %}
|
||||||
|
<script src="{% url 'jsi18n' %}"></script>
|
||||||
|
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
|
||||||
|
<script src="/static/admin/js/jquery.init.js"></script>
|
||||||
|
<script src="/static/admin/js/admin/DateTimeShortcuts.js"></script>
|
||||||
|
<script src="{% static 'recurrence/js/recurrence.js' %}"></script>
|
||||||
|
<script src="{% static 'recurrence/js/recurrence.js' %}"></script>
|
||||||
|
<script src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<script>window.CKEDITOR_BASEPATH = '/static/ckeditor/ckeditor/';</script>
|
||||||
|
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
|
||||||
|
<script src="/static/admin/js/jquery.init.js"></script>
|
||||||
|
<link href="{% static 'css/django_better_admin_arrayfield.min.css' %}" type="text/css" media="all" rel="stylesheet">
|
||||||
|
<script src="{% static 'js/django_better_admin_arrayfield.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/adjust_datetimes.js' %}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block fluid %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static_content_extra %}
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h1>Ajouter un lieu à {{ object.title }} ({{ object.start_day }})</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<p>Si le lieu est disponible dans la liste, veuillez le sélectionner.</p>
|
||||||
|
<form method="post">{% csrf_token %}
|
||||||
|
{{ form.media }}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<div class="grid buttons">
|
||||||
|
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{{ object.get_absolute_url }}{% endif %}" role="button" class="secondary">Annuler</a>
|
||||||
|
<input type="submit" value="Valider">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<h2>Description du lieu :</h2>
|
||||||
|
{% include "agenda_culturel/single-event/event-single-inc.html" with event=object noedit=1 %}
|
||||||
|
</article>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
{% extends "agenda_culturel/page.html" %}
|
||||||
|
{% load utils_extra %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block title %}Événements sans lieu{% endblock %}
|
||||||
|
|
||||||
|
{% load cat_extra %}
|
||||||
|
{% block entete_header %}
|
||||||
|
{% css_categories %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid two-columns">
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<div class="slide-buttons">
|
||||||
|
<a href="{% url 'fix_unknown_places' %}" role="button" data-tooltip="Utiliser les alias des lieux pour les associer aux événements sans lieu">Détecter par alias {% picto_from_name "link" %}</a>
|
||||||
|
</div>
|
||||||
|
<h1>Événements sans lieu</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{% for obj in object_list %}
|
||||||
|
<article>{% include "agenda_culturel/single-event/event-in-unknown-place-list-inc.html" with event=obj %}</article>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<span>
|
||||||
|
{% if page_obj.has_previous %}
|
||||||
|
<a href="?page=1" role="button">« premier</a>
|
||||||
|
<a href="?page={{ page_obj.previous_page_number }}" role="button">précédent</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<span>
|
||||||
|
Page {{ page_obj.number }} sur {{ page_obj.paginator.num_pages }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{% if page_obj.has_next %}
|
||||||
|
<a href="?page={{ page_obj.next_page_number }}" role="button">suivant</a>
|
||||||
|
<a href="?page={{ page_obj.paginator.num_pages }}" role="button">dernier »</a>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
{% include "agenda_culturel/side-nav.html" with current="unknown_places" %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -24,6 +24,9 @@
|
|||||||
{% if perms.agenda_culturel.change_place %}
|
{% if perms.agenda_culturel.change_place %}
|
||||||
<li><a {% if current == "places" %}class="selected" {% endif %}href="{% url 'view_places' %}">Liste des lieux</a></li>
|
<li><a {% if current == "places" %}class="selected" {% endif %}href="{% url 'view_places' %}">Liste des lieux</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if perms.agenda_culturel.change_place and perms.agenda_culturel.change_event %}
|
||||||
|
<li><a {% if current == "unknown_places" %}class="selected" {% endif %}href="{% url 'view_unknown_places' %}">Événements sans lieu</a>{% show_badge_unknown_places "left" %}</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
{% if perms.agenda_culturel.view_batchimportation or perms.agenda_culturel.view_recurrentimport or perms.agenda_culturel.view_categorisationrule%}
|
{% if perms.agenda_culturel.view_batchimportation or perms.agenda_culturel.view_recurrentimport or perms.agenda_culturel.view_categorisationrule%}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</header>
|
</header>
|
||||||
<p class="subentry-search"></p>
|
<p class="subentry-search"></p>
|
||||||
{% picto_from_name "map-pin" %}
|
{% picto_from_name "map-pin" %}
|
||||||
{% if event.location_hl %}{{ event.location_hl | safe }}{% else %}{{ event.location }}{% endif %}</p>
|
{% if event.location_hl %}{{ event.location_hl | safe }}{% else %}{% include "agenda_culturel/event-location-inc.html" with event=event %}{% endif %}</p>
|
||||||
{% if event.has_recurrences %}
|
{% if event.has_recurrences %}
|
||||||
<p class="subentry-search">
|
<p class="subentry-search">
|
||||||
{% picto_from_name "repeat" %}
|
{% picto_from_name "repeat" %}
|
||||||
|
|||||||
@@ -21,14 +21,14 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ event.category | small_cat_recurrent:event.has_recurrences }}
|
{{ event.category | small_cat_recurrent:event.has_recurrences }}
|
||||||
{% if event.location %}<hgroup>{% endif %}
|
{% if event.location or event.exact_location %}<hgroup>{% endif %}
|
||||||
<h3>
|
<h3>
|
||||||
{{ event|picto_status }}
|
{{ event|picto_status }}
|
||||||
<a href="{{ event.get_absolute_url }}">{{ event.title }}</a></h3>
|
<a href="{{ event.get_absolute_url }}">{{ event.title }}</a></h3>
|
||||||
{% if event.location %}
|
{% if event.location or event.exact_location %}
|
||||||
<h4>
|
<h4>
|
||||||
{% picto_from_name "map-pin" %}
|
{% picto_from_name "map-pin" %}
|
||||||
{{ event.location }}
|
{% include "agenda_culturel/event-location-inc.html" with event=event %}
|
||||||
</h4>
|
</h4>
|
||||||
</hgroup>
|
</hgroup>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
{% include "agenda_culturel/ephemeris-inc.html" with event=event filter=filter %}
|
{% include "agenda_culturel/ephemeris-inc.html" with event=event filter=filter %}
|
||||||
|
|
||||||
{{ event.category | small_cat_recurrent:event.has_recurrences }}
|
{{ event.category | small_cat_recurrent:event.has_recurrences }}
|
||||||
{% if event.location %}<hgroup>{% endif %}
|
{% if event.location or event.exact_location %}<hgroup>{% endif %}
|
||||||
<h2>
|
<h2>
|
||||||
{{ event|picto_status }}
|
{{ event|picto_status }}
|
||||||
<a href="{{ event.get_absolute_url }}">{{ event.title }}</a>
|
<a href="{{ event.get_absolute_url }}">{{ event.title }}</a>
|
||||||
</h2>
|
</h2>
|
||||||
{% if event.location %}
|
{% if event.location or event.exact_location %}
|
||||||
<h3>
|
<h3>
|
||||||
{% picto_from_name "map-pin" %}
|
{% picto_from_name "map-pin" %}
|
||||||
|
|
||||||
{{ event.location }}
|
{% include "agenda_culturel/event-location-inc.html" with event=event %}
|
||||||
</h3>
|
</h3>
|
||||||
</hgroup>
|
</hgroup>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
{% load utils_extra %}
|
||||||
|
{% load cat_extra %}
|
||||||
|
{% load event_extra %}
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div class="slide-buttons">
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="{% url 'add_place_to_event' event.pk %}" role="button">Ajouter le lieu {% picto_from_name "map-pin" %}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{ event.category | small_cat_recurrent:event.has_recurrences }}
|
||||||
|
{{ event|picto_status }}
|
||||||
|
<a href="{{ event.get_absolute_url }}">
|
||||||
|
{{ event.title }}</a></p>
|
||||||
|
{% picto_from_name "map-pin" %}
|
||||||
|
{% include "agenda_culturel/event-location-inc.html" with event=event %}
|
||||||
|
</header>
|
||||||
|
<p>{% picto_from_name "calendar" %}
|
||||||
|
{% if event.end_day and event.end_day != event.start_day %}du{% else %}le{% endif %}
|
||||||
|
{% include "agenda_culturel/date-times-inc.html" with event=event %}
|
||||||
|
{% if event.has_recurrences %}
|
||||||
|
<p>
|
||||||
|
{% picto_from_name "repeat" %}
|
||||||
|
<!-- TODO: see https://forge.chapril.org/jmtrivial/agenda_culturel/issues/65 -->
|
||||||
|
{% for r in event.recurrences.rrules %}
|
||||||
|
{{ r.to_text }}{% if not forloop.first %}, {% endif %}{% endfor %}, depuis le
|
||||||
|
{% if event.recurrences.dtstart.date %}
|
||||||
|
{{ event.recurrences.dtstart.date }}
|
||||||
|
{% else %}
|
||||||
|
{{ event.start_day }}
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
<p>
|
||||||
|
{% picto_from_name "tag" %}
|
||||||
|
{% for tag in event.tags %}
|
||||||
|
<a href="{% url 'view_tag' tag %}">{{ tag }}</a>
|
||||||
|
{% if not forloop.last %}, {% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
<div class="description">
|
||||||
|
{% if event.description %}{{ event.description |truncatewords:60 }}{% else %}<em>pas de description</em>{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
{% picto_from_name "map-pin" %}
|
{% picto_from_name "map-pin" %}
|
||||||
{{ event.location }}
|
{% include "agenda_culturel/event-location-inc.html" with event=event nolink=1 %}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{% picto_from_name "calendar" %}
|
{% picto_from_name "calendar" %}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{% picto_from_name "map-pin" %}
|
{% picto_from_name "map-pin" %}
|
||||||
{{ event.location }}
|
{% include "agenda_culturel/event-location-inc.html" with event=event %}
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1 @@
|
|||||||
<div class="grid">
|
|
||||||
<div>
|
|
||||||
{{field_input}}
|
{{field_input}}
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="map-widget" style="margin-top: 4px">
|
|
||||||
<label></label>
|
|
||||||
|
|
||||||
<div id="map_{{field_name}}" style="width: 100%; aspect-ratio: 16/9"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -51,6 +51,15 @@ def show_badges_events(placement="top"):
|
|||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def show_badge_unknown_places(placement="top"):
|
||||||
|
nb_unknown = Event.objects.filter(exact_location__isnull=True).count()
|
||||||
|
if nb_unknown != 0:
|
||||||
|
return mark_safe('<a href="' + reverse_lazy("view_unknown_places") + '" class="badge" data-placement="' + placement + '" data-tooltip="' + str(nb_unknown) + ' événement' + pluralize(nb_unknown) + ' sans lieu défini">' + picto_from_name("map-pin") + " " + str(nb_unknown) + '</a>')
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def event_field_verbose_name(the_field):
|
def event_field_verbose_name(the_field):
|
||||||
return Event._meta.get_field(the_field).verbose_name
|
return Event._meta.get_field(the_field).verbose_name
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ urlpatterns = [
|
|||||||
path("place/<int:pk>/delete", PlaceDeleteView.as_view(), name="delete_place"),
|
path("place/<int:pk>/delete", PlaceDeleteView.as_view(), name="delete_place"),
|
||||||
path("places/", PlaceListView.as_view(), name="view_places"),
|
path("places/", PlaceListView.as_view(), name="view_places"),
|
||||||
path("places/add", PlaceCreateView.as_view(), name="add_place"),
|
path("places/add", PlaceCreateView.as_view(), name="add_place"),
|
||||||
|
path("places/add/<int:pk>", PlaceFromEventCreateView.as_view(), name="add_place_from_event"),
|
||||||
|
path("events/unknown-places", UnknownPlacesListView.as_view(), name="view_unknown_places"),
|
||||||
|
path("events/unknown-places/fix", fix_unknown_places, name="fix_unknown_places"),
|
||||||
|
path("event/<int:pk>/addplace", UnknownPlaceAddView.as_view(), name="add_place_to_event"),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from django.urls import reverse
|
|||||||
import urllib
|
import urllib
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
|
||||||
from .forms import EventSubmissionForm, EventForm, BatchImportationForm, FixDuplicates, SelectEventInList, MergeDuplicates, RecurrentImportForm, CategorisationRuleImportForm, ModerationQuestionForm, ModerationAnswerForm, ModerateForm, CategorisationForm
|
from .forms import EventSubmissionForm, EventForm, BatchImportationForm, FixDuplicates, SelectEventInList, MergeDuplicates, RecurrentImportForm, CategorisationRuleImportForm, ModerationQuestionForm, ModerationAnswerForm, ModerateForm, CategorisationForm, EventAddPlaceForm, PlaceForm
|
||||||
|
|
||||||
from .models import Event, Category, StaticContent, ContactMessage, BatchImportation, DuplicatedEvents, RecurrentImport, CategorisationRule, remove_accents, ModerationQuestion, ModerationAnswer, Place
|
from .models import Event, Category, StaticContent, ContactMessage, BatchImportation, DuplicatedEvents, RecurrentImport, CategorisationRule, remove_accents, ModerationQuestion, ModerationAnswer, Place
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
@@ -94,6 +94,11 @@ class EventFilter(django_filters.FilterSet):
|
|||||||
queryset=Category.objects.all(),
|
queryset=Category.objects.all(),
|
||||||
widget=CategoryCheckboxSelectMultiple)
|
widget=CategoryCheckboxSelectMultiple)
|
||||||
|
|
||||||
|
city = django_filters.MultipleChoiceFilter(label="Filtrer par ville",
|
||||||
|
field_name='exact_location__city',
|
||||||
|
choices=[(p["city"], p["city"]) for p in Place.objects.values("city").distinct().order_by("city")],
|
||||||
|
widget=forms.CheckboxSelectMultiple)
|
||||||
|
|
||||||
status = django_filters.MultipleChoiceFilter(label="Filtrer par status",
|
status = django_filters.MultipleChoiceFilter(label="Filtrer par status",
|
||||||
choices=Event.STATUS.choices,
|
choices=Event.STATUS.choices,
|
||||||
field_name="status",
|
field_name="status",
|
||||||
@@ -102,7 +107,7 @@ class EventFilter(django_filters.FilterSet):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Event
|
model = Event
|
||||||
fields = ["category", "tags", "exclude_tags", "status", "recurrences"]
|
fields = ["category", "city", "tags", "exclude_tags", "status", "recurrences"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@@ -136,6 +141,9 @@ class EventFilter(django_filters.FilterSet):
|
|||||||
def get_status(self):
|
def get_status(self):
|
||||||
return self.form.cleaned_data["status"]
|
return self.form.cleaned_data["status"]
|
||||||
|
|
||||||
|
def get_cities(self):
|
||||||
|
return self.form.cleaned_data["city"]
|
||||||
|
|
||||||
def get_status_names(self):
|
def get_status_names(self):
|
||||||
if "status" in self.form.cleaned_data:
|
if "status" in self.form.cleaned_data:
|
||||||
return [dict(Event.STATUS.choices)[s] for s in self.form.cleaned_data["status"]]
|
return [dict(Event.STATUS.choices)[s] for s in self.form.cleaned_data["status"]]
|
||||||
@@ -158,7 +166,7 @@ class EventFilter(django_filters.FilterSet):
|
|||||||
else:
|
else:
|
||||||
if "status" in self.form.cleaned_data and len(self.form.cleaned_data["status"]) != 0:
|
if "status" in self.form.cleaned_data and len(self.form.cleaned_data["status"]) != 0:
|
||||||
return True
|
return True
|
||||||
return len(self.form.cleaned_data["category"]) != 0 or len(self.form.cleaned_data["tags"]) != 0 or len(self.form.cleaned_data["exclude_tags"]) != 0 or len(self.form.cleaned_data["recurrences"]) != 0
|
return len(self.form.cleaned_data["category"]) != 0 or len(self.form.cleaned_data["tags"]) != 0 or len(self.form.cleaned_data["exclude_tags"]) != 0 or len(self.form.cleaned_data["recurrences"]) != 0 or len(self.form.cleaned_data["city"]) != 0
|
||||||
|
|
||||||
def is_selected(self, cat):
|
def is_selected(self, cat):
|
||||||
return cat in self.form.cleaned_data["category"]
|
return cat in self.form.cleaned_data["category"]
|
||||||
@@ -1081,22 +1089,138 @@ class ModerationAnswerDeleteView(PermissionRequiredMixin, DeleteView):
|
|||||||
|
|
||||||
class PlaceListView(ListView):
|
class PlaceListView(ListView):
|
||||||
model = Place
|
model = Place
|
||||||
|
paginate_by = 10
|
||||||
|
ordering = ['-pk']
|
||||||
|
|
||||||
class PlaceDetailView(PermissionRequiredMixin, DetailView):
|
|
||||||
model = Place
|
|
||||||
permission_required = ("agenda_culturel.view_place")
|
|
||||||
|
|
||||||
class PlaceUpdateView(PermissionRequiredMixin, UpdateView):
|
class PlaceDetailView(DetailView):
|
||||||
|
model = Place
|
||||||
|
|
||||||
|
class UpdatePlaces:
|
||||||
|
def form_valid(self, form):
|
||||||
|
result = super().form_valid(form)
|
||||||
|
p = form.instance
|
||||||
|
|
||||||
|
if not hasattr(self, "nb_applied"):
|
||||||
|
self.nb_applied = 0
|
||||||
|
|
||||||
|
# if required, find all matching events
|
||||||
|
if form.apply():
|
||||||
|
u_events = Event.objects.filter(exact_location__isnull=True)
|
||||||
|
|
||||||
|
to_be_updated = []
|
||||||
|
# try to find matches
|
||||||
|
for ue in u_events:
|
||||||
|
if p.match(ue):
|
||||||
|
ue.exact_location = p
|
||||||
|
to_be_updated.append(ue)
|
||||||
|
continue
|
||||||
|
# update events with a location
|
||||||
|
Event.objects.bulk_update(to_be_updated, fields=["exact_location"])
|
||||||
|
self.nb_applied += len(to_be_updated)
|
||||||
|
|
||||||
|
if self.nb_applied > 1:
|
||||||
|
messages.success(self.request, _("{} events have been updated.").format(self.nb_applied))
|
||||||
|
elif self.nb_applied == 1:
|
||||||
|
messages.success(self.request, _("1 event has been updated."))
|
||||||
|
else:
|
||||||
|
messages.info(self.request, _("No events have been modified."))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class PlaceUpdateView(UpdatePlaces, PermissionRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||||
model = Place
|
model = Place
|
||||||
fields = '__all__'
|
|
||||||
permission_required = ("agenda_culturel.change_place")
|
permission_required = ("agenda_culturel.change_place")
|
||||||
|
success_message = _('The place has been successfully updated.')
|
||||||
|
form_class = PlaceForm
|
||||||
|
|
||||||
class PlaceCreateView(PermissionRequiredMixin, SuccessMessageMixin, CreateView):
|
|
||||||
|
class PlaceCreateView(UpdatePlaces, PermissionRequiredMixin, SuccessMessageMixin, CreateView):
|
||||||
model = Place
|
model = Place
|
||||||
permission_required = ("agenda_culturel.add_place")
|
permission_required = ("agenda_culturel.add_place")
|
||||||
|
success_message = _('The place has been successfully created.')
|
||||||
|
form_class = PlaceForm
|
||||||
|
|
||||||
|
|
||||||
class PlaceDeleteView(PermissionRequiredMixin, DeleteView):
|
class PlaceDeleteView(PermissionRequiredMixin, DeleteView):
|
||||||
model = Place
|
model = Place
|
||||||
permission_required = ("agenda_culturel.delete_place")
|
permission_required = ("agenda_culturel.delete_place")
|
||||||
|
success_url = reverse_lazy('view_places')
|
||||||
|
|
||||||
|
class UnknownPlacesListView(PermissionRequiredMixin, ListView):
|
||||||
|
model = Event
|
||||||
|
permission_required = ("agenda_culturel.add_place")
|
||||||
|
paginate_by = 10
|
||||||
|
template_name = 'agenda_culturel/place_unknown_list.html'
|
||||||
|
queryset = Event.objects.filter(exact_location__isnull=True)
|
||||||
|
|
||||||
|
def fix_unknown_places(request):
|
||||||
|
# get all places
|
||||||
|
places = Place.objects.all()
|
||||||
|
# get all events without exact location
|
||||||
|
u_events = Event.objects.filter(exact_location__isnull=True)
|
||||||
|
|
||||||
|
to_be_updated = []
|
||||||
|
# try to find matches
|
||||||
|
for ue in u_events:
|
||||||
|
for p in places:
|
||||||
|
if p.match(ue):
|
||||||
|
ue.exact_location = p
|
||||||
|
to_be_updated.append(ue)
|
||||||
|
continue
|
||||||
|
# update events with a location
|
||||||
|
Event.objects.bulk_update(to_be_updated, fields=["exact_location"])
|
||||||
|
|
||||||
|
# create a success message
|
||||||
|
nb = len(to_be_updated)
|
||||||
|
if nb > 1:
|
||||||
|
messages.success(request, _("{} events have been updated.").format(nb))
|
||||||
|
elif nb == 1:
|
||||||
|
messages.success(request, _("1 event has been updated."))
|
||||||
|
else:
|
||||||
|
messages.info(request, _("No events have been modified."))
|
||||||
|
|
||||||
|
# come back to the list of places
|
||||||
|
return HttpResponseRedirect(reverse_lazy("view_unknown_places"))
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownPlaceAddView(PermissionRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||||
|
model = Event
|
||||||
|
permission_required = ("agenda_culturel.change_place", "agenda_culturel.change_event")
|
||||||
|
form_class = EventAddPlaceForm
|
||||||
|
template_name = 'agenda_culturel/place_unknown_form.html'
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
self.modified_event = form.modified_event()
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def get_success_message(self, cleaned_data):
|
||||||
|
msg = ""
|
||||||
|
if cleaned_data.get("place"):
|
||||||
|
msg += _('The selected place has been assigned to the event. ')
|
||||||
|
if cleaned_data.get('add_alias'):
|
||||||
|
msg += _('A new alias has been added to the selected place. ')
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
if self.modified_event:
|
||||||
|
return reverse_lazy('view_unknown_places')
|
||||||
|
else:
|
||||||
|
return reverse_lazy('add_place_from_event', args=[self.object.pk])
|
||||||
|
|
||||||
|
|
||||||
|
class PlaceFromEventCreateView(PlaceCreateView):
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["event"] = self.event
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_initial(self, *args, **kwargs):
|
||||||
|
initial = super().get_initial(**kwargs)
|
||||||
|
self.event = get_object_or_404(Event, pk=self.kwargs['pk'])
|
||||||
|
if self.event.location:
|
||||||
|
initial['aliases'] = [self.event.location]
|
||||||
|
return initial
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user