fix error in streamer and on_air

This commit is contained in:
bkfox 2017-07-02 18:09:40 +02:00
parent 013a0894ab
commit 08cb8e71bb
5 changed files with 108 additions and 52 deletions

View File

@ -54,10 +54,18 @@ class Monitor:
Datetime of the next sync
"""
_last_log = None
"""
Last emitted log
"""
def __init__(self, station, **kwargs):
self.station = station
self.__dict__.update(kwargs)
self._last_log = Log.objects.station(station).order_by('date') \
.last()
def monitor(self):
"""
Run all monitoring functions.
@ -81,6 +89,12 @@ class Monitor:
log.save()
log.print()
# 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
def trace(self):
"""
Check the current_sound of the station and update logs if
@ -106,12 +120,12 @@ class Monitor:
log.sound.path == current_sound):
return
sound = Sound.objects.filter(path = current_sound)
sound = Sound.objects.filter(path = current_sound).first()
self.log(
type = Log.Type.play,
type = Log.Type.on_air,
source = current_source.id,
date = tz.now(),
sound = sound[0] if sound else None,
sound = sound,
# keep sound path (if sound is removed, we keep that info)
comment = current_sound,
)
@ -135,14 +149,13 @@ class Monitor:
now = tz.now()
for track in tracks:
pos = log.date + tz.timedelta(seconds = track.position)
if pos < now:
self.log(
type = Log.Type.play,
source = log.source,
date = pos,
track = track,
comment = track,
)
if pos > now:
break
self.log(
type = Log.Type.on_air, source = log.source,
date = pos, track = track,
comment = track,
)
def sync_playlists(self):
"""
@ -243,11 +256,16 @@ class Monitor:
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,
diffusion = diff, date = date)
if dealer.playlist == playlist:
return
dealer.playlist = playlist
if diff and not diff.is_live():
self.log(type = Log.Type.load,
source = source.id,
diffusion = diff,
date = date,
comment = '\n'.join(playlist))
def handle_diff_start(self, source, diff, date):
"""
@ -257,18 +275,22 @@ class Monitor:
if not diff or diff.start > date:
return
# TODO: user has not yet put the diffusion sound when diff started
# => live logged; what we want: if user put a sound after it
# has been logged as live, load and start this sound
# live: just log it
if diff.is_live():
diff_ = Log.objects.station(self.station) \
.filter(diffusion = diff)
.filter(diffusion = diff, type = Log.Type.on_air)
if not diff_.count():
self.log(type = Log.Type.on_air, source = source.id,
diffusion = diff, date = date)
return
# enable dealer
if not dealer.active:
dealer.active = True
if not source.active:
source.active = True
self.log(type = Log.Type.play, source = source.id,
diffusion = diff, date = date)

View File

@ -278,7 +278,7 @@ class Station(Nameable):
for diff in diffs:
if count and n >= count:
break
q = q | models.Q(date__gte = diff.start, date__lte = diff.end)
q = q | models.Q(date__gte = diff.start, end__lte = diff.end)
n += 1
logs = logs.exclude(q, diffusion__isnull = True)
@ -1197,6 +1197,8 @@ class LogManager(models.Manager):
def _at(self, date = None, qs = None, **kwargs):
start, end = utils.date_range(date)
qs = self if qs is None else qs
# return qs.filter(models.Q(end__gte = start) |
# models.Q(date__lte = end))
return qs.filter(date__gte = start, date__lte = end, **kwargs)
def at(self, station = None, date = None, qs = None, **kwargs):
@ -1207,8 +1209,7 @@ class LogManager(models.Manager):
qs = self._at(date, qs, **kwargs)
return self.station(station, qs) if station else qs
def played(self, station, archives = True, include_live = True,
**kwargs):
def played(self, station, archives = True, **kwargs):
"""
Return a queryset of the played elements' log for the given
station and model. This queryset is ordered by date ascending
@ -1219,11 +1220,8 @@ class LogManager(models.Manager):
* include_live: include diffusion that have no archive
* kwargs: extra filter kwargs
"""
if include_live:
qs = self.filter(type__in = (Log.Type.play, Log.Type.on_air),
**kwargs)
else:
qs = self.filter(type = Log.Type.play, **kwargs)
qs = self.filter(type__in = (Log.Type.play, Log.Type.on_air),
**kwargs)
if not archives and station.dealer:
qs = qs.exclude(
@ -1247,9 +1245,8 @@ class Log(models.Model):
"""
play = 0x01
"""
Source has been started/changed and is running related_object
If no related_object is available, comment is used to designate
the sound.
The related item has been started by the streamer or manually,
and occured on air.
"""
load = 0x02
"""
@ -1257,7 +1254,7 @@ class Log(models.Model):
"""
on_air = 0x03
"""
A diffusion occured, but in live (no sound played by Aircox)
The related item has been detected occuring on air
"""
other = 0x04
"""
@ -1287,6 +1284,12 @@ class Log(models.Model):
default=tz.now,
db_index = True,
)
# date of the next diffusion: used in order to ease on_air algo's
end = models.DateTimeField(
_('end'),
default=tz.now,
db_index = True,
)
comment = models.CharField(
_('comment'),
max_length = 512,
@ -1314,15 +1317,14 @@ class Log(models.Model):
objects = LogManager()
@property
def end(self):
def estimate_end(self):
"""
Calculated end using self.related informations
"""
if self.diffusion:
return self.diffusion.end
if self.sound:
return self.date + to_timedelta(sound.duration)
return self.date + utils.to_timedelta(self.sound.duration)
return self.date
@property
@ -1347,7 +1349,6 @@ class Log(models.Model):
if self.track:
r.append('track: ' + str(self.track_id))
logger.info('log #%s: %s%s',
str(self),
self.comment or '',
@ -1359,3 +1360,8 @@ class Log(models.Model):
self.pk, self.date.strftime('%Y/%m/%d %H:%M'), self.source
)
def save(self, *args, **kwargs):
if not self.end:
self.end = self.estimate_end()
return super().save(*args, **kwargs)

View File

@ -6,6 +6,9 @@ from django.conf import settings
def ensure (key, default):
globals()[key] = getattr(settings, key, default)
########################################################################
# Global & misc
########################################################################
# group to assign to users at their creation, along with the permissions
# to add to each group.
ensure('AIRCOX_DEFAULT_USER_GROUPS', {
@ -23,6 +26,24 @@ ensure('AIRCOX_DEFAULT_USER_GROUPS', {
ensure('AIRCOX_PROGRAMS_DIR',
os.path.join(settings.MEDIA_ROOT, 'programs'))
# Directory for working data
ensure('AIRCOX_DATA_DIR',
os.path.join(settings.PROJECT_ROOT, 'data'))
########################################################################
# Logs & Archives
########################################################################
# Directory where to save logs' archives
ensure('AIRCOX_LOGS_ARCHIVES_DIR',
os.path.join(AIRCOX_DATA_DIR, 'archives')
)
# In days, minimal age of a log before it is archived
ensure('AIRCOX_LOGS_ARCHIVES_MIN_AGE', 60)
########################################################################
# Sounds
########################################################################
# Default directory for the sounds that not linked to a program
ensure('AIRCOX_SOUND_DEFAULT_DIR',
os.path.join(AIRCOX_PROGRAMS_DIR, 'defaults')),
@ -54,22 +75,26 @@ ensure(
('.ogg','.flac','.wav','.mp3','.opus')
)
# Stream for the scheduled diffusions
ensure('AIRCOX_SCHEDULED_STREAM', 0)
# Import playlist: columns for CSV file
ensure(
'AIRCOX_IMPORT_PLAYLIST_CSV_COLS',
('artist', 'title', 'minutes', 'seconds', 'tags', 'info')
)
# Import playlist: column delimiter of csv text files
ensure('AIRCOX_IMPORT_PLAYLIST_CSV_DELIMITER', ';')
# Import playlist: text delimiter of csv text files
ensure('AIRCOX_IMPORT_PLAYLIST_CSV_TEXT_QUOTE', '"')
########################################################################
# Streamer & Controllers
########################################################################
# Controllers working directory
ensure('AIRCOX_CONTROLLERS_WORKING_DIR', '/tmp/aircox')
########################################################################
# Playlist import from CSV
########################################################################
# Columns for CSV file
ensure(
'AIRCOX_IMPORT_PLAYLIST_CSV_COLS',
('artist', 'title', 'minutes', 'seconds', 'tags', 'info')
)
# Column delimiter of csv text files
ensure('AIRCOX_IMPORT_PLAYLIST_CSV_DELIMITER', ';')
# Text delimiter of csv text files
ensure('AIRCOX_IMPORT_PLAYLIST_CSV_TEXT_QUOTE', '"')

View File

@ -37,14 +37,17 @@ def on_air(request):
station = request.GET.get('station');
if station:
station = stations.stations.filter(name = station)
if not station.count():
return HttpResponse('')
else:
station = stations.stations.first()
station = stations.stations
station = station.first()
on_air = station.on_air(count = 10).select_related('track','diffusion')
if not on_air.count():
return HttpResponse('')
last = on_air.last()
last = on_air.first()
if last.track:
last = {
'type': 'track',

View File

@ -185,7 +185,7 @@ def diffusion_post_saved(sender, instance, created, *args, **kwargs):
page.save()
return
if instance.page:
if hasattr(instance, 'page'):
return
page = models.DiffusionPage.from_diffusion(