Commit 88f4ba01 authored by fred's avatar fred

new period_program(), that gives the actual program over a time period

(day_program() has been changed to use it)
parent 691abb0e
from datetime import datetime, timedelta
from django.core.management.base import BaseCommand, CommandError
from django.views.generic.dates import _date_from_string
from ...utils import period_program
class Command(BaseCommand):
def handle(self, year, week, **options):
date = _date_from_string(year, '%Y',
'1', '%w',
week, '%W')
date = datetime(*date.timetuple()[:3])
for entry in period_program(date, date+timedelta(days=7)):
print entry.datetime, entry
......@@ -12,6 +12,24 @@ from taggit.managers import TaggableManager
from utils import maybe_resize
class WeekdayMixin:
DAY_HOUR_START = 6
def get_weekday(self):
weekday = self.datetime.weekday() + 7
if self.datetime.time() < datetime.time(self.DAY_HOUR_START, 0):
weekday -= 1
weekday %= 7
return weekday
def is_on_weekday(self, day): # day is [1..7]
week_day = self.datetime.weekday()
if self.datetime.hour < self.DAY_HOUR_START:
week_day -= 1
week_day = (week_day % 7) + 1
return week_day == day
class Category(models.Model):
title = models.CharField(max_length=50)
......@@ -63,9 +81,7 @@ class Emission(models.Model):
return Schedule.objects.filter(emission=self).order_by('datetime')
class Schedule(models.Model):
DAY_HOUR_START = 6
class Schedule(models.Model, WeekdayMixin):
WEEK_CHOICES = (
(0b1111, 'Every week'),
......@@ -82,22 +98,6 @@ class Schedule(models.Model):
rerun = models.BooleanField(default=False)
duration = models.IntegerField(null=True, blank=True)
def get_weekday(self):
weekday = self.datetime.weekday() + 7
if self.datetime.time() < datetime.time(self.DAY_HOUR_START, 0):
weekday -= 1
weekday %= 7
return weekday
def is_on_weekday(self, day): # day is [1..7]
if self.datetime >= datetime.datetime(2007, 1, day, 5, 0) and \
self.datetime < datetime.datetime(2007, 1, day+1, self.DAY_HOUR_START, 0):
return True
if day == 7 and self.datetime < datetime.datetime(2007, 1, 1, self.DAY_HOUR_START, 0):
# special case for Sunday nights
return True
return False
@property
def weeks_string(self):
if self.weeks == 0b0001:
......@@ -121,6 +121,8 @@ class Schedule(models.Model):
return self.emission.duration
def match_week(self, week_no):
if week_no == 4:
week_no = 3
if (self.weeks & (0b0001<<(week_no)) == 0):
return False
return True
......@@ -205,7 +207,7 @@ class Episode(models.Model):
self._main_sound = value
class Diffusion(models.Model):
class Diffusion(models.Model, WeekdayMixin):
episode = models.ForeignKey('Episode', verbose_name=u'Episode')
datetime = models.DateTimeField()
......
......@@ -50,43 +50,46 @@ def whatsonair():
'current_slot': current_slot}
def day_program(date):
def period_program(date_start, date_end):
from models import Diffusion, Schedule
date_start = datetime(*date.timetuple()[:3])
date_end = date_start + timedelta(days=1)
diffusions = Diffusion.objects.select_related().filter(
datetime__range=(date_start, date_end)).order_by('datetime')
diffusions = [x for x in diffusions if x.datetime >= date_start and
x.datetime < date_end]
dt = datetime(2007, 1, date.weekday()+1, Schedule.DAY_HOUR_START)
day_schedule = Schedule.objects.select_related().filter(
datetime__gte=dt, datetime__lt=dt+timedelta(days=1)).order_by('datetime')
week_no = (date.day-1) // 7
program = [x for x in day_schedule if x.match_week(week_no)]
# the secondary sortkey puts schedules that happens everyweek after
# specific ones, this will be useful later on, when multiple schedules
# happen at the same time and we have to remove the least specific.
period_schedules = Schedule.objects.select_related().order_by('datetime', 'weeks')
program = []
current_date = date_start
while current_date < date_end:
week_day = current_date.weekday()
week_no = ((current_date.day-1) // 7)
day_schedules = [x for x in period_schedules if x.get_weekday() == week_day and x.match_week(week_no)]
for schedule in day_schedules:
schedule.datetime = datetime(
current_date.year, current_date.month, current_date.day,
schedule.datetime.hour, schedule.datetime.minute) + \
timedelta(days=schedule.datetime.weekday()-current_date.weekday())
program.extend(day_schedules)
current_date += timedelta(days=1)
for i, schedule in enumerate(program):
if schedule is None:
continue
# look for a diffusion matching this schedule
d = [x for x in diffusions if x.datetime.hour == schedule.datetime.hour
and x.datetime.minute == schedule.datetime.minute]
d = [x for x in diffusions if x.datetime.timetuple()[:5] == schedule.datetime.timetuple()[:5]]
if d:
program[i] = d[0]
for j, other_schedule in enumerate(program[i+1:]):
if other_schedule.datetime.hour == schedule.datetime.hour and \
other_schedule.datetime.minute == schedule.datetime.minute:
if other_schedule.datetime.timetuple()[:5] == schedule.datetime.timetuple()[:5]:
program[i+1+j] = None
else:
break
else:
# update schedule datetime to be the requested day
schedule.datetime = datetime(date.year, date.month, date.day,
schedule.datetime.hour, schedule.datetime.minute)
if schedule.datetime.hour < Schedule.DAY_HOUR_START:
schedule.datetime += timedelta(days=1)
program = [x for x in program if x is not None]
for i, slot in enumerate(program):
......@@ -103,3 +106,8 @@ def day_program(date):
j += 1
return [x for x in program if x is not None]
def day_program(date):
date_start = datetime(*date.timetuple()[:3])
date_end = date_start + timedelta(days=1)
return period_program(date_start, date_end)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment