forked from rc/aircox
add a rerun field to diffusion; fix minor bug that can happen on new year's eve
This commit is contained in:
parent
64c59f22ab
commit
44fc4dae31
|
@ -117,6 +117,11 @@
|
||||||
{% include 'aircox_liquidsoap/base_source.html' %}
|
{% include 'aircox_liquidsoap/base_source.html' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="next">
|
||||||
|
{% for diffusion in controller.next_diffusions %}
|
||||||
|
{{ diffusion }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -38,7 +38,7 @@ class Connector:
|
||||||
self.__socket.connect(self.address)
|
self.__socket.connect(self.address)
|
||||||
self.__available = True
|
self.__available = True
|
||||||
except:
|
except:
|
||||||
print('can not connect to liquidsoap socket {}'.format(address))
|
print('can not connect to liquidsoap socket {}'.format(self.address))
|
||||||
self.__available = False
|
self.__available = False
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
@ -218,7 +218,12 @@ class Dealer (Source):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_next_diffusion (self):
|
def get_next_diffusion (self):
|
||||||
pass
|
diffusions = models.Diffusion.get_next(self.station)
|
||||||
|
if not diffusions.count():
|
||||||
|
return
|
||||||
|
|
||||||
|
diffusion = diffusions[0]
|
||||||
|
return diffusion
|
||||||
|
|
||||||
def on_air (self, value = True):
|
def on_air (self, value = True):
|
||||||
pass
|
pass
|
||||||
|
@ -286,6 +291,12 @@ class Controller:
|
||||||
return self.dealer
|
return self.dealer
|
||||||
return self.streams.get(source_id)
|
return self.streams.get(source_id)
|
||||||
|
|
||||||
|
def next_diffusions (self, count = 5):
|
||||||
|
"""
|
||||||
|
Return a list of the count next diffusions
|
||||||
|
"""
|
||||||
|
return models.Diffusion.get_next(self.station)[:count]
|
||||||
|
|
||||||
def update_all (self):
|
def update_all (self):
|
||||||
"""
|
"""
|
||||||
Fetch and update all sources metadata.
|
Fetch and update all sources metadata.
|
||||||
|
@ -316,4 +327,3 @@ class Monitor:
|
||||||
controller.update_all()
|
controller.update_all()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ from django.contrib import admin
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from suit.admin import SortableTabularInline, SortableModelAdmin
|
from suit.admin import SortableTabularInline, SortableModelAdmin
|
||||||
from autocomplete_light.contrib.taggit_field import TaggitWidget, TaggitField
|
|
||||||
|
|
||||||
from aircox_programs.forms import *
|
from aircox_programs.forms import *
|
||||||
from aircox_programs.models import *
|
from aircox_programs.models import *
|
||||||
|
@ -73,7 +72,7 @@ class StationAdmin (NameableAdmin):
|
||||||
|
|
||||||
@admin.register(Program)
|
@admin.register(Program)
|
||||||
class ProgramAdmin (NameableAdmin):
|
class ProgramAdmin (NameableAdmin):
|
||||||
fields = NameableAdmin.fields + [ 'stations', 'active' ]
|
fields = NameableAdmin.fields + [ 'station', 'active' ]
|
||||||
inlines = [ ScheduleInline, StreamInline ]
|
inlines = [ ScheduleInline, StreamInline ]
|
||||||
|
|
||||||
def get_form (self, request, obj=None, **kwargs):
|
def get_form (self, request, obj=None, **kwargs):
|
||||||
|
@ -101,13 +100,14 @@ class DiffusionAdmin (admin.ModelAdmin):
|
||||||
if sound.type == Sound.Type['archive'] )
|
if sound.type == Sound.Type['archive'] )
|
||||||
return ', '.join(sounds) if sounds else ''
|
return ', '.join(sounds) if sounds else ''
|
||||||
|
|
||||||
list_display = ('id', 'type', 'date', 'archives', 'episode', 'program')
|
list_display = ('id', 'type', 'date', 'archives', 'episode', 'program', 'rerun')
|
||||||
list_filter = ('type', 'date', 'program')
|
list_filter = ('type', 'date', 'program')
|
||||||
list_editable = ('type', 'date')
|
list_editable = ('type', 'date')
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
qs = super(DiffusionAdmin, self).get_queryset(request)
|
qs = super(DiffusionAdmin, self).get_queryset(request)
|
||||||
if 'type__exact' in request.GET and \
|
if '_changelist_filters' in request.GET or \
|
||||||
|
'type__exact' in request.GET and \
|
||||||
str(Diffusion.Type['unconfirmed']) in request.GET['type__exact']:
|
str(Diffusion.Type['unconfirmed']) in request.GET['type__exact']:
|
||||||
return qs
|
return qs
|
||||||
return qs.exclude(type = Diffusion.Type['unconfirmed'])
|
return qs.exclude(type = Diffusion.Type['unconfirmed'])
|
||||||
|
|
|
@ -23,16 +23,20 @@ from aircox_programs.models import *
|
||||||
class Actions:
|
class Actions:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update (date):
|
def update (date):
|
||||||
items = []
|
count = 0
|
||||||
for schedule in Schedule.objects.filter(program__active = True):
|
for schedule in Schedule.objects.filter(program__active = True) \
|
||||||
items += schedule.diffusions_of_month(date, exclude_saved = True)
|
.order_by('rerun'):
|
||||||
|
# in order to allow rerun links between diffusions, we save items
|
||||||
|
# by schedule;
|
||||||
|
items = schedule.diffusions_of_month(date, exclude_saved = True)
|
||||||
|
count += len(items)
|
||||||
|
Diffusion.objects.bulk_create(items)
|
||||||
print('> {} new diffusions for schedule #{} ({})'.format(
|
print('> {} new diffusions for schedule #{} ({})'.format(
|
||||||
len(items), schedule.id, str(schedule)
|
len(items), schedule.id, str(schedule)
|
||||||
))
|
))
|
||||||
|
|
||||||
print('total of {} diffusions will be created. To be used, they need '
|
print('total of {} diffusions have been created. They need a '
|
||||||
'manual approval.'.format(len(items)))
|
'manual approval.'.format(count))
|
||||||
Diffusion.objects.bulk_create(items)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def clean (date):
|
def clean (date):
|
||||||
|
|
|
@ -30,6 +30,10 @@ class Nameable (models.Model):
|
||||||
max_length = 128,
|
max_length = 128,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def slug (self):
|
||||||
|
return self.get_slug_name()
|
||||||
|
|
||||||
def get_slug_name (self):
|
def get_slug_name (self):
|
||||||
return slugify(self.name).replace('-', '_')
|
return slugify(self.name).replace('-', '_')
|
||||||
|
|
||||||
|
@ -305,8 +309,8 @@ class Schedule (models.Model):
|
||||||
Return a list with all matching dates of date.month (=today)
|
Return a list with all matching dates of date.month (=today)
|
||||||
"""
|
"""
|
||||||
date = date_or_default(date, True).replace(day=1)
|
date = date_or_default(date, True).replace(day=1)
|
||||||
wday = self.date.weekday()
|
|
||||||
fwday = date.weekday()
|
fwday = date.weekday()
|
||||||
|
wday = self.date.weekday()
|
||||||
|
|
||||||
# move date to the date weekday of the schedule
|
# move date to the date weekday of the schedule
|
||||||
# check on SO#3284452 for the formula
|
# check on SO#3284452 for the formula
|
||||||
|
@ -322,8 +326,14 @@ class Schedule (models.Model):
|
||||||
# if both week are the same, then the date week of the month
|
# if both week are the same, then the date week of the month
|
||||||
# matches. Note: wday % 2 + fwday % 2 => (wday + fwday) % 2
|
# matches. Note: wday % 2 + fwday % 2 => (wday + fwday) % 2
|
||||||
fweek = date.isocalendar()[1]
|
fweek = date.isocalendar()[1]
|
||||||
|
|
||||||
|
if date.month == 1 and fweek >= 50:
|
||||||
|
# isocalendar can think we are on the last week of the
|
||||||
|
# previous year
|
||||||
|
fweek = 0
|
||||||
week = self.date.isocalendar()[1]
|
week = self.date.isocalendar()[1]
|
||||||
weeks = 0b010101 if not (fweek + week) % 2 else 0b001010
|
weeks = 0b010101 if not (fweek + week) % 2 else 0b001010
|
||||||
|
print(date, fweek, week, "{0:b}".format(weeks))
|
||||||
|
|
||||||
dates = []
|
dates = []
|
||||||
for week in range(0,5):
|
for week in range(0,5):
|
||||||
|
@ -331,8 +341,10 @@ class Schedule (models.Model):
|
||||||
if not weeks & (0b1 << week):
|
if not weeks & (0b1 << week):
|
||||||
continue
|
continue
|
||||||
wdate = date + tz.timedelta(days = week * 7)
|
wdate = date + tz.timedelta(days = week * 7)
|
||||||
|
print(wdate, wdate.month == date.month)
|
||||||
if wdate.month == date.month:
|
if wdate.month == date.month:
|
||||||
dates.append(self.normalize(wdate))
|
dates.append(self.normalize(wdate))
|
||||||
|
print(dates)
|
||||||
return dates
|
return dates
|
||||||
|
|
||||||
def diffusions_of_month (self, date, exclude_saved = False):
|
def diffusions_of_month (self, date, exclude_saved = False):
|
||||||
|
@ -363,15 +375,18 @@ class Schedule (models.Model):
|
||||||
if self.rerun:
|
if self.rerun:
|
||||||
first_date -= self.date - self.rerun.date
|
first_date -= self.date - self.rerun.date
|
||||||
|
|
||||||
diffusion = Diffusion.objects.filter(date = first_date,
|
first_diffusion = Diffusion.objects.filter(date = first_date,
|
||||||
program = self.program)
|
program = self.program)
|
||||||
episode = diffusion[0].episode if diffusion.count() else None
|
first_diffusion = first_diffusion[0] if first_diffusion.count() \
|
||||||
|
else None
|
||||||
|
episode = first_diffusion.episode if first_diffusion else None
|
||||||
|
# print(self.rerun, episode, first_diffusion, first_date)
|
||||||
diffusions.append(Diffusion(
|
diffusions.append(Diffusion(
|
||||||
episode = episode,
|
episode = episode,
|
||||||
program = self.program,
|
program = self.program,
|
||||||
type = Diffusion.Type['unconfirmed'],
|
type = Diffusion.Type['unconfirmed'],
|
||||||
date = date,
|
date = date,
|
||||||
|
rerun = first_diffusion if self.rerun else None
|
||||||
))
|
))
|
||||||
return diffusions
|
return diffusions
|
||||||
|
|
||||||
|
@ -422,10 +437,47 @@ class Diffusion (models.Model):
|
||||||
choices = [ (y, x) for x,y in Type.items() ],
|
choices = [ (y, x) for x,y in Type.items() ],
|
||||||
)
|
)
|
||||||
date = models.DateTimeField( _('start of the diffusion') )
|
date = models.DateTimeField( _('start of the diffusion') )
|
||||||
|
rerun = models.ForeignKey (
|
||||||
|
'self',
|
||||||
|
verbose_name = _('rerun'),
|
||||||
|
blank = True, null = True,
|
||||||
|
help_text = _('the diffusion is a rerun of this one. Remove this if '
|
||||||
|
'you want to change the concerned episode')
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_next (cl, station = None):
|
||||||
|
"""
|
||||||
|
Return a queryset with the upcoming diffusions, ordered by
|
||||||
|
+date
|
||||||
|
"""
|
||||||
|
args = {
|
||||||
|
'date__gte': tz.datetime.now()
|
||||||
|
}
|
||||||
|
if station:
|
||||||
|
args['program__station'] = station
|
||||||
|
return cl.objects.filter(**args).order_by('date')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_prev (cl, station = None):
|
||||||
|
"""
|
||||||
|
Return a queryset with the previous diffusion, ordered by
|
||||||
|
-date
|
||||||
|
"""
|
||||||
|
args = {
|
||||||
|
'date__lt': tz.datetime.now()
|
||||||
|
}
|
||||||
|
if station:
|
||||||
|
args['program__station'] = station
|
||||||
|
return cl.objects.filter(**args).order_by('-date')
|
||||||
|
|
||||||
def save (self, *args, **kwargs):
|
def save (self, *args, **kwargs):
|
||||||
if self.episode: # FIXME self.episode or kwargs['episode']
|
if self.rerun:
|
||||||
|
self.episode = self.rerun.episode
|
||||||
self.program = self.episode.program
|
self.program = self.episode.program
|
||||||
|
elif self.episode:
|
||||||
|
self.program = self.episode.program
|
||||||
|
|
||||||
super(Diffusion, self).save(*args, **kwargs)
|
super(Diffusion, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def __str__ (self):
|
def __str__ (self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user