add manager for Related class; rename get_on_air as on_air + can retrieve by last logs instead of date
This commit is contained in:
parent
62380c054d
commit
960fcab65d
|
@ -648,7 +648,7 @@ class LogsPage(DatedListPage):
|
||||||
|
|
||||||
logs = []
|
logs = []
|
||||||
for date in context['nav_dates']['dates']:
|
for date in context['nav_dates']['dates']:
|
||||||
items = self.station.get_on_air(date)
|
items = self.station.on_air(date = date)
|
||||||
items = [ self.as_item(item) for item in items ]
|
items = [ self.as_item(item) for item in items ]
|
||||||
logs.append((date, items))
|
logs.append((date, items))
|
||||||
return logs
|
return logs
|
||||||
|
|
|
@ -32,6 +32,10 @@ from modelcluster.fields import ParentalKey
|
||||||
from modelcluster.tags import ClusterTaggableManager
|
from modelcluster.tags import ClusterTaggableManager
|
||||||
from taggit.models import TaggedItemBase
|
from taggit.models import TaggedItemBase
|
||||||
|
|
||||||
|
# aircox
|
||||||
|
import aircox.programs.models as programs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def related_pages_filter(reset_cache=False):
|
def related_pages_filter(reset_cache=False):
|
||||||
"""
|
"""
|
||||||
|
@ -398,12 +402,12 @@ class DatedListBase(models.Model):
|
||||||
return [ first + tz.timedelta(days=i)
|
return [ first + tz.timedelta(days=i)
|
||||||
for i in range(0, self.nav_days) ]
|
for i in range(0, self.nav_days) ]
|
||||||
|
|
||||||
def get_date_context(self, date):
|
def get_date_context(self, date = None):
|
||||||
"""
|
"""
|
||||||
Return a dict that can be added to the context to be used by
|
Return a dict that can be added to the context to be used by
|
||||||
a date_list.
|
a date_list.
|
||||||
"""
|
"""
|
||||||
today = tz.now().today()
|
today = tz.now().date()
|
||||||
if not date:
|
if not date:
|
||||||
date = today
|
date = today
|
||||||
|
|
||||||
|
@ -809,3 +813,41 @@ class SectionList(ListBase, SectionItem):
|
||||||
)
|
)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
@register_snippet
|
||||||
|
class SectionTimetable(SectionItem,DatedListBase):
|
||||||
|
panels = SectionItem.panels + DatedListBase.panels
|
||||||
|
|
||||||
|
def get_queryset(self, context):
|
||||||
|
from aircox.cms.models import DiffusionPage
|
||||||
|
diffs = []
|
||||||
|
for date in context['nav_dates']['dates']:
|
||||||
|
items = programs.Diffusion.objects.get_at(date).order_by('start')
|
||||||
|
items = [ DiffusionPage.as_item(item) for item in items ]
|
||||||
|
diffs.append((date, items))
|
||||||
|
return diffs
|
||||||
|
|
||||||
|
def get_context(self, request, page, *args, **kwargs):
|
||||||
|
context = super().get_context(request, page, *args, **kwargs)
|
||||||
|
context.update(self.get_date_context())
|
||||||
|
context['object_list'] = self.get_queryset(context)
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
@register_snippet
|
||||||
|
class SectionLogs(SectionItem):
|
||||||
|
count = models.SmallIntegerField(
|
||||||
|
_('count'),
|
||||||
|
default = 5,
|
||||||
|
help_text = _('number of items to display in the list'),
|
||||||
|
)
|
||||||
|
|
||||||
|
panels = SectionItem.panels + [
|
||||||
|
FieldPanel('count'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_context(self, request, page, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ class DiffusionsMenu(GenericMenu):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return programs.Diffusion.objects.filter(
|
return programs.Diffusion.objects.filter(
|
||||||
type = programs.Diffusion.Type.normal,
|
type = programs.Diffusion.Type.normal,
|
||||||
start__contains = tz.now().date() + tz.timedelta(days=2),
|
start__contains = tz.now().date(),
|
||||||
).order_by('start')
|
).order_by('start')
|
||||||
|
|
||||||
def get_title(self, item):
|
def get_title(self, item):
|
||||||
|
|
|
@ -150,7 +150,7 @@ class Station(programs.Nameable):
|
||||||
* archive: if false, exclude log of diffusion's archives from
|
* archive: if false, exclude log of diffusion's archives from
|
||||||
the queryset;
|
the queryset;
|
||||||
"""
|
"""
|
||||||
qs = Log.get_for(model = models) \
|
qs = Log.objects.get_for(model = models) \
|
||||||
.filter(station = self, type = Log.Type.play)
|
.filter(station = self, type = Log.Type.play)
|
||||||
if not archives and self.dealer:
|
if not archives and self.dealer:
|
||||||
qs = qs.exclude(
|
qs = qs.exclude(
|
||||||
|
@ -161,45 +161,66 @@ class Station(programs.Nameable):
|
||||||
)
|
)
|
||||||
return qs.order_by('date')
|
return qs.order_by('date')
|
||||||
|
|
||||||
def get_on_air(self, date = None):
|
|
||||||
|
@staticmethod
|
||||||
|
def __mix_logs_and_diff(diffs, logs, count = 0):
|
||||||
"""
|
"""
|
||||||
Return a list of what should have normally been on air at the
|
Mix together logs and diffusion items ordering by their date.
|
||||||
given date, ordered descending on the diffusion time
|
Diffs and Logs are assumed to be ordered by -date, and so is
|
||||||
|
the resulting list
|
||||||
|
"""
|
||||||
|
# we fill a list with diff and retrieve logs that happened between
|
||||||
|
# each to put them too there
|
||||||
|
items = []
|
||||||
|
diff_ = None
|
||||||
|
for diff in diffs:
|
||||||
|
logs_ = \
|
||||||
|
logs.filter(date__gt = diff.end, date__lt = diff_.start) \
|
||||||
|
if diff_ else logs.filter(date__gt = diff.end)
|
||||||
|
diff_ = diff
|
||||||
|
items.extends(logs_)
|
||||||
|
items.append(diff)
|
||||||
|
if count and len(items) >= count:
|
||||||
|
break
|
||||||
|
|
||||||
|
if diff_ and not count or len(items) <= count:
|
||||||
|
logs_ = logs.filter(date__lt = diff_.end)
|
||||||
|
items.extend(logs_)
|
||||||
|
|
||||||
|
return items[:count] if count else items
|
||||||
|
|
||||||
|
|
||||||
|
def on_air(self, date = None, count = 0):
|
||||||
|
"""
|
||||||
|
Return a list of what happened on air, based on logs and
|
||||||
|
diffusions informations. The list is sorted by -date.
|
||||||
|
|
||||||
|
* date: only for what happened on this date;
|
||||||
|
* count: number of items to retrieve if not zero;
|
||||||
|
|
||||||
|
Be careful with what you which for: the result is a plain list.
|
||||||
|
|
||||||
The list contains:
|
The list contains:
|
||||||
- track logs: for the streamed programs;
|
* track logs: for the streamed programs;
|
||||||
- diffusion: for the scheduled diffusions;
|
* diffusion: for the scheduled diffusions;
|
||||||
"""
|
"""
|
||||||
# TODO: argument to get sound instead of tracks
|
# FIXME: as an iterator?
|
||||||
|
# TODO argument to get sound instead of tracks
|
||||||
|
# TODO #Station
|
||||||
date = date or tz.now().date()
|
date = date or tz.now().date()
|
||||||
if date > datetime.date.today():
|
if date > datetime.date.today():
|
||||||
return []
|
return []
|
||||||
|
|
||||||
logs = Log.get_for(model = programs.Track) \
|
logs = Log.objects.get_for(model = programs.Track) \
|
||||||
.filter(date__contains = date) \
|
.filter(station = self) \
|
||||||
.order_by('date')
|
.order_by('-date')
|
||||||
diffs = programs.Diffusion.objects.get_at(date) \
|
diffs = programs.Diffusion.objects \
|
||||||
.filter(type = programs.Diffusion.Type.normal) \
|
.filter(type = Diffusion.Type.normal) \
|
||||||
.order_by('start')
|
.order_by('-date')
|
||||||
|
if date:
|
||||||
# mix up
|
logs = logs.filter(date__contains = date)
|
||||||
items = []
|
diffs = diffs.get_at(date)
|
||||||
prev_diff = None
|
return self.__mix_logs_and_diff(diffs, logs, count)
|
||||||
for diff in diffs:
|
|
||||||
logs_ = logs.filter(date__gt = prev_diff.end,
|
|
||||||
date__lt = diff.start) \
|
|
||||||
if prev_diff else \
|
|
||||||
logs.filter(date__lt = diff.start)
|
|
||||||
prev_diff = diff
|
|
||||||
items.extend(logs_)
|
|
||||||
items.append(diff)
|
|
||||||
|
|
||||||
# last logs
|
|
||||||
if prev_diff:
|
|
||||||
logs_ = logs.filter(date__gt = prev_diff.end)
|
|
||||||
items.extend(logs_)
|
|
||||||
return reversed(items)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def save(self, make_sources = True, *args, **kwargs):
|
def save(self, make_sources = True, *args, **kwargs):
|
||||||
|
|
|
@ -66,7 +66,7 @@ class Monitor:
|
||||||
if not current_sound or not current_source:
|
if not current_sound or not current_source:
|
||||||
return
|
return
|
||||||
|
|
||||||
log = Log.get_for(model = programs.Sound) \
|
log = Log.objects.get_for(model = programs.Sound) \
|
||||||
.filter(station = self.station).order_by('date').last()
|
.filter(station = self.station).order_by('date').last()
|
||||||
|
|
||||||
# only streamed
|
# only streamed
|
||||||
|
@ -92,11 +92,11 @@ class Monitor:
|
||||||
Log tracks for the given sound (for streamed programs); Called by
|
Log tracks for the given sound (for streamed programs); Called by
|
||||||
self.trace
|
self.trace
|
||||||
"""
|
"""
|
||||||
logs = Log.get_for(model = programs.Track) \
|
logs = Log.objects.get_for(model = programs.Track) \
|
||||||
.filter(pk__gt = log.pk)
|
.filter(pk__gt = log.pk)
|
||||||
logs = [ log.related_id for log in logs ]
|
logs = [ log.related_id for log in logs ]
|
||||||
|
|
||||||
tracks = programs.Track.get_for(object = log.related) \
|
tracks = programs.Track.objects.get_for(object = log.related) \
|
||||||
.filter(in_seconds = True)
|
.filter(in_seconds = True)
|
||||||
if tracks and len(tracks) == len(logs):
|
if tracks and len(tracks) == len(logs):
|
||||||
return
|
return
|
||||||
|
|
|
@ -127,7 +127,7 @@ class SoundInfo:
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
return
|
return
|
||||||
|
|
||||||
old = Track.get_for(object = sound)
|
old = Track.objects.get_for(object = sound)
|
||||||
if old:
|
if old:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,29 @@ def date_or_default(date, no_time = False):
|
||||||
return date
|
return date
|
||||||
|
|
||||||
|
|
||||||
|
class RelatedManager(models.Manager):
|
||||||
|
def get_for(self, object = None, model = None):
|
||||||
|
"""
|
||||||
|
Return a queryset that filter on the given object or model(s)
|
||||||
|
|
||||||
|
* object: if given, use its type and pk; match on models only.
|
||||||
|
* model: one model or an iterable of models
|
||||||
|
"""
|
||||||
|
if not model and object:
|
||||||
|
model = type(object)
|
||||||
|
|
||||||
|
if hasattr(model, '__iter__'):
|
||||||
|
model = [ ContentType.objects.get_for_model(m).id
|
||||||
|
for m in model ]
|
||||||
|
qs = self.filter(related_type__pk__in = model)
|
||||||
|
else:
|
||||||
|
model = ContentType.objects.get_for_model(model)
|
||||||
|
qs = self.filter(related_type__pk = model.id)
|
||||||
|
if object:
|
||||||
|
qs = qs.filter(related_id = object.pk)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class Related(models.Model):
|
class Related(models.Model):
|
||||||
"""
|
"""
|
||||||
Add a field "related" of type GenericForeignKey, plus utilities.
|
Add a field "related" of type GenericForeignKey, plus utilities.
|
||||||
|
@ -60,28 +83,7 @@ class Related(models.Model):
|
||||||
'related_type', 'related_id',
|
'related_type', 'related_id',
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
objects = RelatedManager()
|
||||||
def get_for(cl, object = None, model = None):
|
|
||||||
"""
|
|
||||||
Return a queryset that filter on the given object or model(s)
|
|
||||||
|
|
||||||
* object: if given, use its type and pk; match on models only.
|
|
||||||
* model: one model or list of models
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
Loading…
Reference in New Issue
Block a user