work on player: integrate vuejs + noscript; remove TemplateMixin for Component and ExposedData; rewrite most of the player; clean up files; do lot of other things

This commit is contained in:
bkfox
2018-02-08 06:46:42 +01:00
parent 343279a777
commit d80322dd15
36 changed files with 12711 additions and 1740 deletions

View File

@ -97,7 +97,7 @@ class ProgramAdmin(NameableAdmin):
@admin.register(Diffusion)
class DiffusionAdmin(admin.ModelAdmin):
def archives(self, obj):
sounds = [ str(s) for s in obj.get_archives()]
sounds = [ str(s) for s in obj.get_sounds(archive=True)]
return ', '.join(sounds) if sounds else ''
def conflicts_(self, obj):

View File

@ -297,7 +297,7 @@ class Source:
A playlist from a program uses all its available archives.
"""
if diffusion:
self.playlist = diffusion.playlist
self.playlist = diffusion.get_playlist(archive = True)
return
program = program or self.program

View File

@ -1,3 +1,4 @@
#! /usr/bin/env python3
"""
Monitor sound files; For each program, check for:
- new files;

View File

@ -176,7 +176,7 @@ class Monitor:
last_diff = self.last_diff_start
diff = None
if last_diff and not last_diff.is_expired():
archives = last_diff.diffusion.get_archives()
archives = last_diff.diffusion.sounds(archive = True)
if archives.filter(pk = sound.pk).exists():
diff = last_diff.diffusion
@ -294,7 +294,8 @@ class Monitor:
.filter(source = log.source, pk__gt = log.pk) \
.exclude(sound__type = Sound.Type.removed)
remaining = log.diffusion.get_archives().exclude(pk__in = sounds) \
remaining = log.diffusion.sounds(archive = True) \
.exclude(pk__in = sounds) \
.values_list('path', flat = True)
return log.diffusion, list(remaining)
@ -312,7 +313,7 @@ class Monitor:
.filter(type = Diffusion.Type.normal, **kwargs) \
.distinct().order_by('start')
diff = diff.first()
return (diff, diff and diff.playlist or [])
return (diff, diff and diff.get_playlist(archive = True) or [])
def handle_pl_sync(self, source, playlist, diff = None, date = None):
"""

View File

@ -59,6 +59,7 @@ class Related(models.Model):
related_type = models.ForeignKey(
ContentType,
blank = True, null = True,
on_delete=models.SET_NULL,
)
related_id = models.PositiveIntegerField(
blank = True, null = True,
@ -332,6 +333,7 @@ class Program(Nameable):
station = models.ForeignKey(
Station,
verbose_name = _('station'),
on_delete=models.CASCADE,
)
active = models.BooleanField(
_('active'),
@ -438,6 +440,7 @@ class Stream(models.Model):
program = models.ForeignKey(
Program,
verbose_name = _('related program'),
on_delete=models.CASCADE,
)
delay = models.TimeField(
_('delay'),
@ -483,6 +486,7 @@ class Schedule(models.Model):
program = models.ForeignKey(
Program,
verbose_name = _('related program'),
on_delete=models.CASCADE,
)
time = models.TimeField(
_('time'),
@ -839,6 +843,7 @@ class Diffusion(models.Model):
program = models.ForeignKey (
Program,
verbose_name = _('program'),
on_delete=models.CASCADE,
)
# specific
type = models.SmallIntegerField(
@ -904,34 +909,31 @@ class Diffusion(models.Model):
self._local_end = tz.localtime(self.end, tz.get_current_timezone())
return self._local_end
@property
def playlist(self):
"""
List of archives' path; uses get_archives
"""
playlist = self.get_archives().values_list('path', flat = True)
return list(playlist)
def is_live(self):
return self.type == self.Type.normal and \
not self.get_archives().count()
not self.get_sounds(archive = True).count()
def get_archives(self):
"""
Return a list of available archives sounds for the given episode,
ordered by path.
"""
sounds = self.initial.sound_set if self.initial else self.sound_set
return sounds.filter(type = Sound.Type.archive).order_by('path')
def get_excerpts(self):
def get_playlist(self, **types):
"""
Return a list of available archives sounds for the given episode,
ordered by path.
Returns sounds as a playlist (list of *local* file path).
The given arguments are passed to ``get_sounds``.
"""
sounds = self.initial.sound_set if self.initial else self.sound_set
return sounds.filter(type = Sound.Type.excerpt).order_by('path')
return list(self.get_sounds(archives = True) \
.filter(path__isnull = False) \
.values_list('path', flat = True))
def get_sounds(self, **types):
"""
Return a queryset of sounds related to this diffusion,
ordered by type then path.
**types: filter on the given sound types name, as `archive=True`
"""
sounds = (self.initial or self).sound_set.order_by('type', 'path')
_in = [ getattr(Sound.Type, name)
for name, value in types.items() if value ]
return sounds.filter(type__in = _in)
def is_date_in_range(self, date = None):
"""
@ -1012,6 +1014,7 @@ class Sound(Nameable):
Program,
verbose_name = _('program'),
blank = True, null = True,
on_delete=models.SET_NULL,
help_text = _('program related to it'),
)
diffusion = models.ForeignKey(
@ -1026,11 +1029,13 @@ class Sound(Nameable):
choices = [ (int(y), _(x)) for x,y in Type.__members__.items() ],
blank = True, null = True
)
# FIXME: url() does not use the same directory than here
# should we use FileField for more reliability?
path = models.FilePathField(
_('file'),
path = settings.AIRCOX_PROGRAMS_DIR,
match = r'(' + '|'.join(settings.AIRCOX_SOUND_FILE_EXT) \
.replace('.', r'\.') + ')$',
match = r'(' + '|'.join(settings.AIRCOX_SOUND_FILE_EXT)
.replace('.', r'\.') + ')$',
recursive = True,
blank = True, null = True,
unique = True,
@ -1229,6 +1234,7 @@ class Port (models.Model):
station = models.ForeignKey(
Station,
verbose_name = _('station'),
on_delete=models.CASCADE,
)
direction = models.SmallIntegerField(
_('direction'),
@ -1464,6 +1470,7 @@ class Log(models.Model):
station = models.ForeignKey(
Station,
verbose_name = _('station'),
on_delete=models.CASCADE,
help_text = _('related station'),
)
source = models.CharField(