forked from rc/aircox
fix error in streamer and on_air
This commit is contained in:
parent
013a0894ab
commit
08cb8e71bb
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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', '"')
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue
Block a user