mirror of
https://github.com/ae-utbm/sith.git
synced 2025-02-27 09:57:09 +00:00
105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
from pathlib import Path
|
|
from typing import Literal
|
|
|
|
from django.conf import settings
|
|
from django.http import Http404, HttpResponse
|
|
from ninja import Query
|
|
from ninja_extra import ControllerBase, api_controller, paginate, route
|
|
from ninja_extra.pagination import PageNumberPaginationExtra
|
|
from ninja_extra.permissions import IsAuthenticated
|
|
from ninja_extra.schemas import PaginatedResponseSchema
|
|
|
|
from com.calendar import IcsCalendar
|
|
from com.models import News, NewsDate
|
|
from com.schemas import NewsDateFilterSchema, NewsDateSchema
|
|
from core.auth.api_permissions import HasPerm
|
|
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", url_name="calendar_external")
|
|
def calendar_external(self):
|
|
"""Return the ICS file of the AE Google Calendar
|
|
|
|
Because of Google's cors rules, we can't just do a request to google ics
|
|
from the frontend. Google is blocking CORS request in its responses headers.
|
|
The only way to do it from the frontend is to use Google Calendar API with an API key
|
|
This is not especially desirable as your API key is going to be provided to the frontend.
|
|
|
|
This is why we have this backend based solution.
|
|
"""
|
|
if (calendar := IcsCalendar.get_external()) is not None:
|
|
return send_raw_file(calendar)
|
|
raise Http404
|
|
|
|
@route.get("/internal.ics", url_name="calendar_internal")
|
|
def calendar_internal(self):
|
|
return send_raw_file(IcsCalendar.get_internal())
|
|
|
|
@route.get(
|
|
"/unmoderated.ics",
|
|
permissions=[IsAuthenticated],
|
|
url_name="calendar_unmoderated",
|
|
)
|
|
def calendar_unmoderated(self):
|
|
return HttpResponse(
|
|
IcsCalendar.get_unmoderated(self.context.request.user),
|
|
content_type="text/calendar",
|
|
)
|
|
|
|
|
|
@api_controller("/news")
|
|
class NewsController(ControllerBase):
|
|
@route.patch(
|
|
"/{int:news_id}/moderate",
|
|
permissions=[HasPerm("com.moderate_news")],
|
|
url_name="moderate_news",
|
|
)
|
|
def moderate_news(self, news_id: int):
|
|
news = self.get_object_or_exception(News, id=news_id)
|
|
if not news.is_moderated:
|
|
news.is_moderated = True
|
|
news.moderator = self.context.request.user
|
|
news.save()
|
|
|
|
@route.patch(
|
|
"/{int:news_id}/remove",
|
|
permissions=[HasPerm("com.moderate_news")],
|
|
url_name="remove_news",
|
|
)
|
|
def remove_news(self, news_id: int):
|
|
news = self.get_object_or_exception(News, id=news_id)
|
|
if news.is_moderated:
|
|
news.is_moderated = False
|
|
news.moderator = self.context.request.user
|
|
news.save()
|
|
|
|
@route.delete(
|
|
"/{int:news_id}",
|
|
permissions=[HasPerm("com.delete_news")],
|
|
url_name="delete_news",
|
|
)
|
|
def delete_news(self, news_id: int):
|
|
news = self.get_object_or_exception(News, id=news_id)
|
|
news.delete()
|
|
|
|
@route.get(
|
|
"/date",
|
|
url_name="fetch_news_dates",
|
|
response=PaginatedResponseSchema[NewsDateSchema],
|
|
)
|
|
@paginate(PageNumberPaginationExtra, page_size=50)
|
|
def fetch_news_dates(
|
|
self,
|
|
filters: Query[NewsDateFilterSchema],
|
|
text_format: Literal["md", "html"] = "md",
|
|
):
|
|
return filters.filter(
|
|
NewsDate.objects.viewable_by(self.context.request.user)
|
|
.order_by("start_date")
|
|
.select_related("news", "news__club")
|
|
)
|