add 'live' log type, and handle it in streamer
This commit is contained in:
parent
086eb7ba2f
commit
8a129da46a
|
@ -18,6 +18,13 @@ from django.utils import timezone as tz
|
|||
from aircox.models import Station, Diffusion, Track, Sound, Log
|
||||
|
||||
|
||||
class Tracer:
|
||||
"""
|
||||
Keep trace of played item and update logs in adequation to it
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Monitor:
|
||||
"""
|
||||
Log and launch diffusions for the given station.
|
||||
|
@ -65,11 +72,12 @@ class Monitor:
|
|||
self.sync_playlists()
|
||||
self.handle()
|
||||
|
||||
def log(self, **kwargs):
|
||||
def log(self, date = None, **kwargs):
|
||||
"""
|
||||
Create a log using **kwargs, and print info
|
||||
"""
|
||||
log = Log(station = self.station, **kwargs)
|
||||
log = Log(station = self.station, date = date or tz.now(),
|
||||
**kwargs)
|
||||
log.save()
|
||||
log.print()
|
||||
|
||||
|
@ -147,8 +155,8 @@ class Monitor:
|
|||
for source in self.station.sources:
|
||||
if source == self.station.dealer:
|
||||
continue
|
||||
playlist = [ sound.path for sound in
|
||||
source.program.sound_set.all() ]
|
||||
playlist = source.program.sound_set.all() \
|
||||
.values_list('path', flat = True)
|
||||
source.playlist = playlist
|
||||
|
||||
def trace_canceled(self):
|
||||
|
@ -187,52 +195,78 @@ class Monitor:
|
|||
station = self.station
|
||||
now = tz.now()
|
||||
|
||||
diff_log = station.played(models = Diffusion) \
|
||||
.order_by('date').last()
|
||||
if not diff_log or \
|
||||
not diff_log.related.is_date_in_range(now):
|
||||
log = station.played(models = Diffusion).order_by('date').last()
|
||||
if not log or not log.related.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) \
|
||||
.filter(date__gte = diff_log.date) \
|
||||
.filter(date__gte = log.date) \
|
||||
.order_by('date')
|
||||
|
||||
if sounds.last() and sounds.last().source != diff_log.source:
|
||||
return diff_log, []
|
||||
# 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 the remaining playlist
|
||||
sounds = sounds.filter(
|
||||
source = diff_log.source, pk__gt = diff_log.pk
|
||||
)
|
||||
sounds = [
|
||||
sound.related.path for sound in sounds
|
||||
if sound.related.type != Sound.Type.removed
|
||||
]
|
||||
# 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)
|
||||
|
||||
return (
|
||||
diff_log.related,
|
||||
[ path for path in diff_log.related.playlist
|
||||
if path not in sounds ]
|
||||
)
|
||||
return log.related, remaining
|
||||
|
||||
def __next_diff(self, diff):
|
||||
"""
|
||||
Return the tuple with the next diff that should be played and
|
||||
the playlist
|
||||
|
||||
Note: diff is a log
|
||||
Return the next diffusion to be played as tuple of (diff, playlist).
|
||||
If diff is given, it is the one to be played right after it.
|
||||
"""
|
||||
station = self.station
|
||||
now = tz.now()
|
||||
|
||||
args = {'start__gt': diff.date } if diff else {}
|
||||
diff = Diffusion.objects.at(station, now).filter(
|
||||
type = Diffusion.Type.normal,
|
||||
sound__type = Sound.Type.archive,
|
||||
**args
|
||||
).distinct().order_by('start').first()
|
||||
return (diff, diff and diff.playlist or [])
|
||||
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
|
||||
|
||||
def handle_pl_sync(self, source, playlist, diff = None, date = None):
|
||||
"""
|
||||
Update playlist of a source if required, and handle logging when
|
||||
it is needed.
|
||||
"""
|
||||
dealer = self.station.dealer
|
||||
if dealer.playlist != playlist:
|
||||
dealer.playlist = playlist
|
||||
if diff and not diff.is_live():
|
||||
self.log(type = Log.Type.load, source = source.id,
|
||||
related = 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:
|
||||
return
|
||||
|
||||
# live: just log it
|
||||
if diff.is_live():
|
||||
if not Log.get_for(object = diff).count():
|
||||
self.log(type = Log.Type.live, source = source.id,
|
||||
related = 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)
|
||||
|
||||
def handle(self):
|
||||
"""
|
||||
|
@ -246,33 +280,15 @@ class Monitor:
|
|||
now = tz.now()
|
||||
|
||||
# current and next diffs
|
||||
diff, playlist = self.__current_diff()
|
||||
dealer.active = bool(playlist)
|
||||
current_diff, current_pl = self.__current_diff()
|
||||
next_diff, next_pl = self.__next_diff(diff)
|
||||
|
||||
next_diff, next_playlist = self.__next_diff(diff)
|
||||
playlist += next_playlist
|
||||
# playlist
|
||||
dealer.active = bool(current_pl)
|
||||
playlist = current_pl + next_pl
|
||||
|
||||
# playlist update
|
||||
if dealer.playlist != playlist:
|
||||
dealer.playlist = playlist
|
||||
if next_diff:
|
||||
self.log(
|
||||
type = Log.Type.load,
|
||||
source = dealer.id,
|
||||
date = now,
|
||||
related = next_diff
|
||||
)
|
||||
|
||||
# dealer.on when next_diff start <= now
|
||||
if next_diff and not dealer.active and \
|
||||
next_diff.start <= now:
|
||||
dealer.active = True
|
||||
self.log(
|
||||
type = Log.Type.play,
|
||||
source = dealer.id,
|
||||
date = now,
|
||||
related = next_diff,
|
||||
)
|
||||
self.handle_pl_sync(dealer, playlist, next_diff, now)
|
||||
self.handle_diff_start(dealer, next_diff)
|
||||
|
||||
|
||||
class Command (BaseCommand):
|
||||
|
|
|
@ -231,11 +231,11 @@ class Station(Nameable):
|
|||
self.__prepare()
|
||||
return self.__streamer
|
||||
|
||||
def played(self, models, archives = True):
|
||||
def played(self, models, archives = True, include_live = True):
|
||||
"""
|
||||
Call Log.objects.played for this station
|
||||
"""
|
||||
return Log.objects.played(self, models, archives)
|
||||
return Log.objects.played(self, models, archives, include_live)
|
||||
|
||||
@staticmethod
|
||||
def __mix_logs_and_diff(diffs, logs, count = 0):
|
||||
|
@ -867,7 +867,7 @@ class Diffusion(models.Model):
|
|||
"""
|
||||
List of archives' path; uses get_archives
|
||||
"""
|
||||
return [ sound.path for sound in self.get_archives() ]
|
||||
return self.get_archives().values_list('path', flat = True)
|
||||
|
||||
def get_archives(self):
|
||||
"""
|
||||
|
@ -1260,7 +1260,7 @@ class LogManager(RelatedManager):
|
|||
qs = self.get_for(station, object, model, qs)
|
||||
return self._at(date, qs)
|
||||
|
||||
def played(self, station, models, archives = True):
|
||||
def played(self, station, models, archives = True, include_live = True):
|
||||
"""
|
||||
Return a queryset of the played elements' log for the given
|
||||
station and model. This queryset is ordered by date ascending
|
||||
|
@ -1270,6 +1270,10 @@ class LogManager(RelatedManager):
|
|||
* archives: if false, exclude log of diffusion's archives from
|
||||
the queryset;
|
||||
"""
|
||||
if include_live:
|
||||
qs = self.get_for(station, model = models) \
|
||||
.filter(type__in = (Log.Type.play, Log.Type.live))
|
||||
else:
|
||||
qs = self.get_for(station, model = models) \
|
||||
.filter(type = Log.Type.play)
|
||||
|
||||
|
@ -1303,7 +1307,11 @@ class Log(Related):
|
|||
"""
|
||||
Source starts to be preload related_object
|
||||
"""
|
||||
other = 0x03
|
||||
live = 0x03
|
||||
"""
|
||||
A diffusion occured, but in live (no sound played by Aircox)
|
||||
"""
|
||||
other = 0x04
|
||||
"""
|
||||
Other log
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue
Block a user