# Path: aircox/views/log.py
# 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
# 
# Path: aircox/models/log.py
# class LogArchiver:
#     """ Commodity class used to manage archives of logs. """
#     @cached_property
#     def fields(self):
#         return Log._meta.get_fields()
# 
#     @staticmethod
#     def get_path(station, date):
#         return os.path.join(
#             settings.AIRCOX_LOGS_ARCHIVES_DIR,
#             '{}_{}.log.gz'.format(date.strftime("%Y%m%d"), station.pk)
#         )
# 
#     def archive(self, qs, keep=False):
#         """
#         Archive logs of the given queryset. Delete archived logs if not
#         `keep`. Return the count of archived logs
#         """
#         if not qs.exists():
#             return 0
# 
#         os.makedirs(settings.AIRCOX_LOGS_ARCHIVES_DIR, exist_ok=True)
#         count = qs.count()
#         logs = self.sort_logs(qs)
# 
#         # Note: since we use Yaml, we can just append new logs when file
#         # exists yet <3
#         for (station, date), logs in logs.items():
#             path = self.get_path(station, date)
#             with gzip.open(path, 'ab') as archive:
#                 data = yaml.dump([self.serialize(l) for l in logs]).encode('utf8')
#                 archive.write(data)
# 
#         if not keep:
#             qs.delete()
# 
#         return count
# 
#     @staticmethod
#     def sort_logs(qs):
#         """
#         Sort logs by station and date and return a dict of
#         `{ (station,date): [logs] }`.
#         """
#         qs = qs.order_by('date')
#         logs = {}
#         for log in qs:
#             key = (log.station, log.date)
#             if key not in logs:
#                 logs[key] = [log]
#             else:
#                 logs[key].append(log)
#         return logs
# 
#     def serialize(self, log):
#         """ Serialize log """
#         return {i.attname: getattr(log, i.attname)
#                 for i in self.fields}
# 
#     def load(self, station, date):
#         """ Load an archive returning logs in a list. """
#         path = self.get_path(station, date)
# 
#         if not os.path.exists(path):
#             return []
# 
#         with gzip.open(path, 'rb') as archive:
#             data = archive.read()
#             logs = yaml.load(data)
# 
#             # we need to preload diffusions, sounds and tracks
#             rels = {
#                 'diffusion': self.get_relations(logs, Diffusion, 'diffusion'),
#                 'sound': self.get_relations(logs, Sound, 'sound'),
#                 'track': self.get_relations(logs, Track, 'track'),
#             }
# 
#             def rel_obj(log, attr):
#                 rel_id = log.get(attr + '_id')
#                 return rels[attr][rel_id] if rel_id else None
# 
#             return [Log(diffusion=rel_obj(log, 'diffusion'),
#                         sound=rel_obj(log, 'sound'),
#                         track=rel_obj(log, 'track'),
#                         **log) for log in logs]
# 
#     @staticmethod
#     def get_relations(logs, model, attr):
#         """
#         From a list of dict representing logs, retrieve related objects
#         of the given type.
#         """
#         attr_id = attr + '_id'
#         pks = (log[attr_id] for log in logs if attr_id in log)
#         return {rel.pk: rel for rel in model.objects.filter(pk__in=pks)}


from django.contrib import admin
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.utils.translation import gettext_lazy as _
from django.views.generic import ListView
from .log import LogListView
from ..models.log import LogArchiver



__all__ = ['AdminMixin', 'StatisticsView']


class AdminMixin(LoginRequiredMixin, UserPassesTestMixin):
    title = ''

    @property
    def station(self):
        return self.request.station

    def test_func(self):
        return self.request.user.is_staff

    def get_context_data(self, **kwargs):
        kwargs.update(admin.site.each_context(self.request))
        kwargs.setdefault('title', self.title)
        kwargs.setdefault('station', self.station)
        return super().get_context_data(**kwargs)


class StatisticsView(AdminMixin, LogListView, ListView):
    template_name = 'admin/aircox/statistics.html'
    redirect_date_url = 'admin:tools-stats'
    title = _('Statistics')
    date = None

    def get_object_list(self, logs, full=False):

# Path: aircox/views/log.py
# 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
# 
# Path: aircox/models/log.py
# class LogArchiver:
#     """ Commodity class used to manage archives of logs. """
#     @cached_property
#     def fields(self):
#         return Log._meta.get_fields()
# 
#     @staticmethod
#     def get_path(station, date):
#         return os.path.join(
#             settings.AIRCOX_LOGS_ARCHIVES_DIR,
#             '{}_{}.log.gz'.format(date.strftime("%Y%m%d"), station.pk)
#         )
# 
#     def archive(self, qs, keep=False):
#         """
#         Archive logs of the given queryset. Delete archived logs if not
#         `keep`. Return the count of archived logs
#         """
#         if not qs.exists():
#             return 0
# 
#         os.makedirs(settings.AIRCOX_LOGS_ARCHIVES_DIR, exist_ok=True)
#         count = qs.count()
#         logs = self.sort_logs(qs)
# 
#         # Note: since we use Yaml, we can just append new logs when file
#         # exists yet <3
#         for (station, date), logs in logs.items():
#             path = self.get_path(station, date)
#             with gzip.open(path, 'ab') as archive:
#                 data = yaml.dump([self.serialize(l) for l in logs]).encode('utf8')
#                 archive.write(data)
# 
#         if not keep:
#             qs.delete()
# 
#         return count
# 
#     @staticmethod
#     def sort_logs(qs):
#         """
#         Sort logs by station and date and return a dict of
#         `{ (station,date): [logs] }`.
#         """
#         qs = qs.order_by('date')
#         logs = {}
#         for log in qs:
#             key = (log.station, log.date)
#             if key not in logs:
#                 logs[key] = [log]
#             else:
#                 logs[key].append(log)
#         return logs
# 
#     def serialize(self, log):
#         """ Serialize log """
#         return {i.attname: getattr(log, i.attname)
#                 for i in self.fields}
# 
#     def load(self, station, date):
#         """ Load an archive returning logs in a list. """
#         path = self.get_path(station, date)
# 
#         if not os.path.exists(path):
#             return []
# 
#         with gzip.open(path, 'rb') as archive:
#             data = archive.read()
#             logs = yaml.load(data)
# 
#             # we need to preload diffusions, sounds and tracks
#             rels = {
#                 'diffusion': self.get_relations(logs, Diffusion, 'diffusion'),
#                 'sound': self.get_relations(logs, Sound, 'sound'),
#                 'track': self.get_relations(logs, Track, 'track'),
#             }
# 
#             def rel_obj(log, attr):
#                 rel_id = log.get(attr + '_id')
#                 return rels[attr][rel_id] if rel_id else None
# 
#             return [Log(diffusion=rel_obj(log, 'diffusion'),
#                         sound=rel_obj(log, 'sound'),
#                         track=rel_obj(log, 'track'),
#                         **log) for log in logs]
# 
#     @staticmethod
#     def get_relations(logs, model, attr):
#         """
#         From a list of dict representing logs, retrieve related objects
#         of the given type.
#         """
#         attr_id = attr + '_id'
#         pks = (log[attr_id] for log in logs if attr_id in log)
#         return {rel.pk: rel for rel in model.objects.filter(pk__in=pks)}


# Path: aircox/views/admin.py
from django.contrib import admin
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.utils.translation import gettext_lazy as _
from django.views.generic import ListView
from .log import LogListView
from ..models.log import LogArchiver




__all__ = ['AdminMixin', 'StatisticsView']


class AdminMixin(LoginRequiredMixin, UserPassesTestMixin):
    title = ''

    @property
    def station(self):
        return self.request.station

    def test_func(self):
        return self.request.user.is_staff

    def get_context_data(self, **kwargs):
        kwargs.update(admin.site.each_context(self.request))
        kwargs.setdefault('title', self.title)
        kwargs.setdefault('station', self.station)
        return super().get_context_data(**kwargs)


class StatisticsView(AdminMixin, LogListView, ListView):
    template_name = 'admin/aircox/statistics.html'
    redirect_date_url = 'admin:tools-stats'
    title = _('Statistics')
    date = None

    def get_object_list(self, logs, full=False):

        if not logs.exists():