From 4a7517c109b6a82d6035f71f86d3da7b2bd77055 Mon Sep 17 00:00:00 2001 From: bkfox Date: Mon, 22 Aug 2016 20:55:30 +0200 Subject: [PATCH] monitor: playlist update and fetch to/from file only if changed; fix bug logs filter in on_air --- cms/models.py | 1 - cms/sections.py | 1 + cms/static/cms/js/player.js | 2 +- controllers/models.py | 39 +++++------------------- controllers/monitor.py | 12 ++++---- controllers/plugins/plugins.py | 55 ++++++++++++++++++++++++++++++++-- notes.md | 1 - 7 files changed, 66 insertions(+), 45 deletions(-) diff --git a/cms/models.py b/cms/models.py index 9fd35e1..67f47ad 100644 --- a/cms/models.py +++ b/cms/models.py @@ -407,7 +407,6 @@ class ProgramPage(Publication): diffs = programs.Diffusion.objects \ .filter(end__gte = now, program = self.program) \ .order_by('start').prefetch_related('page') - print(diffs) return self.diffs_to_page(diffs) @property diff --git a/cms/sections.py b/cms/sections.py index 19d45e7..64968a6 100644 --- a/cms/sections.py +++ b/cms/sections.py @@ -884,6 +884,7 @@ class SectionLogsList(SectionItem): Supports: Log/Track, Diffusion """ from aircox.cms.models import DiffusionPage + print(log, type(log)) if type(log) == programs.Diffusion: return DiffusionPage.as_item(log) return ListItem( diff --git a/cms/static/cms/js/player.js b/cms/static/cms/js/player.js index 74bcebf..851d519 100644 --- a/cms/static/cms/js/player.js +++ b/cms/static/cms/js/player.js @@ -344,7 +344,7 @@ Player.prototype = { var data = JSON.parse(req.responseText) if(data.type == 'track') data = { - title: '♫' + (data.artist ? data.artist + ' — ' : '') + + title: '♫ ' + (data.artist ? data.artist + ' — ' : '') + data.title, url: '' } diff --git a/controllers/models.py b/controllers/models.py index e2dc0fa..ab4d663 100644 --- a/controllers/models.py +++ b/controllers/models.py @@ -180,7 +180,7 @@ class Station(programs.Nameable): # each to put them too there items = [] diff_ = None - for diff in diffs: + for diff in diffs.order_by('-start'): logs_ = \ logs.filter(date__gt = diff.end, date__lt = diff_.start) \ if diff_ else \ @@ -194,7 +194,6 @@ class Station(programs.Nameable): if diff_: if count and len(items) >= count: return items[:count] - logs_ = logs.filter(date__lt = diff_.end) else: logs_ = logs.all() @@ -211,6 +210,7 @@ class Station(programs.Nameable): * date: only for what happened on this date; * count: number of items to retrieve if not zero; + If date is not specified, count MUST be set to a non-zero value. Be careful with what you which for: the result is a plain list. The list contains: @@ -220,6 +220,9 @@ class Station(programs.Nameable): # FIXME: as an iterator? # TODO argument to get sound instead of tracks # TODO #Station + if not date and not count: + raise ValueError('at least one argument must be set') + if date and date > datetime.date.today(): return [] @@ -234,8 +237,7 @@ class Station(programs.Nameable): diffs = programs.Diffusion.objects diffs = diffs.filter(type = programs.Diffusion.Type.normal) \ - .filter(start__lte = tz.now()) \ - .order_by('-start') + .filter(start__lte = tz.now()) return self.__mix_logs_and_diff(diffs, logs, count) @@ -345,33 +347,6 @@ class Source(programs.Nameable): if fetch: self.controller.fetch() - def load_playlist(self, diffusion = None, program = None): - """ - Load a playlist to the controller. If diffusion or program is - given use it, otherwise, try with self.program if exists, or - (if URI, self.value). - - A playlist from a program uses all archives available for the - program. - """ - if diffusion: - self.controller.playlist = diffusion.playlist - return - - program = program or self.program - if program: - self.controller.playlist = [ sound.path for sound in - programs.Sound.objects.filter( - type = programs.Sound.Type.archive, - program = program, - ) - ] - return - - if self.type == self.Type.file and self.value: - self.controller.playlist = [ self.value ] - return - def save(self, *args, **kwargs): if self.type in (self.Type.file, self.Type.fallback) and \ not self.url: @@ -462,7 +437,7 @@ class Log(programs.Related): ) date = models.DateTimeField( _('date'), - auto_now_add=True, + default=tz.now, ) comment = models.CharField( _('comment'), diff --git a/controllers/monitor.py b/controllers/monitor.py index 4b059df..5019aad 100644 --- a/controllers/monitor.py +++ b/controllers/monitor.py @@ -44,8 +44,6 @@ class Monitor: """ if not self.controller: self.station.prepare() - for stream in self.station.stream_sources: - stream.load_playlist() self.controller = self.station.controller if not self.controller.ready(): @@ -78,12 +76,13 @@ class Monitor: .filter(station = self.station).order_by('date').last() # only streamed - if log and not log.related.diffusion: + if log and (log.related and not log.related.diffusion): self.trace_sound_tracks(log) # TODO: expiration if log and (log.source == current_source.id_ and \ - log.related.path == current_sound): + log.related and + log.related.path == current_sound): return sound = programs.Sound.objects.filter(path = current_sound) @@ -133,9 +132,8 @@ class Monitor: for source in self.station.stream_sources: playlist = [ sound.path for sound in - source.program.sound_set.all().order_by('path') ] - if playlist != source.controller.playlist: - source.controller.playlist = playlist + source.program.sound_set.all() ] + source.controller.playlist = playlist def trace_canceled(self): """ diff --git a/controllers/plugins/plugins.py b/controllers/plugins/plugins.py index 0f30875..6df0c68 100644 --- a/controllers/plugins/plugins.py +++ b/controllers/plugins/plugins.py @@ -5,6 +5,8 @@ import atexit from django.template.loader import render_to_string +import aircox.programs.models as programs + class Plugins(type): registry = {} @@ -192,12 +194,15 @@ class SourceController: """ Current playlist on the Source, list of paths to play """ + self.fetch() return self.__playlist @playlist.setter def playlist(self, value): - self.__playlist = value - self.push() + value = sorted(value) + if value != self.__playlist: + self.__playlist = value + self.push() def __init__(self, **kwargs): self.__dict__.update(kwargs) @@ -205,6 +210,10 @@ class SourceController: if not self.path: self.path = os.path.join(self.source.station.path, self.source.slug + '.m3u') + self.from_file() + + if not self.__playlist: + self.from_db() def skip(self): """ @@ -225,7 +234,7 @@ class SourceController: """ os.makedirs(os.path.dirname(self.path), exist_ok = True) with open(self.path, 'w') as file: - file.write('\n'.join(self.playlist or [])) + file.write('\n'.join(self.__playlist or [])) def activate(self, value = True): """ @@ -234,6 +243,46 @@ class SourceController: """ pass + def from_db(self, diffusion = None, program = None): + """ + Load a playlist to the controller from the database. If diffusion or + program is given use it, otherwise, try with self.program if exists, or + (if URI, self.url). + + A playlist from a program uses all its available archives. + """ + if diffusion: + self.playlist = diffusion.playlist + return + + source = self.source + program = program or source.program + if program: + self.playlist = [ sound.path for sound in + programs.Sound.objects.filter( + type = programs.Sound.Type.archive, + program = program, + ) + ] + return + + if source.type == source.Type.file and source.url: + self.playlist = [ self.url ] + return + + def from_file(self, path = None): + """ + Load a playlist from the given file (if not, use the + controller's one + """ + path = path or self.path + if not os.path.exists(path): + return + + with open(path, 'r') as file: + self.__playlist = file.read() + self.__playlist = self.__playlist.split('\n') \ + if self.__playlist else [] class Monitor: station = None diff --git a/notes.md b/notes.md index a20db13..ab5028e 100644 --- a/notes.md +++ b/notes.md @@ -22,7 +22,6 @@ controllers: - logs: archive functionnality - tools: - track stats for diffusions - - rename controllers.Station into controllers.Streamer -> keep Station for sth else cms: - player support diffusions with multiple archive files