Ajout des tags au formulaire de soumission

Fix #158
This commit is contained in:
Jean-Marie Favreau 2024-11-15 00:52:11 +01:00
parent 0ae9c399dd
commit 4af14c523c
7 changed files with 121 additions and 37 deletions

View File

@ -288,7 +288,7 @@ def weekly_imports(self):
run_recurrent_imports_from_list([imp.pk for imp in imports]) run_recurrent_imports_from_list([imp.pk for imp in imports])
@app.task(base=ChromiumTask, bind=True) @app.task(base=ChromiumTask, bind=True)
def import_events_from_url(self, url, cat, force=False): def import_events_from_url(self, url, cat, tags, force=False):
from .db_importer import DBImporterEvents from .db_importer import DBImporterEvents
from agenda_culturel.models import RecurrentImport, BatchImportation from agenda_culturel.models import RecurrentImport, BatchImportation
from agenda_culturel.models import Event, Category from agenda_culturel.models import Event, Category
@ -322,7 +322,7 @@ def import_events_from_url(self, url, cat, force=False):
# set default values # set default values
values = {} values = {}
if cat is not None: if cat is not None:
values = {"category": cat} values = {"category": cat, "tags": tags}
# get event # get event
events = u2e.process( events = u2e.process(
@ -351,13 +351,14 @@ def import_events_from_url(self, url, cat, force=False):
@app.task(base=ChromiumTask, bind=True) @app.task(base=ChromiumTask, bind=True)
def import_events_from_urls(self, urls_and_cats): def import_events_from_urls(self, urls_cat_tags):
for ucat in urls_and_cats: for ucat in urls_cat_tags:
if ucat is not None: if ucat is not None:
url = ucat[0] url = ucat[0]
cat = ucat[1] cat = ucat[1]
tags = ucat[2]
import_events_from_url.delay(url, cat) import_events_from_url.delay(url, cat, tags)
app.conf.beat_schedule = { app.conf.beat_schedule = {

View File

@ -22,6 +22,7 @@ from .models import (
CategorisationRule, CategorisationRule,
Place, Place,
Category, Category,
Tag
) )
from django.conf import settings from django.conf import settings
from django.core.files import File from django.core.files import File
@ -48,6 +49,18 @@ class URLSubmissionForm(Form):
help_text=_('Optional. If you don''t specify a category, we''ll find it for you.'), help_text=_('Optional. If you don''t specify a category, we''ll find it for you.'),
required=False, required=False,
) )
tags = MultipleChoiceField(
label=_("Tags"),
initial=None,
choices=[],
help_text=_('Specifying labels will help you find the event more easily'),
required=False
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["tags"].choices = Tag.get_tag_groups(all=True)

View File

@ -214,25 +214,26 @@ class Tag(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse("view_tag", kwargs={"t": self.name}) return reverse("view_tag", kwargs={"t": self.name})
def get_tag_groups(nb_suggestions=10, exclude=False, include=False): def get_tag_groups(nb_suggestions=10, exclude=False, include=False, all=False):
id_cache = 'all_tags ' + str(exclude) + ' ' + str(include) + ' ' + str(nb_suggestions) id_cache = 'all_tags ' + str(exclude) + ' ' + str(include) + ' ' + str(nb_suggestions)
result = cache.get(id_cache) result = cache.get(id_cache)
if not result: #
if not result:
free_tags = Event.get_all_tags(False) free_tags = Event.get_all_tags(False)
obj_tags = Tag.objects obj_tags = Tag.objects
try: if all:
obj_tags = obj_tags.filter(Q(in_excluded_suggestions=True)|Q(in_included_suggestions=True)|Q(principal=True))
else:
if exclude: if exclude:
obj_tags = obj_tags.filter(Q(in_excluded_suggestions=True)) obj_tags = obj_tags.filter(Q(in_excluded_suggestions=True))
if include: if include:
obj_tags = obj_tags.filter(Q(in_included_suggestions=True)|Q(principal=True)) obj_tags = obj_tags.filter(Q(in_included_suggestions=True)|Q(principal=True))
except FieldDoesNotExist:
pass if not exclude and not include:
obj_tags = obj_tags.filter(principal=True)
if not exclude and not include:
obj_tags = obj_tags.filter(principal=True)
obj_tags = obj_tags.values_list("name", flat=True) obj_tags = obj_tags.values_list("name", flat=True)
@ -254,6 +255,9 @@ class Tag(models.Model):
cache.set(id_cache, result, 300) # 5mn cache.set(id_cache, result, 300) # 5mn
return result return result
def __str__(self):
return self.name
class DuplicatedEvents(models.Model): class DuplicatedEvents(models.Model):

View File

@ -1284,17 +1284,15 @@ img.preview {
article { .stick-bottom {
.stick-bottom { background: var(--card-sectionning-background-color);
background: var(--card-sectionning-background-color); margin-right: calc(var(--block-spacing-horizontal) * -1);
margin-right: calc(var(--block-spacing-horizontal) * -1); margin-left: calc(var(--block-spacing-horizontal) * -1);
margin-left: calc(var(--block-spacing-horizontal) * -1); padding: calc(var(--block-spacing-vertical) * 0.66) var(--block-spacing-horizontal);
padding: calc(var(--block-spacing-vertical) * 0.66) var(--block-spacing-horizontal); margin-bottom: calc(var(--block-spacing-vertical) * -1);
margin-bottom: calc(var(--block-spacing-vertical) * -1); position: sticky;
position: sticky; bottom: 0;
bottom: 0; box-shadow: 0 -1px 0 rgba(115, 130, 140, 0.2);
box-shadow: 0 -1px 0 rgba(115, 130, 140, 0.2);
}
} }
/*#menu-rechercher, #menu-ajouter, #menu-configurer { /*#menu-rechercher, #menu-ajouter, #menu-configurer {

View File

@ -31,4 +31,35 @@
tout de même ajouter l'événement en le décrivant sur la page <a href="{% url 'add_event_details' %}" >d'ajout d'événement</a>.</p> tout de même ajouter l'événement en le décrivant sur la page <a href="{% url 'add_event_details' %}" >d'ajout d'événement</a>.</p>
</article> </article>
<script src="{% static 'choicejs/choices.min.js' %}"></script>
<script>
show_firstgroup = {
choice(classes, choice) {
const i = Choices.defaults.templates.choice.call(this, classes, choice);
if (this.first_group !== null && choice.groupId == this.first_group)
i.classList.add("visible");
return i;
},
choiceGroup(classes, group) {
const g = Choices.defaults.templates.choiceGroup.call(this, classes, group);
if (this.first_group === undefined && group.value == "Suggestions")
this.first_group = group.id;
if (this.first_group !== null && group.id == this.first_group)
g.classList.add("visible");
return g;
}
};
const tags = document.querySelector('#id_tags');
const choices_tags = new Choices(tags,
{
placeholderValue: 'Sélectionner les étiquettes à ajouter',
allowHTML: true,
delimiter: ',',
removeItemButton: true,
shouldSort: false,
callbackOnCreateTemplates: () => (show_firstgroup)
}
);
</script>
{% endblock %} {% endblock %}

View File

@ -18,27 +18,62 @@
{% url 'event_import_urls' as local_url %} {% url 'event_import_urls' as local_url %}
{% include "agenda_culturel/static_content.html" with name="import_set" url_path=local_url %} {% include "agenda_culturel/static_content.html" with name="import_set" url_path=local_url %}
</header> </header>
<p>Si l'import automatique ne marche pas, ou si l'événement n'est pas en ligne, vous pouvez
tout de même ajouter l'événement en le décrivant sur la page <a href="{% url 'add_event_details' %}" >d'ajout d'événement</a>.</p>
</article>
<form method="post"> <form method="post">
{{ formset.management_form }} {{ formset.management_form }}
{% csrf_token %} {% csrf_token %}
{% for form in formset %} {% for form in formset %}
<h2>Nouvel événement #{{ forloop.counter }}</h2> <article>
<header>
<h2>Nouvel événement #{{ forloop.counter }}</h2>
</header>
{{ form.as_p }} {{ form.as_p }}
</article>
{% endfor %} {% endfor %}
<div class="stick-bottom"> <div class="stick-bottom">
<input type="submit"value="Lancer l'import" id="import-button"> <input type="submit"value="Lancer l'import" id="import-button">
</div> </div>
</form> </form>
<footer>
<p>Si l'import automatique ne marche pas, ou si l'événement n'est pas en ligne, vous pouvez <script src="{% static 'choicejs/choices.min.js' %}"></script>
tout de même ajouter l'événement en le décrivant sur la page <a href="{% url 'add_event_details' %}" >d'ajout d'événement</a>.</p> <script>
</footer> show_firstgroup = {
</article> choice(classes, choice) {
<dialog id="modal-import"> const i = Choices.defaults.templates.choice.call(this, classes, choice);
<article aria-busy="true"> if (this.first_group !== null && choice.groupId == this.first_group)
Veuillez patienter, lien en cours d'importation... i.classList.add("visible");
</article> return i;
</dialog> },
choiceGroup(classes, group) {
const g = Choices.defaults.templates.choiceGroup.call(this, classes, group);
if (this.first_group === undefined && group.value == "Suggestions")
this.first_group = group.id;
if (this.first_group !== null && group.id == this.first_group)
g.classList.add("visible");
return g;
}
};
const tags = document.querySelectorAll("select[name$='-tags']");
Array.from(tags).forEach((element,index) => {
console.log(element);
const choices_tags = new Choices(element,
{
placeholderValue: 'Sélectionner les étiquettes à ajouter',
allowHTML: true,
delimiter: ',',
removeItemButton: true,
shouldSort: false,
callbackOnCreateTemplates: () => (show_firstgroup)
}
);
});
</script>
{% endblock %} {% endblock %}

View File

@ -695,6 +695,7 @@ class URLEventEvaluation:
self.is_authenticated = is_authenticated self.is_authenticated = is_authenticated
self.cat = None self.cat = None
self.tags = []
self.existing = None self.existing = None
self.url = form.cleaned_data.get('url') self.url = form.cleaned_data.get('url')
self.event = None self.event = None
@ -708,6 +709,7 @@ class URLEventEvaluation:
self.cat = form.cleaned_data.get('category') self.cat = form.cleaned_data.get('category')
if self.cat is not None: if self.cat is not None:
self.cat = self.cat.name self.cat = self.cat.name
self.tags = form.cleaned_data.get('tags')
else: else:
published = [ published = [
@ -745,7 +747,7 @@ class URLEventEvaluation:
def to_list(self): def to_list(self):
if self.is_new(): if self.is_new():
return (self.url, self.cat) return (self.url, self.cat, self.tags)
def import_from_urls(request): def import_from_urls(request):
@ -830,7 +832,7 @@ def import_from_url(request):
request, request,
_('Integrating {} into our import process.').format(uc.url) _('Integrating {} into our import process.').format(uc.url)
) )
import_events_from_url.delay(uc.url, uc.cat) import_events_from_url.delay(uc.url, uc.cat, uc.tags)
return HttpResponseRedirect(reverse("thank_you")) return HttpResponseRedirect(reverse("thank_you"))