liquidsoap: fix error in template, station.current_source on request's id

This commit is contained in:
bkfox 2016-07-12 22:26:36 +02:00
parent 0d75f65ed4
commit a5638f0071
6 changed files with 109 additions and 43 deletions

View File

@ -2,12 +2,25 @@ from django.contrib import admin
import aircox.controllers.models as models
class SourceInline(admin.StackedInline):
model = models.Source
extra = 0
class OutputInline(admin.StackedInline):
model = models.Output
extra = 0
@admin.register(models.Station)
class StationAdmin(admin.ModelAdmin):
inlines = [ SourceInline, OutputInline ]
#@admin.register(Log)
#class LogAdmin(admin.ModelAdmin):
# list_display = ['id', 'date', 'source', 'comment', 'related_object']
# list_filter = ['date', 'source', 'related_type']
admin.site.register(models.Station)
admin.site.register(models.Source)
admin.site.register(models.Output)
admin.site.register(models.Log)

View File

@ -51,6 +51,10 @@ class Station(programs.Nameable):
plugin.StationController
"""
@property
def id_(self):
return self.slug
def get_sources(self, type = None, prepare = True):
"""
Return a list of active sources that can have their controllers
@ -87,7 +91,8 @@ class Station(programs.Nameable):
"""
List of active outputs
"""
return [ output for output in self.output_set if output.active ]
print(self.output_set)
return [ output for output in self.output_set.filter(active = True) ]
def prepare(self, fetch = True):
"""
@ -129,6 +134,32 @@ class Station(programs.Nameable):
if self.plugin_name:
self.plugin = Plugins.registry.get(self.plugin_name)
def play_logs(self, include_diffusions = True,
include_sounds = True,
exclude_archives = True):
"""
Return a queryset with what is playing on air for this station.
Ordered by date ascending.
"""
models = []
if include_diffusions: models.append(programs.Diffusion)
if include_sounds: models.append(programs.Sound)
qs = Log.get_for(model = models) \
.filter(station = station, type = Log.Type.play)
if exclude_archives and self.dealer:
qs = qs.exclude(
source = self.dealer.id_,
related_type = ContentType.objects.get_for_model(
program.Sound
)
)
return qs.order_by('date')
def save(self, make_sources = True, *args, **kwargs):
"""
* make_sources: if the model has not been yet saved, generate
@ -216,6 +247,10 @@ class Source(programs.Nameable):
implements plugin.SourceController;
"""
@property
def id_(self):
return self.slug
@property
def stream(self):
if self.type != self.Type.stream or not self.program:
@ -392,8 +427,14 @@ class Log(models.Model):
if not model and object:
model = type(object)
qs = cl.objects.filter(related_type__pk =
ContentTYpe.objects.get_for_model(model).id)
if type(model) in (list, tuple):
model = [ ContentType.objects.get_for_model(m).id
for m in model ]
qs = cl.objects.filter(related_type__pk__in = model)
else:
model = ContentType.objects.get_for_model(model)
qs = cl.objects.filter(related_type__pk = model.id)
if object:
qs = qs.filter(related_id = object.pk)
return qs
@ -408,7 +449,7 @@ class Log(models.Model):
def __str__(self):
return '#{} ({}, {})'.format(
self.id, self.date.strftime('%Y/%m/%d %H:%M'), self.source.name
self.pk, self.date.strftime('%Y/%m/%d %H:%M'), self.source.name
)

View File

@ -12,6 +12,18 @@ class Monitor:
do that.
"""
station = None
controller = None
def run(self):
"""
Run all monitoring functions. Ensure that station has controllers
"""
if not self.controller:
self.station.prepare()
self.controller = self.station.controller
self.track()
self.handler()
@staticmethod
def log(**kwargs):
@ -27,25 +39,23 @@ class Monitor:
Check the current_sound of the station and update logs if
needed
"""
station = self.station
station.controller.fetch()
current_sound = station.controller.current_sound
current_source = station.controller.current_source
self.controller.fetch()
current_sound = self.controller.current_sound
current_source = self.controller.current_source
if not current_sound:
return
log = Log.get_for(model = programs.Sound) \
.filter(station = station).order_by('date').last()
.filter(station = self.station).order_by('date').last()
# TODO: expiration
if log and (log.source == current_source and \
if log and (log.source == current_source.id_ and \
log.related.path == current_sound):
return
sound = programs.Sound.object.filter(path = current_sound)
self.log(
type = Log.Type.play,
source = current_source,
source = current_source.id_,
date = tz.make_aware(tz.datetime.now()),
related = sound[0] if sound else None,
@ -60,17 +70,21 @@ class Monitor:
station = self.station
now = tz.make_aware(tz.datetime.now())
sound_log = Log.get_for(model = programs.Sound) \
.filter(station = station).order_by('date').last()
diff_log = Log.get_for(model = programs.Diffusion) \
.filter(station = station).order_by('date').last()
.filter(station = station, type = Log.Type.play) \
.order_by('date').last()
if not sound_log or not diff_log or \
sound_log.source != diff_log.source or \
diff_log.related.is_date_in_my_range(now) :
if not diff_log or \
not diff_log.related.is_date_in_my_range(now):
return None, []
# last registered diff is still playing: update the playlist
# sound has switched? assume it has been (forced to) stopped
sound_log = Log.get_for(model = programs.Sound) \
.filter(station = station).order_by('date').last()
if sound_log and sound_log.source != diff_log.source:
return None, []
# last diff is still playing: get the remaining playlist
sounds = Log.get_for(model = programs.Sound) \
.filter(station = station, source = diff_log.source) \
.filter(pk__gt = diff.log.pk)
@ -94,13 +108,13 @@ class Monitor:
diff = programs.Diffusion.get(
now, now = True,
type = programs.Diffusion.Type.normal,
sound__type = programs.Sound.Type.archive,
sound__removed = False,
**args
).distinct().order_by('start').first()
return (diff, diff and diff.playlist or [])
def handle(self):
"""
Handle scheduled diffusion, trigger if needed, preload playlists
@ -116,7 +130,7 @@ class Monitor:
diff, playlist = self.__current_diff()
dealer.on = bool(playlist)
next_diff, next_playlist = self.__next_diff()
next_diff, next_playlist = self.__next_diff(diff)
playlist += next_playlist
# playlist update
@ -125,7 +139,7 @@ class Monitor:
if next_diff:
self.log(
type = Log.Type.load,
source = dealer.id,
source = dealer.id_,
date = now,
related_object = next_diff
)
@ -137,7 +151,7 @@ class Monitor:
source.controller.skip()
cl.log(
type = Log.Type.play,
source = dealer.id,
source = dealer.id_,
date = now,
related_object = next_diff,
)

View File

@ -34,17 +34,20 @@ class StationController(plugins.StationController):
def fetch(self):
super().fetch()
data = self._send('request.on_air')
if not data:
rid = self._send('request.on_air')
if not rid:
return
data = self._send('request.metadata', data, parse = True)
data = self._send('request.metadata', rid, parse = True)
if not data:
return
self.current_sound = data.get('initial_uri')
# FIXME: point to the Source object
self.current_source = data.get('source')
self.current_source = [
# we assume sound is always from a registered source
source for source in self.station.get_sources()
if source.rid = rid
][0]
class SourceController(plugins.SourceController):
@ -77,10 +80,7 @@ class SourceController(plugins.SourceController):
if not data:
return
# FIXME: still usefull? originally tested only if there ass self.program
source = data.get('source') or ''
if not source.startswith(self.id):
return
self.rid = data.get('rid')
self.current_sound = data.get('initial_uri')
def stream(self):

View File

@ -53,10 +53,10 @@ class StationController:
"""
Current sound being played (retrieved by fetch)
"""
@property
def id(self):
return '{station.slug}_{station.pk}'.format(station = self.station)
current_source = None
"""
Current source object that is responsible of self.current_sound
"""
# TODO: add function to launch external program?
@ -72,6 +72,7 @@ class StationController:
"""
sources = self.station.get_sources()
for source in sources:
source.prepare()
if source.controller:
source.controller.fetch()
@ -110,7 +111,6 @@ class StationController:
pass
class SourceController:
"""
Controller of a Source. Value are usually updated directly on the
@ -138,10 +138,6 @@ class SourceController:
Current source being responsible of the current sound
"""
@property
def id(self):
return '{source.station.slug}_{source.slug}'.format(source = self.source)
__playlist = None
@property

View File

@ -39,7 +39,9 @@
- list of played diffusions and tracks when non-stop;
# Long term TODO
- automatic cancel of passed diffusion based on logs
- automatic cancel of passed diffusion based on logs?
- archives can be set afterwards for rerun, so check must be done
at the same time we monitor
- sounds monitor: max_size of path, take in account
- logs: archive functionnality
- track stats for diffusions