forked from rc/aircox
		
	fix and optimize
This commit is contained in:
		@ -15,7 +15,7 @@ from django.conf import settings as main_settings
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from django.utils import timezone as tz
 | 
			
		||||
 | 
			
		||||
from aircox.models import Station, Diffusion, Track, Sound, Log
 | 
			
		||||
from aircox.models import Station, Diffusion, Track, Sound, Log #, DiffusionLog, SoundLog
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Tracer:
 | 
			
		||||
@ -92,17 +92,18 @@ class Monitor:
 | 
			
		||||
        if not current_sound or not current_source:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        log = Log.objects.get_for(self.station, model = Sound) \
 | 
			
		||||
        log = Log.objects.station(self.station, sound__isnull = False) \
 | 
			
		||||
                         .select_related('sound') \
 | 
			
		||||
                         .order_by('date').last()
 | 
			
		||||
 | 
			
		||||
        # only streamed
 | 
			
		||||
        if log and (log.related and not log.related.diffusion):
 | 
			
		||||
        # only streamed ns
 | 
			
		||||
        if log and not log.sound.diffusion:
 | 
			
		||||
            self.trace_sound_tracks(log)
 | 
			
		||||
 | 
			
		||||
        # TODO: expiration
 | 
			
		||||
        if log and (log.source == current_source.id and \
 | 
			
		||||
                log.related and
 | 
			
		||||
                log.related.path == current_sound):
 | 
			
		||||
                log.sound and
 | 
			
		||||
                log.sound.path == current_sound):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        sound = Sound.objects.filter(path = current_sound)
 | 
			
		||||
@ -110,7 +111,7 @@ class Monitor:
 | 
			
		||||
            type = Log.Type.play,
 | 
			
		||||
            source = current_source.id,
 | 
			
		||||
            date = tz.now(),
 | 
			
		||||
            related = sound[0] if sound else None,
 | 
			
		||||
            sound = sound[0] if sound else None,
 | 
			
		||||
            # keep sound path (if sound is removed, we keep that info)
 | 
			
		||||
            comment = current_sound,
 | 
			
		||||
        )
 | 
			
		||||
@ -120,11 +121,12 @@ class Monitor:
 | 
			
		||||
        Log tracks for the given sound (for streamed programs); Called by
 | 
			
		||||
        self.trace
 | 
			
		||||
        """
 | 
			
		||||
        logs = Log.objects.get_for(self.station, model = Track) \
 | 
			
		||||
                          .filter(pk__gt = log.pk)
 | 
			
		||||
        logs = [ log.related_id for log in logs ]
 | 
			
		||||
        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.related) \
 | 
			
		||||
        tracks = Track.objects.get_for(object = log.sound) \
 | 
			
		||||
                              .filter(in_seconds = True)
 | 
			
		||||
        if tracks and len(tracks) == len(logs):
 | 
			
		||||
            return
 | 
			
		||||
@ -138,7 +140,7 @@ class Monitor:
 | 
			
		||||
                    type = Log.Type.play,
 | 
			
		||||
                    source = log.source,
 | 
			
		||||
                    date = pos,
 | 
			
		||||
                    related = track,
 | 
			
		||||
                    track = track,
 | 
			
		||||
                    comment = track,
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
@ -157,7 +159,7 @@ class Monitor:
 | 
			
		||||
                continue
 | 
			
		||||
            playlist = source.program.sound_set.all() \
 | 
			
		||||
                             .values_list('path', flat = True)
 | 
			
		||||
            source.playlist = playlist
 | 
			
		||||
            source.playlist = list(playlist)
 | 
			
		||||
 | 
			
		||||
    def trace_canceled(self):
 | 
			
		||||
        """
 | 
			
		||||
@ -171,18 +173,18 @@ class Monitor:
 | 
			
		||||
            type = Diffusion.Type.normal,
 | 
			
		||||
            sound__type = Sound.Type.archive,
 | 
			
		||||
        )
 | 
			
		||||
        logs = station.played(models = Diffusion)
 | 
			
		||||
        logs = station.played(diffusion__isnull = False)
 | 
			
		||||
 | 
			
		||||
        date = tz.now() - datetime.timedelta(seconds = self.cancel_timeout)
 | 
			
		||||
        for diff in diffs:
 | 
			
		||||
            if logs.filter(related = diff):
 | 
			
		||||
            if logs.filter(diffusion = diff):
 | 
			
		||||
                continue
 | 
			
		||||
            if diff.start < now:
 | 
			
		||||
                diff.type = Diffusion.Type.canceled
 | 
			
		||||
                diff.save()
 | 
			
		||||
                self.log(
 | 
			
		||||
                    type = Log.Type.other,
 | 
			
		||||
                    related = diff,
 | 
			
		||||
                    diffusion = diff,
 | 
			
		||||
                    comment = 'Diffusion canceled after {} seconds' \
 | 
			
		||||
                              .format(self.cancel_timeout)
 | 
			
		||||
                )
 | 
			
		||||
@ -195,29 +197,29 @@ class Monitor:
 | 
			
		||||
        station = self.station
 | 
			
		||||
        now = tz.now()
 | 
			
		||||
 | 
			
		||||
        log = station.played(models = Diffusion).order_by('date').last()
 | 
			
		||||
        if not log or not log.related.is_date_in_range(now):
 | 
			
		||||
        log = station.played(diffusion__isnull = False) \
 | 
			
		||||
                     .select_related('diffusion') \
 | 
			
		||||
                     .order_by('date').last()
 | 
			
		||||
        if not log or not log.diffusion.is_date_in_range(now):
 | 
			
		||||
            # not running anymore
 | 
			
		||||
            return None, []
 | 
			
		||||
 | 
			
		||||
        # sound has switched? assume it has been (forced to) stopped
 | 
			
		||||
        sounds = station.played(models = Sound) \
 | 
			
		||||
        # last sound source change: end of file reached or forced to stop
 | 
			
		||||
        sounds = station.played(sound__isnull = False) \
 | 
			
		||||
                        .filter(date__gte = log.date) \
 | 
			
		||||
                        .order_by('date')
 | 
			
		||||
 | 
			
		||||
        # last sound source change: end of file reached
 | 
			
		||||
        if sounds.count() and sounds.last().source != log.source:
 | 
			
		||||
            # diffusion is finished: end of sound file reached
 | 
			
		||||
            return None, []
 | 
			
		||||
 | 
			
		||||
        # last diff is still playing: get remaining playlist
 | 
			
		||||
        sounds = sounds \
 | 
			
		||||
            .filter(source = log.source, pk__gt = diff_log.pk) \
 | 
			
		||||
            .exclude(related__type = Sound.Type.removed)
 | 
			
		||||
            .values_list('related__path', flat = True)
 | 
			
		||||
        remaining = log.related.get_archives().exclude(path__in = sounds)
 | 
			
		||||
            .filter(source = log.source, pk__gt = log.pk) \
 | 
			
		||||
            .exclude(sound__type = Sound.Type.removed)
 | 
			
		||||
 | 
			
		||||
        return log.related, remaining
 | 
			
		||||
        remaining = log.diffusion.get_archives().exclude(pk__in = sounds) \
 | 
			
		||||
                       .values_list('path', flat = True)
 | 
			
		||||
        return log.diffusion, list(remaining)
 | 
			
		||||
 | 
			
		||||
    def __next_diff(self, diff):
 | 
			
		||||
        """
 | 
			
		||||
@ -230,10 +232,10 @@ class Monitor:
 | 
			
		||||
        kwargs = {'start__gte': diff.end } if diff else {}
 | 
			
		||||
        diff = Diffusion.objects \
 | 
			
		||||
            .at(station, now) \
 | 
			
		||||
            .filter(type = Diffusion.Type.normal,
 | 
			
		||||
                    sound_type = Sound.Type.archive, **kwargs) \
 | 
			
		||||
            .distinct().order_by('start').first()
 | 
			
		||||
        return diff
 | 
			
		||||
            .filter(type = Diffusion.Type.normal, **kwargs) \
 | 
			
		||||
            .distinct().order_by('start')
 | 
			
		||||
        diff = diff.first()
 | 
			
		||||
        return (diff, diff and diff.playlist or [])
 | 
			
		||||
 | 
			
		||||
    def handle_pl_sync(self, source, playlist, diff = None, date = None):
 | 
			
		||||
        """
 | 
			
		||||
@ -245,28 +247,30 @@ class Monitor:
 | 
			
		||||
            dealer.playlist = playlist
 | 
			
		||||
            if diff and not diff.is_live():
 | 
			
		||||
                self.log(type = Log.Type.load, source = source.id,
 | 
			
		||||
                         related = diff, date = date)
 | 
			
		||||
                         diffusion = diff, date = date)
 | 
			
		||||
 | 
			
		||||
    def handle_diff_start(self, source, diff, date):
 | 
			
		||||
        """
 | 
			
		||||
        Enable dealer in order to play a given diffusion if required,
 | 
			
		||||
        handle start of diffusion
 | 
			
		||||
        """
 | 
			
		||||
        if not diff or not diff.start <= now:
 | 
			
		||||
        if not diff or diff.start > date:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        # live: just log it
 | 
			
		||||
        if diff.is_live():
 | 
			
		||||
            if not Log.get_for(object = diff).count():
 | 
			
		||||
            diff_ = Log.objects.station(self.station) \
 | 
			
		||||
                       .filter(diffusion = diff)
 | 
			
		||||
            if not diff_.count():
 | 
			
		||||
                self.log(type = Log.Type.live, source = source.id,
 | 
			
		||||
                         related = diff, date = date)
 | 
			
		||||
                         diffusion = diff, date = date)
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        # enable dealer
 | 
			
		||||
        if not dealer.active:
 | 
			
		||||
            dealer.active = True
 | 
			
		||||
            self.log(type = Log.Type.play, source = source.id,
 | 
			
		||||
                     related = diff, date = date)
 | 
			
		||||
                     diffusion = diff, date = date)
 | 
			
		||||
 | 
			
		||||
    def handle(self):
 | 
			
		||||
        """
 | 
			
		||||
@ -280,15 +284,15 @@ class Monitor:
 | 
			
		||||
        now = tz.now()
 | 
			
		||||
 | 
			
		||||
        # current and next diffs
 | 
			
		||||
        current_diff, current_pl = self.__current_diff()
 | 
			
		||||
        next_diff, next_pl = self.__next_diff(diff)
 | 
			
		||||
        current_diff, remaining_pl = self.__current_diff()
 | 
			
		||||
        next_diff, next_pl = self.__next_diff(current_diff)
 | 
			
		||||
 | 
			
		||||
        # playlist
 | 
			
		||||
        dealer.active = bool(current_pl)
 | 
			
		||||
        playlist = current_pl + next_pl
 | 
			
		||||
        dealer.active = bool(remaining_pl)
 | 
			
		||||
        playlist = remaining_pl + next_pl
 | 
			
		||||
 | 
			
		||||
        self.handle_pl_sync(dealer, playlist, next_diff, now)
 | 
			
		||||
        self.handle_diff_start(dealer, next_diff)
 | 
			
		||||
        self.handle_diff_start(dealer, next_diff, now)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command (BaseCommand):
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user