forked from rc/aircox
		
	liquidsoap: fix error in template, station.current_source on request's id
This commit is contained in:
		@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
@ -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):
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user