make scheduled diffusion work on controllers

This commit is contained in:
bkfox 2016-07-19 20:54:00 +02:00
parent f87c660878
commit 1be3bf1e74
5 changed files with 52 additions and 27 deletions

View File

@ -18,7 +18,7 @@ class StationAdmin(admin.ModelAdmin):
@admin.register(models.Log) @admin.register(models.Log)
class LogAdmin(admin.ModelAdmin): 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'] list_filter = ['date', 'source', 'related_type']
admin.site.register(models.Source) admin.site.register(models.Source)

View File

@ -64,7 +64,7 @@ class Station(programs.Nameable):
def id_(self): def id_(self):
return self.slug 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 Return a list of active sources that can have their controllers
initialized. initialized.
@ -72,7 +72,11 @@ class Station(programs.Nameable):
qs = self.source_set.filter(active = True) qs = self.source_set.filter(active = True)
if type: if type:
qs = qs.filter(type = 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 @property
def stream_sources(self): def stream_sources(self):

View File

@ -22,6 +22,7 @@ class Monitor:
controller = None controller = None
def __init__(self, station): def __init__(self, station):
Log.objects.all().delete()
self.station = station self.station = station
def monitor(self): def monitor(self):
@ -32,9 +33,11 @@ class Monitor:
self.station.prepare() self.station.prepare()
for stream in self.station.stream_sources: for stream in self.station.stream_sources:
stream.load_playlist() stream.load_playlist()
self.controller = self.station.controller self.controller = self.station.controller
if not self.controller.ready():
return
self.trace() self.trace()
self.handle() self.handle()
@ -114,22 +117,26 @@ class Monitor:
diff_log = station.get_played(models = programs.Diffusion) \ diff_log = station.get_played(models = programs.Diffusion) \
.order_by('date').last() .order_by('date').last()
if not diff_log or \ if not diff_log or \
not diff_log.related.is_date_in_range(now): not diff_log.related.is_date_in_range(now):
return None, [] return None, []
# sound has switched? assume it has been (forced to) stopped # sound has switched? assume it has been (forced to) stopped
sounds = station.get_played(models = programs.Sound) sounds = station.get_played(models = programs.Sound) \
last_sound = sounds.order_by('date').last() .filter(date__gte = diff_log.date) \
if last_sound and last_sound.source != diff_log.source: .order_by('date')
return None, []
if sounds.last() and sounds.last().source != diff_log.source:
return diff_log, []
# last diff is still playing: get the remaining playlist # last diff is still playing: get the remaining playlist
sounds = sounds.filter( sounds = sounds.filter(
source = diff_log.source, pk__gt = diff_log.pk 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 ( return (
diff_log.related, diff_log.related,
@ -141,11 +148,13 @@ class Monitor:
""" """
Return the tuple with the next diff that should be played and Return the tuple with the next diff that should be played and
the playlist the playlist
Note: diff is a log
""" """
station = self.station 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( diff = programs.Diffusion.objects.get_at(now).filter(
type = programs.Diffusion.Type.normal, type = programs.Diffusion.Type.normal,
sound__type = programs.Sound.Type.archive, sound__type = programs.Sound.Type.archive,
@ -163,11 +172,11 @@ class Monitor:
dealer = station.dealer dealer = station.dealer
if not dealer: if not dealer:
return return
now = tz.make_aware(tz.datetime.now()) now = tz.now()
# current and next diffs # current and next diffs
diff, playlist = self.__current_diff() diff, playlist = self.__current_diff()
dealer.on = bool(playlist) dealer.controller.active = bool(playlist)
next_diff, next_playlist = self.__next_diff(diff) next_diff, next_playlist = self.__next_diff(diff)
playlist += next_playlist playlist += next_playlist
@ -180,19 +189,20 @@ class Monitor:
type = Log.Type.load, type = Log.Type.load,
source = dealer.id_, source = dealer.id_,
date = now, date = now,
related_object = next_diff related = next_diff
) )
# dealer.on when next_diff start <= now # dealer.on when next_diff start <= now
if next_diff and not dealer.on and next_diff.start <= now: if next_diff and not dealer.controller.active and \
dealer.on = True next_diff.start <= now:
dealer.controller.active = True
for source in station.get_sources(): for source in station.get_sources():
source.controller.skip() source.controller.skip()
cl.log( self.log(
type = Log.Type.play, type = Log.Type.play,
source = dealer.id_, source = dealer.id_,
date = now, date = now,
related_object = next_diff, related = next_diff,
) )

View File

@ -36,10 +36,16 @@ class StationController(plugins.StationController):
def __get_process_args(self): def __get_process_args(self):
return ['liquidsoap', '-v', self.path] return ['liquidsoap', '-v', self.path]
def ready(self):
return self._send('var.list') != ''
def fetch(self): def fetch(self):
super().fetch() 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: if not rid:
return return
@ -50,7 +56,7 @@ class StationController(plugins.StationController):
self.current_sound = data.get('initial_uri') self.current_sound = data.get('initial_uri')
try: try:
self.current_source = next( 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 if source.controller.rid == rid
) )
except: except:
@ -70,12 +76,12 @@ class SourceController(plugins.SourceController):
@property @property
def active(self): 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 @active.setter
def active(self, value): def active(self, value):
return self._send('var.set ', self.source.slug, '_active', '=', self._send('var.set ', self.source.id_, '_active', '=',
'true' if value else 'false') 'true' if value else 'false')
def skip(self): def skip(self):
""" """
@ -85,7 +91,7 @@ class SourceController(plugins.SourceController):
def fetch(self): def fetch(self):
data = self._send(self.source.id_, '.get', parse = True) data = self._send(self.source.id_, '.get', parse = True)
if not data: if not data or type(data) != dict:
return return
self.rid = data.get('rid') self.rid = data.get('rid')

View File

@ -71,7 +71,7 @@ class StationController:
The base function just execute the function of all children The base function just execute the function of all children
sources. The plugin must implement the other extra part 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: for source in sources:
source.prepare() source.prepare()
if source.controller: if source.controller:
@ -117,6 +117,11 @@ class StationController:
self.process.wait() self.process.wait()
self.process = None self.process = None
def ready(self):
"""
If external program is ready to use, returns True
"""
def push(self, config = True): def push(self, config = True):
""" """
Update configuration and children's info. Update configuration and children's info.
@ -124,7 +129,7 @@ class StationController:
The base function just execute the function of all children The base function just execute the function of all children
sources. The plugin must implement the other extra part 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: for source in sources:
source.prepare() source.prepare()
if source.controller: if source.controller: