aircox-radiocampus/aircox/views/log.py
Thomas Kairos f7a61fe6c0 Feat: packaging (#127)
- Add configuration files for packaging
- Precommit now uses ruff

Co-authored-by: bkfox <thomas bkfox net>
Reviewed-on: rc/aircox#127
2023-10-11 10:58:34 +02:00

116 lines
3.8 KiB
Python

import datetime
from django.utils import timezone as tz
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from django.views.generic import ListView
from rest_framework.generics import ListAPIView
from ..models import Diffusion, Log, StaticPage
from ..serializers import LogInfo, LogInfoSerializer
from .base import BaseAPIView, BaseView
from .mixins import AttachedToMixin, GetDateMixin
__all__ = ["LogListMixin", "LogListView"]
class LogListMixin(GetDateMixin):
model = Log
min_date = None
def get_date(self):
date = super().get_date()
if date is not None and not self.request.user.is_staff:
return min(date, datetime.date.today())
return date
def get_queryset(self):
# only get logs for tracks: log for diffusion will be retrieved
# by the diffusions' queryset.
qs = super().get_queryset().on_air().filter(track__isnull=False).filter(date__lte=tz.now())
return (
qs.date(self.date)
if self.date is not None
else qs.after(self.min_date)
if self.min_date is not None
else qs
)
def get_diffusions_queryset(self):
qs = Diffusion.objects.station(self.station).on_air().filter(start__lte=tz.now())
return (
qs.date(self.date)
if self.date is not None
else qs.after(self.min_date)
if self.min_date is not None
else qs
)
def get_object_list(self, logs, full=False):
"""Return diffusions merged to the provided logs iterable.
If `full`, sort items by date without merging.
"""
diffs = self.get_diffusions_queryset()
if self.request.user.is_staff and full:
return sorted(list(logs) + list(diffs), key=lambda obj: obj.start)
return Log.merge_diffusions(logs, diffs)
class LogListView(AttachedToMixin, BaseView, LogListMixin, ListView):
"""Return list of logs for the provided date (from `kwargs` or
`request.GET`, defaults to today)."""
redirect_date_url = "log-list"
has_filters = True
attach_to_value = StaticPage.ATTACH_TO_LOGS
def get_date(self):
date = super().get_date()
return datetime.date.today() if date is None else date
def get_context_data(self, **kwargs):
today = datetime.date.today()
# `super()...` must be called before updating kwargs, in order
# to get `self.object_list`
kwargs = super().get_context_data(**kwargs)
kwargs.update(
{
"date": self.date,
"dates": (today - datetime.timedelta(days=i) for i in range(0, 7)),
"object_list": self.get_object_list(self.object_list),
}
)
return kwargs
# Logs are accessible through API only with this list view
class LogListAPIView(LogListMixin, BaseAPIView, ListAPIView):
"""Return logs list, including diffusions. By default return logs of the
last 30 minutes.
Available GET parameters:
- "date": return logs for a specified date (
- "full": (staff user only) don't merge diffusion and logs
"""
serializer_class = LogInfoSerializer
queryset = Log.objects.all()
@method_decorator(cache_page(5))
def list(self, *args, **kwargs):
return super().list(*args, **kwargs)
def get_date(self):
date = super().get_date()
if date is None:
self.min_date = tz.now() - tz.timedelta(minutes=30)
return date
def get_object_list(self, logs, full):
return [LogInfo(obj) for obj in super().get_object_list(logs, full)]
def get_serializer(self, queryset, *args, **kwargs):
full = bool(self.request.GET.get("full"))
return super().get_serializer(self.get_object_list(queryset, full), *args, **kwargs)