diff --git a/aircox/models.py b/aircox/models.py index f9cb740..2aa8be8 100755 --- a/aircox/models.py +++ b/aircox/models.py @@ -527,7 +527,8 @@ class Schedule(models.Model): This is needed since datetime are stored as UTC date and we want to get it as local time. """ - if not hasattr(self, '_local_date') or self._tz.zone != self.timezone: + if not hasattr(self, '_local_date') or \ + self.changed(fields = ('timezone','date')): self._local_date = tz.localtime(self.date, self.tz) return self._local_date @@ -549,7 +550,7 @@ class Schedule(models.Model): # initial cached data __initial = None - def changed(self, fields = ['date','duration','frequency']): + def changed(self, fields = ['date','duration','frequency','timezone']): initial = self._Schedule__initial if not initial: return @@ -573,9 +574,17 @@ class Schedule(models.Model): Return True if the given datetime matches the schedule """ date = utils.date_or_default(date) - if self.date.weekday() == date.weekday() and self.match_week(date): - return self.date.time() == date.time() if check_time else True - return False + print('match...', date, self.date, self.match_week(date), self.date.weekday() == date.weekday()) + if self.date.weekday() != date.weekday() or not self.match_week(date): + return False + + if not check_time: + return True + + # we check against a normalized version (norm_date will have + # schedule's date. + norm_date = self.normalize(date) + return date == norm_date def match_week(self, date = None): """ @@ -601,13 +610,13 @@ class Schedule(models.Model): # weeks of month if week == 4: # fifth week: return if for every week - return self.frequency == 0b1111 + return self.frequency == self.Frequency.every return (self.frequency & (0b0001 << week) > 0) def normalize(self, date): """ - Set the time of a datetime to the schedule's one - Ensure timezone awareness. + Return a new datetime with schedule time. Timezone is handled + using `schedule.timezone`. """ local_date = self.local_date date = tz.datetime(date.year, date.month, date.day, diff --git a/aircox/signals.py b/aircox/signals.py index de5b801..26f5c75 100755 --- a/aircox/signals.py +++ b/aircox/signals.py @@ -1,9 +1,12 @@ -from django.db.models.signals import post_save, pre_save, pre_delete, m2m_changed -from django.contrib.auth.models import User, Group, Permission +import pytz -from django.dispatch import receiver -from django.utils.translation import ugettext as _, ugettext_lazy +from django.contrib.auth.models import User, Group, Permission from django.contrib.contenttypes.models import ContentType +from django.db.models import F +from django.db.models.signals import post_save, pre_save, pre_delete, m2m_changed +from django.dispatch import receiver +from django.utils import timezone as tz +from django.utils.translation import ugettext as _, ugettext_lazy import aircox.models as models import aircox.utils as utils @@ -36,9 +39,10 @@ def user_default_groups(sender, instance, created, *args, **kwargs): # FIXME: avoid copy of the code in schedule_post_saved and # schedule_pre_delete + @receiver(post_save, sender=models.Schedule) def schedule_post_saved(sender, instance, created, *args, **kwargs): - # TODO: case instance.program has changed + # TODO: case instance.program | instance.frequency has changed if not instance.program.sync: return @@ -46,29 +50,28 @@ def schedule_post_saved(sender, instance, created, *args, **kwargs): if not initial or not instance.changed(['date','duration', 'frequency']): return - if not initial.get('date') or not initial.get('duration') or not initial.get('frequency'): + if not initial.get('date') or not initial.get('duration') \ + or not initial.get('frequency'): return # old schedule and timedelta - old_sched = models.Schedule( - program = instance.program, - date = initial['date'], - duration = initial['duration'], - frequency = initial['frequency'], - ) - delta = instance.date - old_sched.date + old = models.Schedule(**{ key: initial.get(key) + for key in ('date','timezone','duration','frequency') + }) + start_delta = instance.local_date - old.local_date - # update diffusions... - qs = models.Diffusion.objects.after( + old.date = old.local_date.astimezone(pytz.UTC) + + qs = models.Diffusion.objects.station( instance.program.station, - program = instance.program ) - for diff in qs: - if not old_sched.match(diff.date): - continue - diff.start += delta - diff.end = diff.start + utils.to_timedelta(instance.duration) - diff.save() + + pks = [ item.pk for item in qs if old.match(item.date) ] + qs.filter(pk__in = pks).update( + start = F('start') + start_delta, + end = F('start') + start_delta + utils.to_timedelta(instance.duration) + ) + return @receiver(pre_delete, sender=models.Schedule) def schedule_pre_delete(sender, instance, *args, **kwargs): @@ -79,17 +82,14 @@ def schedule_pre_delete(sender, instance, *args, **kwargs): if not initial or not instance.changed(['date','duration', 'frequency']): return - old_sched = models.Schedule( - date = initial['date'], - duration = initial['duration'], - frequency = initial['frequency'], + old = models.Schedule(**{ key: initial.get(key) + for key in ('date','timezone','duration','frequency') + }) + + qs = models.Diffusion.objects.station( + instance.program.station, ) - qs = models.Diffusion.objects.after(instance.program.station).filter( - program = instance.program - ) - for diff in qs: - if not old_sched.match(diff.date): - continue - diff.delete() + pks = [ item.pk for item in qs if old.match(item.date) ] + qs.filter(pk__in = pks).delete() diff --git a/aircox_cms/sections.py b/aircox_cms/sections.py index 2c407e5..d2d260f 100755 --- a/aircox_cms/sections.py +++ b/aircox_cms/sections.py @@ -277,13 +277,14 @@ class BaseList(models.Model): def __get_related(self, qs): related = self.related and self.related.specific - filter = self.RelationFilter if self.relation in (filter.subpages, filter.subpages_or_siblings): - qs = qs.descendant_of(related) - if not qs.count() and self.relation == filter.subpages_or_siblings: - qs = qs.sibling_of(related) + qs_ = qs.descendant_of(related) + if self.relation == filter.subpages_or_siblings and \ + not qs.count(): + qs_ = qs.sibling_of(related) + qs = qs_ else: qs = qs.sibling_of(related) @@ -393,7 +394,7 @@ class BaseList(models.Model): 'asc': self.asc, 'date_filter': self.get_date_filter_display(), 'model': self.model and self.model.model, - 'relation': self.get_relation_display(), + 'relation': self.relation, 'search': self.search, 'tags': self.tags } @@ -437,7 +438,13 @@ class BaseList(models.Model): """ date_filter = request.GET.get('date_filter') model = request.GET.get('model') + relation = request.GET.get('relation') + if relation is not None: + try: + relation = int(relation) + except: + relation = None related_= request.GET.get('related') if related_: @@ -459,10 +466,7 @@ class BaseList(models.Model): DiffusionPage if model == 'diffusion' else EventPage if model == 'event' else None, 'related': related_, - 'relation': - int(getattr(cl.RelationFilter, relation)) - if relation and hasattr(cl.RelationFilter, relation) - else None, + 'relation': relation, 'tags': request.GET.get('tags'), 'search': request.GET.get('search'), }