forked from rc/aircox
fix logs merge with diff algorithm
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,4 @@
|
||||
from collections import deque
|
||||
import datetime
|
||||
from enum import IntEnum
|
||||
import logging
|
||||
@ -25,10 +26,14 @@ class LogQuerySet(models.QuerySet):
|
||||
return self.filter(station=station) if id is None else \
|
||||
self.filter(station_id=id)
|
||||
|
||||
def at(self, date=None):
|
||||
date = utils.date_or_default(date)
|
||||
def today(self, date):
|
||||
return self.filter(date__date=date)
|
||||
|
||||
def after(self, date):
|
||||
return self.filter(date__gte=date) \
|
||||
if isinstance(date, tz.datetime) else \
|
||||
self.filter(date__date__gte=date)
|
||||
|
||||
def on_air(self):
|
||||
return self.filter(type=Log.Type.on_air)
|
||||
|
||||
@ -100,13 +105,9 @@ class LogQuerySet(models.QuerySet):
|
||||
}
|
||||
|
||||
def rel_obj(log, attr):
|
||||
attr_id = attr + '_id'
|
||||
rel_id = log.get(attr + '_id')
|
||||
|
||||
return rels[attr][rel_id] if rel_id else None
|
||||
|
||||
# make logs
|
||||
|
||||
return [
|
||||
Log(diffusion=rel_obj(log, 'diffusion'),
|
||||
sound=rel_obj(log, 'sound'),
|
||||
@ -134,7 +135,7 @@ class LogQuerySet(models.QuerySet):
|
||||
if os.path.exists(path) and not force:
|
||||
return -1
|
||||
|
||||
qs = self.station(station).at(date)
|
||||
qs = self.station(station).today(date)
|
||||
|
||||
if not qs.exists():
|
||||
return 0
|
||||
@ -241,6 +242,56 @@ class Log(models.Model):
|
||||
"""
|
||||
return tz.localtime(self.date, tz.get_current_timezone())
|
||||
|
||||
def __str__(self):
|
||||
return '#{} ({}, {}, {})'.format(
|
||||
self.pk, self.get_type_display(),
|
||||
self.source, self.local_date.strftime('%Y/%m/%d %H:%M%z'))
|
||||
|
||||
@classmethod
|
||||
def __list_append(cls, object_list, items):
|
||||
object_list += [cls(obj) for obj in items]
|
||||
|
||||
@classmethod
|
||||
def merge_diffusions(cls, logs, diffs):
|
||||
diffs = deque(diffs.order_by('start'))
|
||||
logs = list(logs.order_by('date'))
|
||||
object_list = []
|
||||
|
||||
# +++ +++ ++ ++
|
||||
# ---- ----- ----
|
||||
while True:
|
||||
if not len(diffs):
|
||||
object_list += logs
|
||||
break
|
||||
|
||||
if not len(logs):
|
||||
object_list += diffs
|
||||
break
|
||||
|
||||
diff = diffs.popleft()
|
||||
|
||||
# - takes all logs before diff happens
|
||||
index = next((i for i, v in enumerate(logs)
|
||||
if v.date >= diff.start), len(logs))
|
||||
if index is not None and index > 0:
|
||||
object_list += logs[:index]
|
||||
logs = logs[index:]
|
||||
|
||||
# - add diff
|
||||
object_list.append(diff)
|
||||
|
||||
# - last log while diff is running
|
||||
# Using of greater allow last_log to log that starts with date
|
||||
# equals to diff.end
|
||||
index = next((i for i, v in enumerate(logs) if v.date > diff.end),
|
||||
None)
|
||||
if index is not None and index > 0:
|
||||
object_list.append(logs[index-1])
|
||||
logs = logs[index:]
|
||||
|
||||
return object_list
|
||||
|
||||
|
||||
def print(self):
|
||||
r = []
|
||||
if self.diffusion:
|
||||
@ -252,7 +303,3 @@ class Log(models.Model):
|
||||
logger.info('log %s: %s%s', str(self), self.comment or '',
|
||||
' (' + ', '.join(r) + ')' if r else '')
|
||||
|
||||
def __str__(self):
|
||||
return '#{} ({}, {}, {})'.format(
|
||||
self.pk, self.get_type_display(),
|
||||
self.source, self.local_date.strftime('%Y/%m/%d %H:%M%z'))
|
||||
|
@ -44,7 +44,7 @@ def program_post_save(sender, instance, created, *args, **kwargs):
|
||||
Clean-up later diffusions when a program becomes inactive
|
||||
"""
|
||||
if not instance.active:
|
||||
Diffusion.objects.program(instance).after().delete()
|
||||
Diffusion.objects.program(instance).after(tz.now()).delete()
|
||||
Episode.object.program(instance).filter(diffusion__isnull=True) \
|
||||
.delete()
|
||||
|
||||
@ -70,7 +70,7 @@ def schedule_post_save(sender, instance, created, *args, **kwargs):
|
||||
today = tz.datetime.today()
|
||||
delta = instance.normalize(today) - initial.normalize(today)
|
||||
|
||||
qs = Diffusion.objects.program(instance.program).after()
|
||||
qs = Diffusion.objects.program(instance.program).after(tz.now())
|
||||
pks = [d.pk for d in qs if initial.match(d.date)]
|
||||
qs.filter(pk__in=pks).update(
|
||||
start=F('start') + delta,
|
||||
@ -86,7 +86,7 @@ def schedule_pre_delete(sender, instance, *args, **kwargs):
|
||||
if not instance.program.sync:
|
||||
return
|
||||
|
||||
qs = Diffusion.objects.program(instance.program).after()
|
||||
qs = Diffusion.objects.program(instance.program).after(tz.now())
|
||||
pks = [d.pk for d in qs if instance.match(d.date)]
|
||||
qs.filter(pk__in=pks).delete()
|
||||
|
||||
|
@ -55,6 +55,11 @@ class Station(models.Model):
|
||||
_("website's urls"), max_length=512, null=True, blank=True,
|
||||
help_text=_('specify one url per line')
|
||||
)
|
||||
audio_streams = models.TextField(
|
||||
_("audio streams"), max_length=2048, null=True, blank=True,
|
||||
help_text=_("Audio streams urls used by station's player. One url "
|
||||
"a line.")
|
||||
)
|
||||
|
||||
objects = StationQuerySet.as_manager()
|
||||
|
||||
|
Reference in New Issue
Block a user