Séparation des vues export

This commit is contained in:
SebF 2025-04-14 18:07:05 +02:00
parent 94950e148f
commit 0c7280f50e
4 changed files with 122 additions and 111 deletions

View File

@ -33,6 +33,9 @@ from .views import (
merge_duplicate, merge_duplicate,
set_duplicate, set_duplicate,
update_duplicate_event, update_duplicate_event,
# Export
export_event_ical,
export_ical,
# General pages # General pages
about, about,
activite, activite,
@ -102,11 +105,9 @@ from .views import (
month_view, month_view,
day_view, day_view,
upcoming_events, upcoming_events,
export_ical,
recent, recent,
administration, administration,
clear_cache, clear_cache,
export_event_ical,
EventDetailView, EventDetailView,
EventUpdateView, EventUpdateView,
StaticContentCreateView, StaticContentCreateView,
@ -187,6 +188,21 @@ urlpatterns = [
DuplicatedEventsDetailView.as_view(), DuplicatedEventsDetailView.as_view(),
name="view_duplicate", name="view_duplicate",
), ),
# Export
path(
"event/<int:year>/<int:month>/<int:day>/<int:pk>/ical",
export_event_ical,
name="export_event_ical",
),
path("cat:<cat>/ical", export_ical, name="export_ical_category"),
path("ical", export_ical, name="export_ical"),
path(
"organisme/<int:organisation_pk>/ical",
export_ical,
name="export_ical_organisation",
),
path("place/<int:place_pk>/ical", export_ical, name="export_ical_place"),
path("tag/<tag>/ical", export_ical, name="export_ical_tag"),
path("duplicates/", duplicates, name="duplicates"), path("duplicates/", duplicates, name="duplicates"),
path("duplicates/<int:pk>/fix", fix_duplicate, name="fix_duplicate"), path("duplicates/<int:pk>/fix", fix_duplicate, name="fix_duplicate"),
# General pages # General pages
@ -416,7 +432,6 @@ urlpatterns = [
name="a_venir_jour_category", name="a_venir_jour_category",
), ),
path("cat:<cat>/cette-semaine/", week_view, name="cette_semaine_category"), path("cat:<cat>/cette-semaine/", week_view, name="cette_semaine_category"),
path("cat:<cat>/ical", export_ical, name="export_ical_category"),
path("cat:<cat>/ce-mois-ci", month_view, name="ce_mois_ci_category"), path("cat:<cat>/ce-mois-ci", month_view, name="ce_mois_ci_category"),
path("semaine/<int:year>/<int:week>/", week_view, name="week_view"), path("semaine/<int:year>/<int:week>/", week_view, name="week_view"),
path("mois/<int:year>/<int:month>/", month_view, name="month_view"), path("mois/<int:year>/<int:month>/", month_view, name="month_view"),
@ -431,7 +446,6 @@ urlpatterns = [
), ),
path("cette-semaine/", week_view, name="cette_semaine"), path("cette-semaine/", week_view, name="cette_semaine"),
path("ce-mois-ci", month_view, name="ce_mois_ci"), path("ce-mois-ci", month_view, name="ce_mois_ci"),
path("tag/<tag>/ical", export_ical, name="export_ical_tag"),
path("recent/", recent, name="recent"), path("recent/", recent, name="recent"),
path("administration/", administration, name="administration"), path("administration/", administration, name="administration"),
path( path(
@ -483,18 +497,6 @@ urlpatterns = [
name="edit_static_content", name="edit_static_content",
), ),
path("rimports/<int:pk>/stats", statistics, name="stats_rimport"), path("rimports/<int:pk>/stats", statistics, name="stats_rimport"),
path(
"organisme/<int:organisation_pk>/ical",
export_ical,
name="export_ical_organisation",
),
path("place/<int:place_pk>/ical", export_ical, name="export_ical_place"),
path(
"event/<int:year>/<int:month>/<int:day>/<int:pk>/ical",
export_event_ical,
name="export_event_ical",
),
path("ical", export_ical, name="export_ical"),
re_path(r"^robots\.txt", include("robots.urls")), re_path(r"^robots\.txt", include("robots.urls")),
path("__debug__/", include("debug_toolbar.urls")), path("__debug__/", include("debug_toolbar.urls")),
path("ckeditor5/", include("django_ckeditor_5.urls")), path("ckeditor5/", include("django_ckeditor_5.urls")),

View File

@ -2,6 +2,7 @@ from .oldviews import *
from .categorisation_rules_view import * from .categorisation_rules_view import *
from .event_duplicate_views import * from .event_duplicate_views import *
from .errors import * from .errors import *
from .export_views import *
from .general_pages_views import * from .general_pages_views import *
from .import_batch_views import * from .import_batch_views import *
from .import_recurrent_views import * from .import_recurrent_views import *

View File

@ -0,0 +1,103 @@
import hashlib
from datetime import timedelta, date
import emoji
from django.core.cache import cache
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from . import get_event_qs
from ..calendar import CalendarList
from ..filters import EventFilter
from ..models import Event, Category, Place, Organisation
def export_event_ical(request, year, month, day, pk):
event = get_object_or_404(Event, pk=pk)
event = event.get_recurrence_at_date(year, month, day)
events = list()
events.append(event)
cal = Event.export_to_ics(events, request)
response = HttpResponse(content_type="text/calendar")
response.content = cal.to_ical().decode("utf-8").replace("\r\n", "\n")
response["Content-Disposition"] = "attachment; filename={0}{1}".format(
event.title.replace("\n", " ").replace("\r", "")[0:32], ".ics"
)
return response
def export_ical(request, cat=None, tag=None, organisation_pk=None, place_pk=None):
now = date.today()
qs = get_event_qs(request)
if cat is not None:
category = Category.objects.filter(slug=cat).first()
qs = qs.filter(category=category)
else:
category = None
if place_pk is not None:
qs = qs.filter(exact_location=place_pk)
if organisation_pk is not None:
qs = qs.filter(organisers__in=[organisation_pk])
if tag is not None:
qs = qs.filter(tags__in=[tag])
request = EventFilter.set_default_values(request)
filter = EventFilter(request.GET, queryset=qs, request=request)
if filter.has_category_parameters():
return HttpResponseRedirect(filter.get_new_url())
id_cache = hashlib.md5(
(
filter.get_url()
+ "-"
+ str(tag)
+ "-"
+ str(cat)
+ "-"
+ str(organisation_pk)
+ "-"
+ str(place_pk)
).encode("utf8")
).hexdigest()
ical = cache.get(id_cache)
if not ical:
calendar = CalendarList(
now + timedelta(days=-7), now + timedelta(days=+60), filter
)
ical = calendar.export_to_ics(request)
cache.set(id_cache, ical, 3600) # 1 heure
response = HttpResponse(content_type="text/calendar")
response.content = ical.to_ical().decode("utf-8").replace("\r\n", "\n")
extra = filter.to_str(" ")
if extra is None:
extra = ""
if category is not None:
extra += " " + str(category)
if place_pk is not None:
extra += (
" @ " + Place.objects.filter(pk=place_pk).values("name").first()["name"]
)
if organisation_pk is not None:
extra += (
" - "
+ Organisation.objects.filter(pk=organisation_pk)
.values("name")
.first()["name"]
)
if tag is not None:
extra += " - " + emoji.replace_emoji(tag, replace="")
response["Content-Disposition"] = "attachment; filename={0}{1}{2}".format(
"Pommes de lune", extra, ".ics"
)
return response

View File

@ -1,8 +1,6 @@
import hashlib
import logging import logging
from datetime import date, timedelta from datetime import date, timedelta
import emoji
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.mixins import ( from django.contrib.auth.mixins import (
@ -16,7 +14,6 @@ from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db.models import Aggregate, FloatField from django.db.models import Aggregate, FloatField
from django.db.models import F, OuterRef, Q, Subquery from django.db.models import F, OuterRef, Q, Subquery
from django.http import ( from django.http import (
HttpResponse,
HttpResponseForbidden, HttpResponseForbidden,
HttpResponseRedirect, HttpResponseRedirect,
) )
@ -60,8 +57,6 @@ from ..models import (
DuplicatedEvents, DuplicatedEvents,
Event, Event,
Message, Message,
Organisation,
Place,
RecurrentImport, RecurrentImport,
StaticContent, StaticContent,
UserProfile, UserProfile,
@ -826,96 +821,6 @@ def import_from_url(request):
) )
def export_event_ical(request, year, month, day, pk):
event = get_object_or_404(Event, pk=pk)
event = event.get_recurrence_at_date(year, month, day)
events = list()
events.append(event)
cal = Event.export_to_ics(events, request)
response = HttpResponse(content_type="text/calendar")
response.content = cal.to_ical().decode("utf-8").replace("\r\n", "\n")
response["Content-Disposition"] = "attachment; filename={0}{1}".format(
event.title.replace("\n", " ").replace("\r", "")[0:32], ".ics"
)
return response
def export_ical(request, cat=None, tag=None, organisation_pk=None, place_pk=None):
now = date.today()
qs = get_event_qs(request)
if cat is not None:
category = Category.objects.filter(slug=cat).first()
qs = qs.filter(category=category)
else:
category = None
if place_pk is not None:
qs = qs.filter(exact_location=place_pk)
if organisation_pk is not None:
qs = qs.filter(organisers__in=[organisation_pk])
if tag is not None:
qs = qs.filter(tags__in=[tag])
request = EventFilter.set_default_values(request)
filter = EventFilter(request.GET, queryset=qs, request=request)
if filter.has_category_parameters():
return HttpResponseRedirect(filter.get_new_url())
id_cache = hashlib.md5(
(
filter.get_url()
+ "-"
+ str(tag)
+ "-"
+ str(cat)
+ "-"
+ str(organisation_pk)
+ "-"
+ str(place_pk)
).encode("utf8")
).hexdigest()
ical = cache.get(id_cache)
if not ical:
calendar = CalendarList(
now + timedelta(days=-7), now + timedelta(days=+60), filter
)
ical = calendar.export_to_ics(request)
cache.set(id_cache, ical, 3600) # 1 heure
response = HttpResponse(content_type="text/calendar")
response.content = ical.to_ical().decode("utf-8").replace("\r\n", "\n")
extra = filter.to_str(" ")
if extra is None:
extra = ""
if category is not None:
extra += " " + str(category)
if place_pk is not None:
extra += (
" @ " + Place.objects.filter(pk=place_pk).values("name").first()["name"]
)
if organisation_pk is not None:
extra += (
" - "
+ Organisation.objects.filter(pk=organisation_pk)
.values("name")
.first()["name"]
)
if tag is not None:
extra += " - " + emoji.replace_emoji(tag, replace="")
response["Content-Disposition"] = "attachment; filename={0}{1}{2}".format(
"Pommes de lune", extra, ".ics"
)
return response
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_event") @permission_required("agenda_culturel.view_event")
def administration(request): def administration(request):