diff --git a/controllers/admin.py b/controllers/admin.py index 6521d70..aa3c4e8 100644 --- a/controllers/admin.py +++ b/controllers/admin.py @@ -18,7 +18,7 @@ class StationAdmin(admin.ModelAdmin): @admin.register(models.Log) class LogAdmin(admin.ModelAdmin): - list_display = ['id', 'date', 'station', 'source', 'comment', 'related'] + list_display = ['id', 'date', 'station', 'source', 'type', 'comment', 'related'] list_filter = ['date', 'source', 'related_type'] admin.site.register(models.Source) diff --git a/controllers/models.py b/controllers/models.py index fb6fc7a..c1c2cc7 100644 --- a/controllers/models.py +++ b/controllers/models.py @@ -64,7 +64,7 @@ class Station(programs.Nameable): def id_(self): return self.slug - def get_sources(self, type = None, prepare = True): + def get_sources(self, type = None, prepare = True, dealer = False): """ Return a list of active sources that can have their controllers initialized. @@ -72,7 +72,11 @@ class Station(programs.Nameable): qs = self.source_set.filter(active = True) if type: qs = qs.filter(type = type) - return [ source.prepare() or source for source in qs ] + + sources = [ source.prepare() or source for source in qs ] + if dealer == True: + sources.append(self.dealer) + return sources @property def stream_sources(self): diff --git a/controllers/monitor.py b/controllers/monitor.py index c103944..6edeb8f 100644 --- a/controllers/monitor.py +++ b/controllers/monitor.py @@ -22,6 +22,7 @@ class Monitor: controller = None def __init__(self, station): + Log.objects.all().delete() self.station = station def monitor(self): @@ -32,9 +33,11 @@ class Monitor: self.station.prepare() for stream in self.station.stream_sources: stream.load_playlist() - self.controller = self.station.controller + if not self.controller.ready(): + return + self.trace() self.handle() @@ -114,22 +117,26 @@ class Monitor: diff_log = station.get_played(models = programs.Diffusion) \ .order_by('date').last() - if not diff_log or \ not diff_log.related.is_date_in_range(now): return None, [] # sound has switched? assume it has been (forced to) stopped - sounds = station.get_played(models = programs.Sound) - last_sound = sounds.order_by('date').last() - if last_sound and last_sound.source != diff_log.source: - return None, [] + sounds = station.get_played(models = programs.Sound) \ + .filter(date__gte = diff_log.date) \ + .order_by('date') + + if sounds.last() and sounds.last().source != diff_log.source: + return diff_log, [] # last diff is still playing: get the remaining playlist sounds = sounds.filter( source = diff_log.source, pk__gt = diff_log.pk ) - sounds = [ sound.path for sound in sounds if not sound.removed ] + sounds = [ + sound.related.path for sound in sounds + if not sound.related.removed + ] return ( diff_log.related, @@ -141,11 +148,13 @@ class Monitor: """ Return the tuple with the next diff that should be played and the playlist + + Note: diff is a log """ station = self.station - now = tz.make_aware(tz.datetime.now()) + now = tz.now() - args = {'start__gt': diff.start } if diff else {} + args = {'start__gt': diff.date } if diff else {} diff = programs.Diffusion.objects.get_at(now).filter( type = programs.Diffusion.Type.normal, sound__type = programs.Sound.Type.archive, @@ -163,11 +172,11 @@ class Monitor: dealer = station.dealer if not dealer: return - now = tz.make_aware(tz.datetime.now()) + now = tz.now() # current and next diffs diff, playlist = self.__current_diff() - dealer.on = bool(playlist) + dealer.controller.active = bool(playlist) next_diff, next_playlist = self.__next_diff(diff) playlist += next_playlist @@ -180,19 +189,20 @@ class Monitor: type = Log.Type.load, source = dealer.id_, date = now, - related_object = next_diff + related = next_diff ) # dealer.on when next_diff start <= now - if next_diff and not dealer.on and next_diff.start <= now: - dealer.on = True + if next_diff and not dealer.controller.active and \ + next_diff.start <= now: + dealer.controller.active = True for source in station.get_sources(): source.controller.skip() - cl.log( + self.log( type = Log.Type.play, source = dealer.id_, date = now, - related_object = next_diff, + related = next_diff, ) diff --git a/controllers/plugins/liquidsoap.py b/controllers/plugins/liquidsoap.py index 9c0a90c..15531a4 100644 --- a/controllers/plugins/liquidsoap.py +++ b/controllers/plugins/liquidsoap.py @@ -36,10 +36,16 @@ class StationController(plugins.StationController): def __get_process_args(self): return ['liquidsoap', '-v', self.path] + def ready(self): + return self._send('var.list') != '' + def fetch(self): super().fetch() - rid = self._send('request.on_air') + + rid = self._send('request.on_air').split(' ')[0] + if ' ' in rid: + rid = rid[:rid.index(' ')] if not rid: return @@ -50,7 +56,7 @@ class StationController(plugins.StationController): self.current_sound = data.get('initial_uri') try: self.current_source = next( - source for source in self.station.get_sources() + source for source in self.station.get_sources(dealer = True) if source.controller.rid == rid ) except: @@ -70,12 +76,12 @@ class SourceController(plugins.SourceController): @property def active(self): - return self._send('var.get ', self.source.slug, '_active') == 'true' + return self._send('var.get ', self.source.id_, '_active') == 'true' @active.setter def active(self, value): - return self._send('var.set ', self.source.slug, '_active', '=', - 'true' if value else 'false') + self._send('var.set ', self.source.id_, '_active', '=', + 'true' if value else 'false') def skip(self): """ @@ -85,7 +91,7 @@ class SourceController(plugins.SourceController): def fetch(self): data = self._send(self.source.id_, '.get', parse = True) - if not data: + if not data or type(data) != dict: return self.rid = data.get('rid') diff --git a/controllers/plugins/plugins.py b/controllers/plugins/plugins.py index d0f3e3d..beccdb9 100644 --- a/controllers/plugins/plugins.py +++ b/controllers/plugins/plugins.py @@ -71,7 +71,7 @@ class StationController: The base function just execute the function of all children sources. The plugin must implement the other extra part """ - sources = self.station.get_sources() + sources = self.station.get_sources(dealer = True) for source in sources: source.prepare() if source.controller: @@ -117,6 +117,11 @@ class StationController: self.process.wait() self.process = None + def ready(self): + """ + If external program is ready to use, returns True + """ + def push(self, config = True): """ Update configuration and children's info. @@ -124,7 +129,7 @@ class StationController: The base function just execute the function of all children sources. The plugin must implement the other extra part """ - sources = self.station.get_sources() + sources = self.station.get_sources(dealer = True) for source in sources: source.prepare() if source.controller: