fix bug for nth week and one on two; enum Schedule.Frequency
This commit is contained in:
parent
bae670e883
commit
fe87e0be99
|
@ -18,7 +18,7 @@ from aircox.cms import settings
|
||||||
|
|
||||||
class Routable:
|
class Routable:
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_with_thread(cl, thread = None, queryset = None,
|
def get_siblings(cl, thread = None, queryset = None,
|
||||||
thread_model = None, thread_id = None):
|
thread_model = None, thread_id = None):
|
||||||
"""
|
"""
|
||||||
Return posts of the cl's type that are children of the given thread.
|
Return posts of the cl's type that are children of the given thread.
|
||||||
|
|
|
@ -5,8 +5,6 @@ import heapq
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
from aircox.cms.models import Routable
|
|
||||||
|
|
||||||
|
|
||||||
class QCombine:
|
class QCombine:
|
||||||
"""
|
"""
|
||||||
|
@ -126,7 +124,7 @@ class Manager(type):
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class GenericModel(Routable,metaclass=Manager):
|
class GenericModel(metaclass=Manager):
|
||||||
"""
|
"""
|
||||||
This class is used to register a route for multiple models to a website.
|
This class is used to register a route for multiple models to a website.
|
||||||
A QCombine is created with qs for all given models when objects
|
A QCombine is created with qs for all given models when objects
|
||||||
|
|
|
@ -126,7 +126,7 @@ class ThreadRoute(Route):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_queryset(cl, model, request, thread_model, pk, **kwargs):
|
def get_queryset(cl, model, request, thread_model, pk, **kwargs):
|
||||||
thread = cl.get_thread(model, thread_model, pk)
|
thread = cl.get_thread(model, thread_model, pk)
|
||||||
return model.get_with_thread(thread_model = thread, thread_id = pk)
|
return model.get_siblings(thread_model = thread, thread_id = pk)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_title(cl, model, request, thread_model, pk, **kwargs):
|
def get_title(cl, model, request, thread_model, pk, **kwargs):
|
||||||
|
|
5
notes.md
5
notes.md
|
@ -8,11 +8,12 @@
|
||||||
- translation
|
- translation
|
||||||
|
|
||||||
- programs:
|
- programs:
|
||||||
|
- schedule: potential issue with nth' week of month
|
||||||
- tests:
|
- tests:
|
||||||
- sound_monitor
|
- sound_monitor
|
||||||
|
|
||||||
- liquidsoap:
|
- liquidsoap:
|
||||||
- update rc's supervisor scripts
|
- models to template
|
||||||
- tests:
|
- tests:
|
||||||
- monitor
|
- monitor
|
||||||
- check when a played sound has a temp blank
|
- check when a played sound has a temp blank
|
||||||
|
@ -33,7 +34,6 @@
|
||||||
- calendar
|
- calendar
|
||||||
- article list with the focus
|
- article list with the focus
|
||||||
-> set html attribute based on values that are public
|
-> set html attribute based on values that are public
|
||||||
- rename qcombine.FakeModel -> GenericModel?
|
|
||||||
|
|
||||||
- website:
|
- website:
|
||||||
- diffusions:
|
- diffusions:
|
||||||
|
@ -45,7 +45,6 @@
|
||||||
- mixcloud
|
- mixcloud
|
||||||
- seek bar
|
- seek bar
|
||||||
- load complete week for a schedule?
|
- load complete week for a schedule?
|
||||||
- finish that fucking website
|
|
||||||
- list of played diffusions and tracks when non-stop;
|
- list of played diffusions and tracks when non-stop;
|
||||||
- search input in a section
|
- search input in a section
|
||||||
|
|
||||||
|
|
|
@ -137,8 +137,11 @@ class DiffusionAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
qs = super().get_queryset(request)
|
qs = super().get_queryset(request)
|
||||||
if request.GET and '_changelist_filters' in request.GET and \
|
print('type__exact' in request.GET,
|
||||||
request.GET.get('type__exact') == Diffusion.Type.unconfirmed:
|
request.GET.get('type__exact'),
|
||||||
|
Diffusion.Type.unconfirmed,
|
||||||
|
request.GET.get('type__exact') == Diffusion.Type.unconfirmed)
|
||||||
|
if request.GET and len(request.GET):
|
||||||
return qs
|
return qs
|
||||||
return qs.exclude(type = Diffusion.Type.unconfirmed)
|
return qs.exclude(type = Diffusion.Type.unconfirmed)
|
||||||
|
|
||||||
|
@ -164,6 +167,7 @@ class ScheduleAdmin(admin.ModelAdmin):
|
||||||
rerun.short_description = _('Rerun')
|
rerun.short_description = _('Rerun')
|
||||||
rerun.boolean = True
|
rerun.boolean = True
|
||||||
|
|
||||||
|
list_filter = ['frequency', 'program']
|
||||||
list_display = ['id', 'program_name', 'frequency', 'date', 'day', 'rerun']
|
list_display = ['id', 'program_name', 'frequency', 'date', 'day', 'rerun']
|
||||||
list_editable = ['frequency', 'date']
|
list_editable = ['frequency', 'date']
|
||||||
|
|
||||||
|
|
|
@ -264,19 +264,16 @@ class Schedule(models.Model):
|
||||||
# Important: the first week is always the first week where the weekday of
|
# Important: the first week is always the first week where the weekday of
|
||||||
# the schedule is present.
|
# the schedule is present.
|
||||||
# For ponctual programs, there is no need for a schedule, only a diffusion
|
# For ponctual programs, there is no need for a schedule, only a diffusion
|
||||||
Frequency = {
|
class Frequency(IntEnum):
|
||||||
'first': (0b000001, _('first week of the month')),
|
first = 0b000001
|
||||||
'second': (0b000010, _('second week of the month')),
|
second = 0b000010
|
||||||
'third': (0b000100, _('third week of the month')),
|
third = 0b000100
|
||||||
'fourth': (0b001000, _('fourth week of the month')),
|
fourth = 0b001000
|
||||||
'last': (0b010000, _('last week of the month')),
|
last = 0b010000
|
||||||
'first and third': (0b000101, _('first and third weeks of the month')),
|
first_and_third = 0b000101
|
||||||
'second and fourth': (0b001010, _('second and fourth weeks of the month')),
|
second_and_fourth = 0b001010
|
||||||
'every': (0b011111, _('every week')),
|
every = 0b011111
|
||||||
'one on two': (0b100000, _('one week on two')),
|
one_on_two = 0b100000
|
||||||
}
|
|
||||||
VerboseFrequency = { value[0]: value[1] for key, value in Frequency.items() }
|
|
||||||
Frequency = { key: value[0] for key, value in Frequency.items() }
|
|
||||||
|
|
||||||
program = models.ForeignKey(
|
program = models.ForeignKey(
|
||||||
'Program',
|
'Program',
|
||||||
|
@ -289,7 +286,19 @@ class Schedule(models.Model):
|
||||||
)
|
)
|
||||||
frequency = models.SmallIntegerField(
|
frequency = models.SmallIntegerField(
|
||||||
_('frequency'),
|
_('frequency'),
|
||||||
choices = VerboseFrequency.items(),
|
choices = [
|
||||||
|
(int(y), {
|
||||||
|
'first': _('first week of the month'),
|
||||||
|
'second': _('second week of the month'),
|
||||||
|
'third': _('third week of the month'),
|
||||||
|
'fourth': _('fourth week of the month'),
|
||||||
|
'last': _('last week of the month'),
|
||||||
|
'first_and_third': _('first and third weeks of the month'),
|
||||||
|
'second_and_fourth': _('second and fourth weeks of the month'),
|
||||||
|
'every': _('every week'),
|
||||||
|
'one_on_two': _('one week on two'),
|
||||||
|
}[x]) for x,y in Frequency.__members__.items()
|
||||||
|
],
|
||||||
)
|
)
|
||||||
initial = models.ForeignKey(
|
initial = models.ForeignKey(
|
||||||
'self',
|
'self',
|
||||||
|
@ -303,7 +312,6 @@ class Schedule(models.Model):
|
||||||
Return True if the given datetime matches the schedule
|
Return True if the given datetime matches the schedule
|
||||||
"""
|
"""
|
||||||
date = date_or_default(date)
|
date = date_or_default(date)
|
||||||
|
|
||||||
if self.date.weekday() == date.weekday() and self.match_week(date):
|
if self.date.weekday() == date.weekday() and self.match_week(date):
|
||||||
return self.date.time() == date.time() if check_time else True
|
return self.date.time() == date.time() if check_time else True
|
||||||
return False
|
return False
|
||||||
|
@ -314,11 +322,14 @@ class Schedule(models.Model):
|
||||||
otherwise.
|
otherwise.
|
||||||
If the schedule is ponctual, return None.
|
If the schedule is ponctual, return None.
|
||||||
"""
|
"""
|
||||||
# FIXME: does not work if first_day > date_day
|
# since we care only about the week, go to the same day of the week
|
||||||
date = date_or_default(date)
|
date = date_or_default(date)
|
||||||
if self.frequency == Schedule.Frequency['one on two']:
|
date += tz.timedelta(days = self.date.weekday() - date.weekday() )
|
||||||
week = date.isocalendar()[1]
|
|
||||||
return (week % 2) == (self.date.isocalendar()[1] % 2)
|
if self.frequency == Schedule.Frequency.one_on_two:
|
||||||
|
# cf notes in date_of_month
|
||||||
|
diff = as_date(date, False) - as_date(self.date, False)
|
||||||
|
return not (diff.days % 14)
|
||||||
|
|
||||||
first_of_month = date.replace(day = 1)
|
first_of_month = date.replace(day = 1)
|
||||||
week = date.isocalendar()[1] - first_of_month.isocalendar()[1]
|
week = date.isocalendar()[1] - first_of_month.isocalendar()[1]
|
||||||
|
@ -351,7 +362,7 @@ class Schedule(models.Model):
|
||||||
month = date.month
|
month = date.month
|
||||||
|
|
||||||
# last of the month
|
# last of the month
|
||||||
if freq == Schedule.Frequency['last']:
|
if freq == Schedule.Frequency.last:
|
||||||
date += tz.timedelta(days = 4 * 7)
|
date += tz.timedelta(days = 4 * 7)
|
||||||
next_date = date + tz.timedelta(days = 7)
|
next_date = date + tz.timedelta(days = 7)
|
||||||
if next_date.month == month:
|
if next_date.month == month:
|
||||||
|
@ -359,12 +370,12 @@ class Schedule(models.Model):
|
||||||
return [self.normalize(date)]
|
return [self.normalize(date)]
|
||||||
|
|
||||||
dates = []
|
dates = []
|
||||||
if freq == Schedule.Frequency['one on two']:
|
if freq == Schedule.Frequency.one_on_two:
|
||||||
# NOTE previous algorithm was based on the week number, but this
|
# NOTE previous algorithm was based on the week number, but this
|
||||||
# approach is wrong because number of weeks in a year can be
|
# approach is wrong because number of weeks in a year can be
|
||||||
# 52 or 53. This also clashes with the first week of the year.
|
# 52 or 53. This also clashes with the first week of the year.
|
||||||
diff = as_date(date, False) - as_date(self.date, False)
|
diff = as_date(date, False) - as_date(self.date, False)
|
||||||
if not diff.days % 14:
|
if diff.days % 14:
|
||||||
date += tz.timedelta(days = 7)
|
date += tz.timedelta(days = 7)
|
||||||
|
|
||||||
while date.month == month:
|
while date.month == month:
|
||||||
|
@ -376,6 +387,7 @@ class Schedule(models.Model):
|
||||||
if freq & (0b1 << week):
|
if freq & (0b1 << week):
|
||||||
dates.append(date)
|
dates.append(date)
|
||||||
date += tz.timedelta(days = 7)
|
date += tz.timedelta(days = 7)
|
||||||
|
week += 1;
|
||||||
return [self.normalize(date) for date in dates]
|
return [self.normalize(date) for date in dates]
|
||||||
|
|
||||||
def diffusions_of_month(self, date, exclude_saved = False):
|
def diffusions_of_month(self, date, exclude_saved = False):
|
||||||
|
|
|
@ -150,11 +150,11 @@ class Diffusions(sections.List):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.object:
|
if self.object:
|
||||||
return models.Diffusion.route_url(routes.ThreadRoute,
|
return models.Diffusion.reverse(routes.ThreadRoute,
|
||||||
pk = self.object.id,
|
pk = self.object.id,
|
||||||
thread_model = 'program',
|
thread_model = 'program',
|
||||||
)
|
)
|
||||||
return models.Diffusion.route_url(routes.AllRoute)
|
return models.Diffusion.reverse(routes.AllRoute)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def header(self):
|
def header(self):
|
||||||
|
@ -246,7 +246,7 @@ class Schedule(Diffusions):
|
||||||
|
|
||||||
date = self.date_or_default()
|
date = self.date_or_default()
|
||||||
dates = [
|
dates = [
|
||||||
(date, models.Diffusion.route_url(
|
(date, models.Diffusion.reverse(
|
||||||
routes.DateRoute,
|
routes.DateRoute,
|
||||||
year = date.year, month = date.month, day = date.day
|
year = date.year, month = date.month, day = date.day
|
||||||
))
|
))
|
||||||
|
@ -254,14 +254,14 @@ class Schedule(Diffusions):
|
||||||
]
|
]
|
||||||
|
|
||||||
next_week = dates[-1][0] + tz.timedelta(days=1)
|
next_week = dates[-1][0] + tz.timedelta(days=1)
|
||||||
next_week = models.Diffusion.route_url(
|
next_week = models.Diffusion.reverse(
|
||||||
routes.DateRoute,
|
routes.DateRoute,
|
||||||
year = next_week.year, month = next_week.month,
|
year = next_week.year, month = next_week.month,
|
||||||
day = next_week.day
|
day = next_week.day
|
||||||
)
|
)
|
||||||
|
|
||||||
prev_week = dates[0][0] - tz.timedelta(days=1)
|
prev_week = dates[0][0] - tz.timedelta(days=1)
|
||||||
prev_week = models.Diffusion.route_url(
|
prev_week = models.Diffusion.reverse(
|
||||||
routes.DateRoute,
|
routes.DateRoute,
|
||||||
year = prev_week.year, month = prev_week.month,
|
year = prev_week.year, month = prev_week.month,
|
||||||
day = prev_week.day
|
day = prev_week.day
|
||||||
|
|
Loading…
Reference in New Issue
Block a user