forked from rc/aircox
		
	work on streamer, change a bit how it works; make archiving
This commit is contained in:
		@ -14,6 +14,7 @@ from argparse import RawTextHelpFormatter
 | 
			
		||||
from django.conf import settings as main_settings
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from django.utils import timezone as tz
 | 
			
		||||
from django.utils.functional import cached_property
 | 
			
		||||
 | 
			
		||||
from aircox.models import Station, Diffusion, Track, Sound, Log #, DiffusionLog, SoundLog
 | 
			
		||||
 | 
			
		||||
@ -54,17 +55,41 @@ class Monitor:
 | 
			
		||||
    Datetime of the next sync
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    _last_log = None
 | 
			
		||||
    """
 | 
			
		||||
    Last emitted log
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def _last_log(self, **kwargs):
 | 
			
		||||
        return Log.objects.station(self.station, **kwargs) \
 | 
			
		||||
                  .select_related('diffusion', 'sound') \
 | 
			
		||||
                  .order_by('date').last()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def last_log(self):
 | 
			
		||||
        """
 | 
			
		||||
        Last log of monitored station
 | 
			
		||||
        """
 | 
			
		||||
        return self._last_log()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def last_sound(self):
 | 
			
		||||
        """
 | 
			
		||||
        Last sound log of monitored station that occurred on_air
 | 
			
		||||
        """
 | 
			
		||||
        return self._last_log(type = Log.Type.on_air,
 | 
			
		||||
                              sound__isnull = False)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def last_diff_start(self):
 | 
			
		||||
        """
 | 
			
		||||
        Log of last triggered item (sound or diffusion)
 | 
			
		||||
        """
 | 
			
		||||
        return self._last_log(type = Log.Type.start,
 | 
			
		||||
                              diffusion__isnull = False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def __init__(self, station, **kwargs):
 | 
			
		||||
        self.station = station
 | 
			
		||||
        self.__dict__.update(kwargs)
 | 
			
		||||
 | 
			
		||||
        self._last_log = Log.objects.station(station).order_by('date') \
 | 
			
		||||
                            .last()
 | 
			
		||||
        now = tz.now()
 | 
			
		||||
 | 
			
		||||
    def monitor(self):
 | 
			
		||||
        """
 | 
			
		||||
@ -91,9 +116,9 @@ class Monitor:
 | 
			
		||||
 | 
			
		||||
        # update last log
 | 
			
		||||
        if log.type != Log.Type.other and \
 | 
			
		||||
                self._last_log and not self._last_log.end:
 | 
			
		||||
            self._last_log.end = log.date
 | 
			
		||||
        self._last_log = log
 | 
			
		||||
                self.last_log and not self.last_log.end:
 | 
			
		||||
            self.last_log.end = log.date
 | 
			
		||||
        return log
 | 
			
		||||
 | 
			
		||||
    def trace(self):
 | 
			
		||||
        """
 | 
			
		||||
@ -106,51 +131,59 @@ class Monitor:
 | 
			
		||||
        if not current_sound or not current_source:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        log = Log.objects.station(self.station, sound__isnull = False) \
 | 
			
		||||
                         .select_related('sound') \
 | 
			
		||||
                         .order_by('date').last()
 | 
			
		||||
        # last log can be anything, so we need to keep track of the last
 | 
			
		||||
        # sound log too
 | 
			
		||||
        # sound on air can be of a diffusion or a stream.
 | 
			
		||||
 | 
			
		||||
        # only streamed ns
 | 
			
		||||
        if log and not log.sound.diffusion:
 | 
			
		||||
        log = self.last_log
 | 
			
		||||
 | 
			
		||||
        # sound on air changed
 | 
			
		||||
        if log.source != current_source.id or \
 | 
			
		||||
                (log.sound and log.sound.path != current_sound):
 | 
			
		||||
            sound = Sound.objects.filter(path = current_sound).first()
 | 
			
		||||
 | 
			
		||||
            # find diff
 | 
			
		||||
            last_diff = self.last_diff_start
 | 
			
		||||
            diff = None
 | 
			
		||||
            if not last_diff.is_expired():
 | 
			
		||||
                archives = last_diff.diffusion.get_archives()
 | 
			
		||||
                if archives.filter(pk = sound.pk).exists():
 | 
			
		||||
                    diff = last_diff.diffusion
 | 
			
		||||
 | 
			
		||||
            # log sound on air
 | 
			
		||||
            log = self.log(
 | 
			
		||||
                type = Log.Type.on_air,
 | 
			
		||||
                source = current_source.id,
 | 
			
		||||
                date = tz.now(),
 | 
			
		||||
                sound = sound,
 | 
			
		||||
                diffusion = diff,
 | 
			
		||||
                # keep sound path (if sound is removed, we keep that info)
 | 
			
		||||
                comment = current_sound,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        # tracks -- only for sound's
 | 
			
		||||
        if not log.diffusion:
 | 
			
		||||
            self.trace_sound_tracks(log)
 | 
			
		||||
 | 
			
		||||
        # TODO: expiration
 | 
			
		||||
        if log and (log.source == current_source.id and \
 | 
			
		||||
                log.sound and
 | 
			
		||||
                log.sound.path == current_sound):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        sound = Sound.objects.filter(path = current_sound).first()
 | 
			
		||||
        self.log(
 | 
			
		||||
            type = Log.Type.on_air,
 | 
			
		||||
            source = current_source.id,
 | 
			
		||||
            date = tz.now(),
 | 
			
		||||
            sound = sound,
 | 
			
		||||
            # keep sound path (if sound is removed, we keep that info)
 | 
			
		||||
            comment = current_sound,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def trace_sound_tracks(self, log):
 | 
			
		||||
        """
 | 
			
		||||
        Log tracks for the given sound (for streamed programs); Called by
 | 
			
		||||
        self.trace
 | 
			
		||||
        Log tracks for the given sound log (for streamed programs).
 | 
			
		||||
        Called by self.trace
 | 
			
		||||
        """
 | 
			
		||||
        logs = Log.objects.station(self.station,
 | 
			
		||||
                                   track__isnull = False,
 | 
			
		||||
                                   pk__gt = log.pk) \
 | 
			
		||||
                          .values_list('sound__pk', flat = True)
 | 
			
		||||
 | 
			
		||||
        tracks = Track.objects.get_for(object = log.sound) \
 | 
			
		||||
                              .filter(in_seconds = True)
 | 
			
		||||
        if tracks and len(tracks) == len(logs):
 | 
			
		||||
        if not tracks.exists():
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        tracks = tracks.exclude(pk__in = logs).order_by('position')
 | 
			
		||||
        tracks = tracks.exclude(log__station = self.station,
 | 
			
		||||
                                log__pk__gt = log.pk)
 | 
			
		||||
        now = tz.now()
 | 
			
		||||
        for track in tracks:
 | 
			
		||||
            pos = log.date + tz.timedelta(seconds = track.position)
 | 
			
		||||
            if pos > now:
 | 
			
		||||
                break
 | 
			
		||||
            # log track on air
 | 
			
		||||
            self.log(
 | 
			
		||||
                type = Log.Type.on_air, source = log.source,
 | 
			
		||||
                date = pos, track = track,
 | 
			
		||||
@ -195,6 +228,7 @@ class Monitor:
 | 
			
		||||
            if diff.start < now:
 | 
			
		||||
                diff.type = Diffusion.Type.canceled
 | 
			
		||||
                diff.save()
 | 
			
		||||
                # log canceled diffusion
 | 
			
		||||
                self.log(
 | 
			
		||||
                    type = Log.Type.other,
 | 
			
		||||
                    diffusion = diff,
 | 
			
		||||
@ -254,13 +288,17 @@ class Monitor:
 | 
			
		||||
        """
 | 
			
		||||
        Update playlist of a source if required, and handle logging when
 | 
			
		||||
        it is needed.
 | 
			
		||||
 | 
			
		||||
        - source: source on which it happens
 | 
			
		||||
        - playlist: list of sounds to use to update
 | 
			
		||||
        - diff: related diffusion
 | 
			
		||||
        """
 | 
			
		||||
        dealer = self.station.dealer
 | 
			
		||||
        if dealer.playlist == playlist:
 | 
			
		||||
        if source.playlist == playlist:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        dealer.playlist = playlist
 | 
			
		||||
        source.playlist = playlist
 | 
			
		||||
        if diff and not diff.is_live():
 | 
			
		||||
            # log diffusion archive load
 | 
			
		||||
            self.log(type = Log.Type.load,
 | 
			
		||||
                     source = source.id,
 | 
			
		||||
                     diffusion = diff,
 | 
			
		||||
@ -284,6 +322,7 @@ class Monitor:
 | 
			
		||||
            diff_ = Log.objects.station(self.station) \
 | 
			
		||||
                       .filter(diffusion = diff, type = Log.Type.on_air)
 | 
			
		||||
            if not diff_.count():
 | 
			
		||||
                # log live diffusion
 | 
			
		||||
                self.log(type = Log.Type.on_air, source = source.id,
 | 
			
		||||
                         diffusion = diff, date = date)
 | 
			
		||||
            return
 | 
			
		||||
@ -291,8 +330,11 @@ class Monitor:
 | 
			
		||||
        # enable dealer
 | 
			
		||||
        if not source.active:
 | 
			
		||||
            source.active = True
 | 
			
		||||
            self.log(type = Log.Type.play, source = source.id,
 | 
			
		||||
                     diffusion = diff, date = date)
 | 
			
		||||
            last_start = self.last_start
 | 
			
		||||
            if last_start.diffusion_id != diff.pk:
 | 
			
		||||
                # log triggered diffusion
 | 
			
		||||
                self.log(type = Log.Type.start, source = source.id,
 | 
			
		||||
                         diffusion = diff, date = date)
 | 
			
		||||
 | 
			
		||||
    def handle(self):
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user