From 0ecaa6366388b12d4069103139b739ec6463c88f Mon Sep 17 00:00:00 2001 From: bkfox Date: Thu, 17 Aug 2017 14:26:07 +0200 Subject: [PATCH] include logs in stats; fix bug --- aircox/management/commands/streamer.py | 5 ++- aircox/models.py | 47 +++++++++++++++++++++++--- aircox/views.py | 3 ++ aircox_cms/wagtail_hooks.py | 7 ++-- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/aircox/management/commands/streamer.py b/aircox/management/commands/streamer.py index c7f552a..4b4c248 100755 --- a/aircox/management/commands/streamer.py +++ b/aircox/management/commands/streamer.py @@ -145,6 +145,7 @@ class Monitor: is_diff = log.date != on_air except: + on_air = None is_diff = log.source != current_source.id or \ (log.sound and log.sound.path != current_sound) @@ -159,12 +160,11 @@ class Monitor: if archives.filter(pk = sound.pk).exists(): diff = last_diff.diffusion - # log sound on air log = self.log( type = Log.Type.on_air, source = current_source.id, - date = on_air or tz.now(), + date = on_air or tz.now(), sound = sound, diffusion = diff, # if sound is removed, we keep sound path info @@ -181,7 +181,6 @@ class Monitor: Log tracks for the given sound log (for streamed programs). Called by self.trace """ - # TODO take restart in account tracks = Track.objects.get_for(object = log.sound) \ .filter(in_seconds = True) if not tracks.exists(): diff --git a/aircox/models.py b/aircox/models.py index 2b79642..0440f54 100755 --- a/aircox/models.py +++ b/aircox/models.py @@ -1242,12 +1242,28 @@ class LogManager(models.Manager): # of retrieving archive when it changes return os.path.join( settings.AIRCOX_LOGS_ARCHIVES_DIR, - # FIXME: number format - '{}{}{}_{}.log.gz'.format( - date.year, date.month, date.day, station.pk - ) + '{}_{}.log.gz'.format(date.strftime("%Y%m%d"), station.pk) ) + @staticmethod + def _get_rel_objects(logs, type, attr): + """ + From a list of dict representing logs, retrieve related objects + of the given type. + + Example: _get_rel_objects([{..},..], Diffusion, 'diffusion') + """ + attr_id = attr + '_id' + return { + rel.pk: rel + for rel in type.objects.filter( + pk__in = ( + log[attr_id] + for log in logs if attr_id in log + ) + ) + } + def load_archive(self, station, date): """ Return archived logs for a specific date as a list @@ -1262,7 +1278,28 @@ class LogManager(models.Manager): with gzip.open(path, 'rb') as archive: data = archive.read() logs = yaml.load(data) - return logs + + # we need to preload diffusions, sounds and tracks + # we get them all at once, in order to reduce db calls + rels = { + 'diffusion': self._get_rel_objects(logs, Diffusion, 'diffusion'), + 'sound': self._get_rel_objects(logs, Sound, 'sound'), + 'track': self._get_rel_objects(logs, Track, 'track'), + } + + def rel_obj(log, attr): + attr_id = attr + '_id' + rel_id = log.get(attr + '_id') + return rels[attr][rel_id] if rel_id else None + + # make logs + return [ + Log(diffusion = rel_obj(log, 'diffusion'), + sound = rel_obj(log, 'sound'), + track = rel_obj(log, 'track'), + **log) + for log in logs + ] def make_archive(self, station, date, force = False, keep = False): """ diff --git a/aircox/views.py b/aircox/views.py index cb6584c..6729aaf 100755 --- a/aircox/views.py +++ b/aircox/views.py @@ -201,6 +201,9 @@ class StatisticsView(View,TemplateResponseMixin,LoginRequiredMixin): qs = station.raw_on_air(date = date) \ .prefetch_related('diffusion', 'sound', 'track', 'track__tags') + if not qs.exists(): + qs = models.Log.objects.load_archive(station, date) + sound_log = None for log in qs: rel = None diff --git a/aircox_cms/wagtail_hooks.py b/aircox_cms/wagtail_hooks.py index 751e938..f96a09c 100755 --- a/aircox_cms/wagtail_hooks.py +++ b/aircox_cms/wagtail_hooks.py @@ -225,7 +225,7 @@ class GenericMenu(Menu): @staticmethod def page_of(item): - return item.page + return hasattr(item, 'page') and item.page def page_url(self, item): page = self.page_of(item) @@ -317,8 +317,9 @@ class TodayMenu(GenericMenu): attrs = {} - qs = PageRevision.objects.filter(page = item.page) - if qs.count(): + qs = hasattr(item, 'page') and \ + PageRevision.objects.filter(page = item.page) + if qs and qs.count(): headline = qs.latest('created_at').content_json headline = json.loads(headline).get('headline') attrs['title'] = headline