mirror of
https://github.com/ae-utbm/sith.git
synced 2025-04-16 02:50:22 +00:00
77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
from pathlib import Path
|
|
|
|
from dateutil.relativedelta import relativedelta
|
|
from django.conf import settings
|
|
from django.contrib.sites.models import Site
|
|
from django.contrib.syndication.views import add_domain
|
|
from django.db.models import F, QuerySet
|
|
from django.http import HttpRequest
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from ical.calendar import Calendar
|
|
from ical.calendar_stream import IcsCalendarStream
|
|
from ical.event import Event
|
|
|
|
from com.models import NewsDate
|
|
from core.models import User
|
|
|
|
|
|
def as_absolute_url(url: str, request: HttpRequest | None = None) -> str:
|
|
return add_domain(
|
|
Site.objects.get_current(request=request),
|
|
url,
|
|
secure=request.is_secure() if request is not None else settings.HTTPS,
|
|
)
|
|
|
|
|
|
class IcsCalendar:
|
|
_CACHE_FOLDER: Path = settings.MEDIA_ROOT / "com" / "calendars"
|
|
_INTERNAL_CALENDAR = _CACHE_FOLDER / "internal.ics"
|
|
|
|
@classmethod
|
|
def get_internal(cls) -> Path:
|
|
if not cls._INTERNAL_CALENDAR.exists():
|
|
return cls.make_internal()
|
|
return cls._INTERNAL_CALENDAR
|
|
|
|
@classmethod
|
|
def make_internal(cls) -> Path:
|
|
# Updated through a post_save signal on News in com.signals
|
|
# Create a file so we can offload the download to the reverse proxy if available
|
|
cls._CACHE_FOLDER.mkdir(parents=True, exist_ok=True)
|
|
with open(cls._INTERNAL_CALENDAR, "wb") as f:
|
|
_ = f.write(
|
|
cls.ics_from_queryset(
|
|
NewsDate.objects.filter(
|
|
news__is_published=True,
|
|
end_date__gte=timezone.now() - (relativedelta(months=6)),
|
|
)
|
|
)
|
|
)
|
|
return cls._INTERNAL_CALENDAR
|
|
|
|
@classmethod
|
|
def get_unpublished(cls, user: User) -> bytes:
|
|
return cls.ics_from_queryset(
|
|
NewsDate.objects.viewable_by(user).filter(
|
|
news__is_published=False,
|
|
end_date__gte=timezone.now() - (relativedelta(months=6)),
|
|
),
|
|
)
|
|
|
|
@classmethod
|
|
def ics_from_queryset(cls, queryset: QuerySet[NewsDate]) -> bytes:
|
|
calendar = Calendar()
|
|
for news_date in queryset.annotate(news_title=F("news__title")):
|
|
event = Event(
|
|
summary=news_date.news_title,
|
|
start=news_date.start_date,
|
|
end=news_date.end_date,
|
|
url=as_absolute_url(
|
|
reverse("com:news_detail", kwargs={"news_id": news_date.news.id})
|
|
),
|
|
)
|
|
calendar.events.append(event)
|
|
|
|
return IcsCalendarStream.calendar_to_ics(calendar).encode("utf-8")
|