mirror of
https://github.com/ae-utbm/sith.git
synced 2025-01-08 16:11:17 +00:00
Use signals to update internal ics
This commit is contained in:
parent
a60e1f1fdc
commit
65df55a635
27
com/api.py
27
com/api.py
@ -1,14 +1,10 @@
|
|||||||
from datetime import timedelta
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.urls import reverse
|
|
||||||
from django.utils import timezone
|
|
||||||
from ics import Calendar, Event
|
|
||||||
from ninja_extra import ControllerBase, api_controller, route
|
from ninja_extra import ControllerBase, api_controller, route
|
||||||
|
|
||||||
from com.models import IcsCalendar, NewsDate
|
from com.models import IcsCalendar
|
||||||
from core.views.files import send_raw_file
|
from core.views.files import send_raw_file
|
||||||
|
|
||||||
|
|
||||||
@ -33,23 +29,4 @@ class CalendarController(ControllerBase):
|
|||||||
|
|
||||||
@route.get("/internal.ics")
|
@route.get("/internal.ics")
|
||||||
def calendar_internal(self):
|
def calendar_internal(self):
|
||||||
calendar = Calendar()
|
return send_raw_file(IcsCalendar.get_internal())
|
||||||
for news_date in NewsDate.objects.filter(
|
|
||||||
news__is_moderated=True,
|
|
||||||
end_date__gte=timezone.now()
|
|
||||||
- (timedelta(days=30) * 60), # Roughly get the last 6 months
|
|
||||||
).prefetch_related("news"):
|
|
||||||
event = Event(
|
|
||||||
name=news_date.news.title,
|
|
||||||
begin=news_date.start_date,
|
|
||||||
end=news_date.end_date,
|
|
||||||
url=reverse("com:news_detail", kwargs={"news_id": news_date.news.id}),
|
|
||||||
)
|
|
||||||
calendar.events.add(event)
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
9
com/apps.py
Normal file
9
com/apps.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class ComConfig(AppConfig):
|
||||||
|
name = "com"
|
||||||
|
verbose_name = "News and communication"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
import com.signals # noqa F401
|
@ -37,6 +37,7 @@ from django.templatetags.static import static
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from ics import Calendar, Event
|
||||||
|
|
||||||
from club.models import Club
|
from club.models import Club
|
||||||
from core.models import Notification, Preferences, User
|
from core.models import Notification, Preferences, User
|
||||||
@ -46,6 +47,7 @@ from core.models import Notification, Preferences, User
|
|||||||
class IcsCalendar:
|
class IcsCalendar:
|
||||||
_CACHE_FOLDER: Path = settings.MEDIA_ROOT / "com" / "calendars"
|
_CACHE_FOLDER: Path = settings.MEDIA_ROOT / "com" / "calendars"
|
||||||
_EXTERNAL_CALENDAR = _CACHE_FOLDER / "external.ics"
|
_EXTERNAL_CALENDAR = _CACHE_FOLDER / "external.ics"
|
||||||
|
_INTERNAL_CALENDAR = _CACHE_FOLDER / "internal.ics"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_external(cls, expiration: timedelta = timedelta(hours=1)) -> Path | None:
|
def get_external(cls, expiration: timedelta = timedelta(hours=1)) -> Path | None:
|
||||||
@ -74,6 +76,35 @@ class IcsCalendar:
|
|||||||
_ = f.write(calendar.data)
|
_ = f.write(calendar.data)
|
||||||
return cls._EXTERNAL_CALENDAR
|
return cls._EXTERNAL_CALENDAR
|
||||||
|
|
||||||
|
@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
|
||||||
|
calendar = Calendar()
|
||||||
|
for news_date in NewsDate.objects.filter(
|
||||||
|
news__is_moderated=True,
|
||||||
|
end_date__gte=timezone.now()
|
||||||
|
- (timedelta(days=30) * 60), # Roughly get the last 6 months
|
||||||
|
).prefetch_related("news"):
|
||||||
|
event = Event(
|
||||||
|
name=news_date.news.title,
|
||||||
|
begin=news_date.start_date,
|
||||||
|
end=news_date.end_date,
|
||||||
|
url=reverse("com:news_detail", kwargs={"news_id": news_date.news.id}),
|
||||||
|
)
|
||||||
|
calendar.events.add(event)
|
||||||
|
|
||||||
|
# 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(calendar.serialize().encode("utf-8"))
|
||||||
|
return cls._INTERNAL_CALENDAR
|
||||||
|
|
||||||
|
|
||||||
class Sith(models.Model):
|
class Sith(models.Model):
|
||||||
"""A one instance class storing all the modifiable infos."""
|
"""A one instance class storing all the modifiable infos."""
|
||||||
|
9
com/signals.py
Normal file
9
com/signals.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from django.db.models.base import post_save
|
||||||
|
from django.dispatch import receiver
|
||||||
|
|
||||||
|
from com.models import IcsCalendar, News
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=News, dispatch_uid="update_internal_ics")
|
||||||
|
def update_internal_ics(*args, **kwargs):
|
||||||
|
_ = IcsCalendar.make_internal()
|
@ -46,7 +46,7 @@ from accounting.models import (
|
|||||||
SimplifiedAccountingType,
|
SimplifiedAccountingType,
|
||||||
)
|
)
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
from com.models import News, NewsDate, Sith, Weekmail
|
from com.models import IcsCalendar, News, NewsDate, Sith, Weekmail
|
||||||
from core.models import Group, Page, PageRev, SithFile, User
|
from core.models import Group, Page, PageRev, SithFile, User
|
||||||
from core.utils import resize_image
|
from core.utils import resize_image
|
||||||
from counter.models import Counter, Product, ProductType, StudentCard
|
from counter.models import Counter, Product, ProductType, StudentCard
|
||||||
@ -764,6 +764,7 @@ Welcome to the wiki page!
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
NewsDate.objects.bulk_create(news_dates)
|
NewsDate.objects.bulk_create(news_dates)
|
||||||
|
IcsCalendar.make_internal() # Force refresh of the calendar after a bulk_create
|
||||||
|
|
||||||
# Create some data for pedagogy
|
# Create some data for pedagogy
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user