forked from rc/aircox
		
	make scheduled diffusion work on controllers
This commit is contained in:
		@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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):
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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')
 | 
			
		||||
 | 
			
		||||
@ -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:
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user