add script to import playlists to sounds or to diffusions
This commit is contained in:
@ -39,6 +39,11 @@ class Station(programs.Nameable):
|
||||
max_length = 32,
|
||||
choices = [ (name, name) for name in Plugins.registry.keys() ],
|
||||
)
|
||||
active = models.BooleanField(
|
||||
_('active'),
|
||||
default = True,
|
||||
help_text = _('this station is active')
|
||||
)
|
||||
|
||||
plugin = None
|
||||
"""
|
||||
@ -127,24 +132,22 @@ 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):
|
||||
def get_played(self, models, archives = True):
|
||||
"""
|
||||
Return a queryset with log of played elements on this station.
|
||||
Ordered by date ascending.
|
||||
"""
|
||||
models = []
|
||||
if include_diffusions: models.append(programs.Diffusion)
|
||||
if include_sounds: models.append(programs.Sound)
|
||||
Return a queryset with log of played elements on this station,
|
||||
of the given models, ordered by date ascending.
|
||||
|
||||
* model: a model or a list of models
|
||||
* archive: if false, exclude log of diffusion's archives from
|
||||
the queryset;
|
||||
"""
|
||||
qs = Log.get_for(model = models) \
|
||||
.filter(station = station, type = Log.Type.play)
|
||||
if exclude_archives and self.dealer:
|
||||
if not archives and self.dealer:
|
||||
qs = qs.exclude(
|
||||
source = self.dealer.id_,
|
||||
related_type = ContentType.objects.get_for_model(
|
||||
program.Sound
|
||||
programs.Sound
|
||||
)
|
||||
)
|
||||
return qs.order_by('date')
|
||||
@ -294,7 +297,6 @@ class Source(programs.Nameable):
|
||||
raise ValueError('can not save a dealer source')
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
# TODO update controls
|
||||
|
||||
|
||||
class Output (models.Model):
|
||||
@ -326,7 +328,7 @@ class Output (models.Model):
|
||||
)
|
||||
|
||||
|
||||
class Log(models.Model):
|
||||
class Log(programs.Related):
|
||||
"""
|
||||
Log sounds and diffusions that are played on the station.
|
||||
|
||||
@ -376,16 +378,6 @@ class Log(models.Model):
|
||||
max_length = 512,
|
||||
blank = True, null = True,
|
||||
)
|
||||
related_type = models.ForeignKey(
|
||||
ContentType,
|
||||
blank = True, null = True,
|
||||
)
|
||||
related_id = models.PositiveIntegerField(
|
||||
blank = True, null = True,
|
||||
)
|
||||
related = GenericForeignKey(
|
||||
'related_type', 'related_id',
|
||||
)
|
||||
|
||||
@property
|
||||
def end(self):
|
||||
@ -407,29 +399,6 @@ class Log(models.Model):
|
||||
date = programs.date_or_default(date)
|
||||
return self.end < date
|
||||
|
||||
@classmethod
|
||||
def get_for(cl, object = None, model = None):
|
||||
"""
|
||||
Return a queryset that filter on the related object. If object is
|
||||
given, filter using it, otherwise only using model.
|
||||
|
||||
If model is not given, uses object's type.
|
||||
"""
|
||||
if not model and object:
|
||||
model = type(object)
|
||||
|
||||
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
|
||||
|
||||
def print(self):
|
||||
logger.info('log #%s: %s%s',
|
||||
str(self),
|
||||
|
@ -10,6 +10,11 @@ class Monitor:
|
||||
Monitor should be able to be used after a crash a go back
|
||||
where it was playing, so we heavily use logs to be able to
|
||||
do that.
|
||||
|
||||
We keep trace of played items on the generated stream:
|
||||
- sounds played on this stream;
|
||||
- scheduled diffusions
|
||||
- tracks for sounds of streamed programs
|
||||
"""
|
||||
station = None
|
||||
controller = None
|
||||
@ -22,11 +27,10 @@ class Monitor:
|
||||
self.station.prepare()
|
||||
self.controller = self.station.controller
|
||||
|
||||
self.track()
|
||||
self.trace()
|
||||
self.handler()
|
||||
|
||||
@staticmethod
|
||||
def log(**kwargs):
|
||||
def log(self, **kwargs):
|
||||
"""
|
||||
Create a log using **kwargs, and print info
|
||||
"""
|
||||
@ -34,10 +38,10 @@ class Monitor:
|
||||
log.save()
|
||||
log.print()
|
||||
|
||||
def track(self):
|
||||
def trace(self):
|
||||
"""
|
||||
Check the current_sound of the station and update logs if
|
||||
needed
|
||||
needed.
|
||||
"""
|
||||
self.controller.fetch()
|
||||
current_sound = self.controller.current_sound
|
||||
@ -47,6 +51,11 @@ class Monitor:
|
||||
|
||||
log = Log.get_for(model = programs.Sound) \
|
||||
.filter(station = self.station).order_by('date').last()
|
||||
|
||||
# only streamed
|
||||
if log and not log.related.diffusion:
|
||||
self.trace_sound_tracks(log)
|
||||
|
||||
# TODO: expiration
|
||||
if log and (log.source == current_source.id_ and \
|
||||
log.related.path == current_sound):
|
||||
@ -56,12 +65,37 @@ class Monitor:
|
||||
self.log(
|
||||
type = Log.Type.play,
|
||||
source = current_source.id_,
|
||||
date = tz.make_aware(tz.datetime.now()),
|
||||
|
||||
date = tz.now(),
|
||||
related = sound[0] if sound else None,
|
||||
comment = None if sound else current_sound,
|
||||
)
|
||||
|
||||
def trace_sound_tracks(self, log):
|
||||
"""
|
||||
Log tracks for the given sound (for streamed programs); Called by
|
||||
self.trace
|
||||
"""
|
||||
logs = Log.get_for(model = programs.Track) \
|
||||
.filter(pk__gt = log.pk)
|
||||
logs = [ log.pk for log in logs ]
|
||||
|
||||
tracks = programs.Track.get_for(object = log.related)
|
||||
.filter(pos_in_sec = True)
|
||||
if len(tracks) == len(logs):
|
||||
return
|
||||
|
||||
tracks = tracks.exclude(pk__in = logs).order_by('pos')
|
||||
now = tz.now()
|
||||
for track in tracks:
|
||||
pos = log.date + tz.timedelta(seconds = track.pos)
|
||||
if pos < now:
|
||||
self.log(
|
||||
type = Log.Type.play,
|
||||
source = log.source,
|
||||
date = pos,
|
||||
related = track
|
||||
)
|
||||
|
||||
def __current_diff(self):
|
||||
"""
|
||||
Return a tuple with the currently running diffusion and the items
|
||||
@ -70,24 +104,23 @@ class Monitor:
|
||||
station = self.station
|
||||
now = tz.make_aware(tz.datetime.now())
|
||||
|
||||
diff_log = Log.get_for(model = programs.Diffusion) \
|
||||
.filter(station = station, type = Log.Type.play) \
|
||||
.order_by('date').last()
|
||||
diff_log = station.get_played(models = programs.Diffusion) \
|
||||
.order_by('date').last()
|
||||
|
||||
if not diff_log or \
|
||||
not diff_log.related.is_date_in_my_range(now):
|
||||
return None, []
|
||||
|
||||
# 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:
|
||||
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, []
|
||||
|
||||
# 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)
|
||||
sounds = sounds.filter(
|
||||
source = diff_log.source, pk__gt = diff_log.pk
|
||||
)
|
||||
sounds = [ sound.path for sound in sounds if not sound.removed ]
|
||||
|
||||
return (
|
||||
|
Reference in New Issue
Block a user