fix bug for nth week and one on two; enum Schedule.Frequency

This commit is contained in:
bkfox 2016-06-28 17:27:47 +02:00
parent bae670e883
commit fe87e0be99
7 changed files with 51 additions and 38 deletions

View File

@ -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.

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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']

View File

@ -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):

View File

@ -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