Return calendars as real files

This commit is contained in:
Antoine Bartuccio 2025-01-03 01:48:18 +01:00
parent 007080ee48
commit 0a0f44607e

View File

@ -1,7 +1,8 @@
from datetime import timedelta
from datetime import datetime, timedelta
from pathlib import Path
import urllib3
from django.core.cache import cache
from django.conf import settings
from django.http import HttpResponse
from django.urls import reverse
from django.utils import timezone
@ -9,30 +10,37 @@ from ics import Calendar, Event
from ninja_extra import ControllerBase, api_controller, route
from com.models import NewsDate
from core.views.files import send_raw_file
@api_controller("/calendar")
class CalendarController(ControllerBase):
CACHE_FOLDER: Path = settings.MEDIA_ROOT / "com" / "calendars"
@route.get("/external.ics")
def calendar_external(self):
CACHE_KEY = "external_calendar"
if cached := cache.get(CACHE_KEY):
return HttpResponse(
cached,
content_type="text/calendar",
status=200,
)
file = self.CACHE_FOLDER / "external.ics"
# Return cached file if updated less than an our ago
if (
file.exists()
and timezone.make_aware(datetime.fromtimestamp(file.stat().st_mtime))
+ timedelta(hours=1)
> timezone.now()
):
return send_raw_file(file)
calendar = urllib3.request(
"GET",
"https://calendar.google.com/calendar/ical/ae.utbm%40gmail.com/public/basic.ics",
)
if calendar.status == 200:
cache.set(CACHE_KEY, calendar.data, 3600) # Cache for one hour
return HttpResponse(
calendar.data,
content_type="text/calendar",
status=calendar.status,
)
if calendar.status != 200:
return HttpResponse(status=calendar.status)
self.CACHE_FOLDER.mkdir(parents=True, exist_ok=True)
with open(file, "wb") as f:
_ = f.write(calendar.data)
return send_raw_file(file)
@route.get("/internal.ics")
def calendar_internal(self):
@ -50,7 +58,9 @@ class CalendarController(ControllerBase):
)
calendar.events.add(event)
return HttpResponse(
calendar.serialize().encode("utf-8"),
content_type="text/calendar",
)
# Create a file so we can offload the download to the reverse proxy if available
file = self.CACHE_FOLDER / "internal.ics"
self.CACHE_FOLDER.mkdir(parents=True, exist_ok=True)
with open(file, "wb") as f:
_ = f.write(calendar.serialize().encode("utf-8"))
return send_raw_file(file)