forked from rc/aircox
add date into diffusion menu in wagtail nav; get larger menus in back-office
This commit is contained in:
@ -101,9 +101,9 @@ class DiffusionAdmin(admin.ModelAdmin):
|
||||
sounds = [ str(s) for s in obj.get_archives()]
|
||||
return ', '.join(sounds) if sounds else ''
|
||||
|
||||
def conflicts(self, obj):
|
||||
if obj.type == Diffusion.Type.unconfirmed:
|
||||
return ', '.join([ str(d) for d in obj.get_conflicts()])
|
||||
def conflicts_(self, obj):
|
||||
if obj.conflicts.count():
|
||||
return obj.conflicts.count()
|
||||
return ''
|
||||
|
||||
def end_time(self, obj):
|
||||
@ -113,12 +113,13 @@ class DiffusionAdmin(admin.ModelAdmin):
|
||||
def first(self, obj):
|
||||
return obj.initial.start if obj.initial else ''
|
||||
|
||||
list_display = ('id', 'program', 'start', 'end_time', 'type', 'first', 'archives', 'conflicts')
|
||||
list_display = ('id', 'program', 'start', 'end_time', 'type', 'first', 'archives', 'conflicts_')
|
||||
list_filter = ('type', 'start', 'program')
|
||||
list_editable = ('type',)
|
||||
ordering = ('-start', 'id')
|
||||
|
||||
fields = ['type', 'start', 'end', 'initial', 'program']
|
||||
fields = ['type', 'start', 'end', 'initial', 'program', 'conflicts']
|
||||
readonly_fields = ('conflicts',)
|
||||
inlines = [ DiffusionInline, SoundInline ]
|
||||
|
||||
|
||||
|
@ -25,43 +25,12 @@ from aircox.models import *
|
||||
|
||||
logger = logging.getLogger('aircox.tools')
|
||||
|
||||
import time
|
||||
|
||||
class Actions:
|
||||
@staticmethod
|
||||
def __check_conflicts (item, saved_items):
|
||||
"""
|
||||
Check for conflicts, and update conflictual
|
||||
items if they have been generated during this
|
||||
update.
|
||||
|
||||
It set an attribute 'do_not_save' if the item should not
|
||||
be saved. FIXME: find proper way
|
||||
|
||||
Return the number of conflicts
|
||||
"""
|
||||
conflicts = list(item.get_conflicts())
|
||||
for i, conflict in enumerate(conflicts):
|
||||
if conflict.program == item.program:
|
||||
item.do_not_save = True
|
||||
del conflicts[i]
|
||||
continue
|
||||
|
||||
if conflict.pk in saved_items and \
|
||||
conflict.type != Diffusion.Type.unconfirmed:
|
||||
conflict.type = Diffusion.Type.unconfirmed
|
||||
conflict.save()
|
||||
|
||||
if not conflicts:
|
||||
item.type = Diffusion.Type.normal
|
||||
return 0
|
||||
|
||||
item.type = Diffusion.Type.unconfirmed
|
||||
return len(conflicts)
|
||||
|
||||
@classmethod
|
||||
def update (cl, date, mode):
|
||||
manual = (mode == 'manual')
|
||||
if not manual:
|
||||
saved_items = set()
|
||||
|
||||
count = [0, 0]
|
||||
for schedule in Schedule.objects.filter(program__active = True) \
|
||||
@ -71,16 +40,15 @@ class Actions:
|
||||
items = schedule.diffusions_of_month(date, exclude_saved = True)
|
||||
count[0] += len(items)
|
||||
|
||||
if manual:
|
||||
Diffusion.objects.bulk_create(items)
|
||||
else:
|
||||
for item in items:
|
||||
count[1] += cl.__check_conflicts(item, saved_items)
|
||||
if hasattr(item, 'do_not_save'):
|
||||
count[0] -= 1
|
||||
continue
|
||||
item.save()
|
||||
saved_items.add(item)
|
||||
# we can't bulk create because we ned signal processing
|
||||
for item in items:
|
||||
conflicts = item.get_conflicts()
|
||||
item.type = Diffusion.Type.unconfirmed \
|
||||
if manual or conflicts.count() else \
|
||||
Diffusion.Type.normal
|
||||
item.save(no_check = True)
|
||||
if conflicts.count():
|
||||
item.conflicts.set(conflicts.all())
|
||||
|
||||
logger.info('[update] schedule %s: %d new diffusions',
|
||||
str(schedule), len(items),
|
||||
|
@ -720,19 +720,6 @@ class DiffusionManager(models.Manager):
|
||||
qs = self if qs is None else qs
|
||||
return qs.filter(program__station = station)
|
||||
|
||||
@staticmethod
|
||||
def __in_range(field, range, field_ = None, reversed = False):
|
||||
"""
|
||||
Return a kwargs to catch diffusions based on the given field name
|
||||
and datetime range.
|
||||
"""
|
||||
if reversed:
|
||||
return { field + "__lte": range[1],
|
||||
(field_ or field) + "__gte": range[0] }
|
||||
|
||||
return { field + "__gte" : range[0],
|
||||
(field_ or field) + "__lte" : range[1] }
|
||||
|
||||
def at(self, station, date = None, next = False, qs = None):
|
||||
"""
|
||||
Return diffusions occuring at the given date, ordered by +start
|
||||
@ -754,22 +741,21 @@ class DiffusionManager(models.Manager):
|
||||
if isinstance(date, datetime.datetime):
|
||||
# use datetime: we want diffusion that occurs around this
|
||||
# range
|
||||
range = date, date
|
||||
filters = self.__in_range('start', range, 'end', True)
|
||||
filters = { 'start__lte': date, 'end__gte': date }
|
||||
if next:
|
||||
qs = qs.filter(
|
||||
models.Q(date__gte = date) | models.Q(**filters)
|
||||
models.Q(start__gte = date) | models.Q(**filters)
|
||||
)
|
||||
else:
|
||||
qs = qs.filter(**filters)
|
||||
else:
|
||||
# use date: we want diffusions that occurs this day
|
||||
range = utils.date_range(date)
|
||||
filters = models.Q(**self.__in_range('start', range)) | \
|
||||
models.Q(**self.__in_range('end', range))
|
||||
start, end = utils.date_range(date)
|
||||
filters = models.Q(start__gte = start, start__lte = end) | \
|
||||
models.Q(end__gt = start, end__lt = end)
|
||||
if next:
|
||||
# include also diffusions of the next day
|
||||
filters |= models.Q(start__gte = range[0])
|
||||
filters |= models.Q(start__gte = start)
|
||||
qs = qs.filter(filters)
|
||||
return self.station(station, qs).order_by('start').distinct()
|
||||
|
||||
@ -842,6 +828,12 @@ class Diffusion(models.Model):
|
||||
# blank = True, null = True,
|
||||
# help_text = _('use this input port'),
|
||||
# )
|
||||
conflicts = models.ManyToManyField(
|
||||
'self',
|
||||
verbose_name = _('conflicts'),
|
||||
blank = True,
|
||||
help_text = _('conflicts'),
|
||||
)
|
||||
|
||||
start = models.DateTimeField( _('start of the diffusion') )
|
||||
end = models.DateTimeField( _('end of the diffusion') )
|
||||
@ -891,22 +883,44 @@ class Diffusion(models.Model):
|
||||
"""
|
||||
Return a list of conflictual diffusions, based on the scheduled duration.
|
||||
"""
|
||||
r = Diffusion.objects.filter(
|
||||
return Diffusion.objects.filter(
|
||||
models.Q(start__lt = self.start,
|
||||
end__gt = self.start) |
|
||||
models.Q(start__gt = self.start,
|
||||
start__lt = self.end)
|
||||
)
|
||||
return r
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
def check_conflicts(self):
|
||||
conflicts = self.get_conflicts()
|
||||
self.conflicts.set(conflicts)
|
||||
|
||||
__initial = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.__initial = {
|
||||
'start': self.start,
|
||||
'end': self.end,
|
||||
}
|
||||
|
||||
def save(self, no_check = False, *args, **kwargs):
|
||||
if no_check:
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
if self.initial:
|
||||
# force link to the top initial diffusion
|
||||
if self.initial.initial:
|
||||
self.initial = self.initial.initial
|
||||
self.program = self.initial.program
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
if self.__initial:
|
||||
if self.start != self.__initial['start'] or \
|
||||
self.end != self.__initial['end']:
|
||||
self.check_conflicts()
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return '{self.program.name} {date} #{self.pk}'.format(
|
||||
self=self, date=self.date.strftime('%Y-%m-%d %H:%M')
|
||||
|
Reference in New Issue
Block a user