diff --git a/src/agenda_culturel/migrations/0099_update_categories.py b/src/agenda_culturel/migrations/0099_update_categories.py new file mode 100644 index 0000000..601df35 --- /dev/null +++ b/src/agenda_culturel/migrations/0099_update_categories.py @@ -0,0 +1,208 @@ +# Generated by Django 4.2.9 on 2024-11-01 14:22 + +from django.db import migrations +import os.path + +class SimpleCat: + def __init__(self=None, + name=None, color=None, + pictogram=None, position=None, + transfered_to=None, + transtag=None): + self.name = name + self.color = color + self.pictogram = pictogram + self.position = position + self.transfered_to = transfered_to + self.transfered_to_object = {} + self.transtag = transtag + + def get_transfered_category(self, e): + # we check if the given event has a corresponding tag (except empty string) + if not e is None: + for t, c in self.transfered_to.items(): + if t != "" and t in e.tags: + return c + + return self.transfered_to[""] if "" in self.transfered_to else None + + def get_transfered_to_object(self, apps, e=None): + if self.transfered_to is None: + return None, None + Category = apps.get_model("agenda_culturel", "Category") + + if isinstance(self.transfered_to, dict): + cname = self.get_transfered_category(e) + else: + cname = self.transfered_to + + if not cname in self.transfered_to_object.keys(): + self.transfered_to_object[cname] = Category.objects.filter(name=cname).first() + + return self.transfered_to_object[cname], self.transtag + + def get_pictogram_file(self): + from django.core.files import File + f = open(os.path.dirname(__file__) + "/images/" + self.pictogram, "rb") + return File(name=self.pictogram, file=f) + +# Color selection +# https://colorkit.co/color-palette-generator/4cae4f-ff9900-2094f3-9b27b0-ffec3d-ff5724-795649-4051b5-009485/ +# #4cae4f, #ff9900, #2094f3, #9b27b0, #ffec3d, #ff5724, #795649, #4051b5, #009485 + +preserved = { + "Nature": { + "old": SimpleCat("Nature", color="#27AEEF", pictogram="leaf.svg", position=8), + "new": SimpleCat("Nature", color="#4cae4f", pictogram="leaf.svg", position=8) + }, + "Cinéma": { + "old": SimpleCat("Cinéma", color="#EDE15B", pictogram="theater.svg", position=5), + "new": SimpleCat("Cinéma", color="#ff9900", pictogram="theater.svg", position=4), + }, + "Sans catégorie": { + "old": SimpleCat("Sans catégorie", color="#AAAAAA", pictogram="calendar.svg", position=100), + "new": SimpleCat("Sans catégorie", color="#AAAAAA", pictogram="calendar.svg", position=100), + } +} + + +old_cats = [ + SimpleCat("Conférence", "#87BC45", "school-outline.svg", 7, "Rencontres & Débats", "conférence"), + SimpleCat("Exposition", "#BDCF32", "warehouse.svg", 6, "Visites & Expositions", "exposition"), + SimpleCat("Arts du spectacle", "#EDBF33", "track-light.svg", 4, "Spectacles"), + SimpleCat("Danse", "#EF9B20", "dance-ballroom.svg", 3, "Spectacles", "danse"), + SimpleCat("Concert", "#F46A9B", "account-music-outline.svg", 2, "Fêtes & Concerts", "concert"), + SimpleCat("Théâtre", "#EA5545", "drama-masks.svg", 1, "Spectacles", "théâtre") +] + +new_cats = [ + SimpleCat("Fêtes & Concerts", "#ff5724", "party-popper.svg", 1, {"concert": "Concert", "": "Sans catégorie"}), + SimpleCat("Spectacles", "#edbf33", "track-light.svg", 2, {"théâtre": "Théâtre", "danse": "Danse", "": "Arts du spectacle"}), + SimpleCat("Rencontres & Débats", "#9b27b0", "workshop.svg", 3, {"conférence": "Conférence", "": "Sans catégorie"}), + SimpleCat("Animations & Ateliers", "#4051b5", "tools.svg", 5, "Sans catégorie"), + SimpleCat("Rendez-vous locaux", "#2094f3", "ferris-wheel.svg", 6, "Sans catégorie"), + SimpleCat("Visites & Expositions", "#795649", "compass-outline.svg", 7, {"exposition": "Exposition", "": "Sans catégorie"}), +] + +def create_categories(apps, catlist): + Category = apps.get_model("agenda_culturel", "Category") + + cats = [Category(name=c.name, color=c.color, position=c.position, pictogram=c.get_pictogram_file()) for c in catlist] + + Category.objects.bulk_create(cats) + + + +def delete_categories(apps, catlist): + Category = apps.get_model("agenda_culturel", "Category") + Category.objects.filter(name__in=[c.name for c in catlist]).delete() + +def create_new_categories(apps, schema_editor): + create_categories(apps, new_cats) + +def delete_new_categories(apps, schema_editor): + delete_categories(apps, new_cats) + +def create_old_categories(apps, schema_editor): + create_categories(apps, old_cats) + +def delete_old_categories(apps, schema_editor): + delete_categories(apps, old_cats) + + + +def update_preserved_categories(apps, dest): + other = "old" if dest == "new" else "new" + Category = apps.get_model("agenda_culturel", "Category") + + cats = Category.objects.filter(name__in=preserved.keys()) + ucats = [] + for c in cats: + c.color = preserved[c.name][dest].color + c.position = preserved[c.name][dest].position + if preserved[c.name][dest].pictogram != preserved[c.name][other].pictogram: + c.pictogram = preserved[c.name][dest].get_pictogram_file() + ucats.append(c) + + Category.objects.bulk_update(ucats, fields=["color", "position", "pictogram"]) + +def update_preserved_categories_new(apps, schema_editor): + update_preserved_categories(apps, "new") + +def update_preserved_categories_old(apps, schema_editor): + update_preserved_categories(apps, "old") + + +def update_database(apps, cats): + convert = dict([(c.name, c) for c in cats]) + + # update events + Event = apps.get_model("agenda_culturel", "Event") + events = Event.objects.all() + uevents = [] + for e in events: + if e.category and e.category.name in convert.keys(): + cat, tag = convert[e.category.name].get_transfered_to_object(apps, e) + e.category = cat + if not tag is None: + if e.tags is None: + e.tags = [tag] + else: + if not tag in e.tags: + e.tags.append(tag) + uevents.append(e) + Event.objects.bulk_update(uevents, fields=["category", "tags"]) + + # update categorisation rules + CategorisationRule = apps.get_model("agenda_culturel", "CategorisationRule") + crules = CategorisationRule.objects.all() + ucrules = [] + for r in crules: + if r.category and r.category.name in convert.keys(): + r.category, tag = convert[r.category.name].get_transfered_to_object(apps) + ucrules.append(r) + CategorisationRule.objects.bulk_update(ucrules, fields=["category"]) + + # update recurrent import + RecurrentImport = apps.get_model("agenda_culturel", "RecurrentImport") + rimports = RecurrentImport.objects.all() + urimports = [] + for ri in rimports: + if ri.defaultCategory and ri.defaultCategory.name in convert.keys(): + ri.defaultCategory, tag = convert[ri.defaultCategory.name].get_transfered_to_object(apps) + urimports.append(ri) + RecurrentImport.objects.bulk_update(urimports, fields=["defaultCategory"]) + + +def update_database_new(apps, schema_editor): + update_database(apps, old_cats) + +def update_database_old(apps, schema_editor): + update_database(apps, new_cats) + +def add_tags(apps, schema_editor): + Tag = apps.get_model("agenda_culturel", "Tag") + + new_tags = ["cinéma", "théâtre", "concert", "conférence", "exposition"] + + new_tags = [Tag(name=t, description="", principal=True) for t in new_tags if Tag.objects.filter(name=t).count() == 0] + + Tag.objects.bulk_create(new_tags) + +def do_nothing(apps, schema_editor): + pass + +class Migration(migrations.Migration): + + dependencies = [ + ('agenda_culturel', '0098_remove_category_alt_name_remove_category_codename'), + ] + + operations = [ + migrations.RunPython(create_new_categories, reverse_code=delete_new_categories), + migrations.RunPython(update_preserved_categories_new, reverse_code=update_preserved_categories_old), + migrations.RunPython(update_database_new, reverse_code=update_database_old), + migrations.RunPython(delete_old_categories, reverse_code=create_old_categories), + migrations.RunPython(add_tags, reverse_code=do_nothing) + ] + diff --git a/src/agenda_culturel/migrations/images/account-music-outline.svg b/src/agenda_culturel/migrations/images/account-music-outline.svg new file mode 100644 index 0000000..234f360 --- /dev/null +++ b/src/agenda_culturel/migrations/images/account-music-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/calendar.svg b/src/agenda_culturel/migrations/images/calendar.svg new file mode 100644 index 0000000..002fbf7 --- /dev/null +++ b/src/agenda_culturel/migrations/images/calendar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/compass-outline.svg b/src/agenda_culturel/migrations/images/compass-outline.svg new file mode 100644 index 0000000..1ed99c4 --- /dev/null +++ b/src/agenda_culturel/migrations/images/compass-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/dance-ballroom.svg b/src/agenda_culturel/migrations/images/dance-ballroom.svg new file mode 100644 index 0000000..09c4fdc --- /dev/null +++ b/src/agenda_culturel/migrations/images/dance-ballroom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/drama-masks.svg b/src/agenda_culturel/migrations/images/drama-masks.svg new file mode 100644 index 0000000..e278941 --- /dev/null +++ b/src/agenda_culturel/migrations/images/drama-masks.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/ferris-wheel.svg b/src/agenda_culturel/migrations/images/ferris-wheel.svg new file mode 100644 index 0000000..00d4d32 --- /dev/null +++ b/src/agenda_culturel/migrations/images/ferris-wheel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/leaf.svg b/src/agenda_culturel/migrations/images/leaf.svg new file mode 100644 index 0000000..f605060 --- /dev/null +++ b/src/agenda_culturel/migrations/images/leaf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/party-popper.svg b/src/agenda_culturel/migrations/images/party-popper.svg new file mode 100644 index 0000000..4ad1672 --- /dev/null +++ b/src/agenda_culturel/migrations/images/party-popper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/school-outline.svg b/src/agenda_culturel/migrations/images/school-outline.svg new file mode 100644 index 0000000..5caeb47 --- /dev/null +++ b/src/agenda_culturel/migrations/images/school-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/theater.svg b/src/agenda_culturel/migrations/images/theater.svg new file mode 100644 index 0000000..85c7781 --- /dev/null +++ b/src/agenda_culturel/migrations/images/theater.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/tools.svg b/src/agenda_culturel/migrations/images/tools.svg new file mode 100644 index 0000000..e83473e --- /dev/null +++ b/src/agenda_culturel/migrations/images/tools.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/track-light.svg b/src/agenda_culturel/migrations/images/track-light.svg new file mode 100644 index 0000000..9827c0f --- /dev/null +++ b/src/agenda_culturel/migrations/images/track-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/warehouse.svg b/src/agenda_culturel/migrations/images/warehouse.svg new file mode 100644 index 0000000..8d4e223 --- /dev/null +++ b/src/agenda_culturel/migrations/images/warehouse.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/migrations/images/workshop.svg b/src/agenda_culturel/migrations/images/workshop.svg new file mode 100644 index 0000000..3d02d00 --- /dev/null +++ b/src/agenda_culturel/migrations/images/workshop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/agenda_culturel/templates/agenda_culturel/tag.html b/src/agenda_culturel/templates/agenda_culturel/tag.html index 15158f4..6e48a98 100644 --- a/src/agenda_culturel/templates/agenda_culturel/tag.html +++ b/src/agenda_culturel/templates/agenda_culturel/tag.html @@ -32,13 +32,23 @@

Les événements {{ tag }}

+ {% if object %}

{{ object.description|safe }}

{% endif %} +{% include 'agenda_culturel/paginator.html' %} + -{% for event in events %} -{% include "agenda_culturel/single-event/event-elegant-inc.html" with event=event day=0 %} +{% for event in paginator_filter %} + {% include "agenda_culturel/single-event/event-elegant-inc.html" with event=event day=0 %} {% endfor %} + +
+ +
+ {% endblock %} \ No newline at end of file diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 52e6085..010b46f 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -2095,11 +2095,25 @@ class TagDeleteView(PermissionRequiredMixin, DeleteView): def view_tag(request, t): - events = Event.objects.filter(tags__contains=[t]).order_by( - "start_day", "start_time" + + paginator = Paginator( + Event.objects.filter(tags__contains=[t]).order_by( + "start_day", "start_time"), + 10, ) + page = request.GET.get("page") + + try: + response = paginator.page(page) + except PageNotAnInteger: + response = paginator.page(1) + except EmptyPage: + response = paginator.page(paginator.num_pages) + + + tag = Tag.objects.filter(name=t).first() - context = {"tag": t, "events": events, "object": tag} + context = {"tag": t, "paginator_filter": response, "object": tag} return render(request, "agenda_culturel/tag.html", context)