summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
Diffstat (limited to 'program')
-rw-r--r--program/admin.py43
-rw-r--r--program/forms.py15
-rw-r--r--program/management/__init__.py2
-rw-r--r--program/management/commands/__init__.py2
-rw-r--r--program/models.py188
-rw-r--r--program/templatetags/content_boxes.py4
-rw-r--r--program/templatetags/timeslots.py13
-rw-r--r--program/urls.py57
-rw-r--r--program/views.py129
9 files changed, 309 insertions, 144 deletions
diff --git a/program/admin.py b/program/admin.py
index 6a542bc..7b52fa4 100644
--- a/program/admin.py
+++ b/program/admin.py
@@ -1,28 +1,34 @@
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
-from models import BroadcastFormat, MusicFocus, ShowInformation, ShowTopic, Host, Note, ProgramSlot, Show, TimeSlot
+from models import (BroadcastFormat, MusicFocus, ShowInformation, ShowTopic,
+ Host, Note, ProgramSlot, Show, TimeSlot)
from forms import MusicFocusForm
from datetime import date
+
class BroadcastFormatAdmin(admin.ModelAdmin):
list_display = ('format', 'enabled', 'admin_color')
prepopulated_fields = {'slug': ('format',)}
+
class MusicFocusAdmin(admin.ModelAdmin):
form = MusicFocusForm
list_display = ('focus', 'abbrev', 'admin_buttons')
prepopulated_fields = {'slug': ('focus',)}
+
class ShowInformationAdmin(admin.ModelAdmin):
list_display = ('information', 'abbrev', 'admin_buttons')
prepopulated_fields = {'slug': ('information',)}
+
class ShowTopicAdmin(admin.ModelAdmin):
list_display = ('topic', 'abbrev', 'admin_buttons')
prepopulated_fields = {'slug': ('topic',)}
+
class NoteAdmin(admin.ModelAdmin):
date_hierarchy = 'start'
list_display = ('title', 'show', 'start', 'status')
@@ -33,49 +39,66 @@ class NoteAdmin(admin.ModelAdmin):
shows = request.user.shows.all()
return super(NoteAdmin, self).queryset(request).filter(show__in=shows)
- def formfield_for_foreignkey(self, db_field, request, **kwargs):
+ def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'timeslot':
shows = request.user.shows.all()
kwargs['queryset'] = TimeSlot.objects.filter(show__in=shows)
- return super(NoteAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super(NoteAdmin, self).formfield_for_foreignkey(db_field,
+ request,
+ **kwargs)
def save_model(self, request, obj, form, change):
obj.save()
+
class TimeSlotInline(admin.TabularInline):
model = TimeSlot
+
def renew(modeladmin, request, queryset):
- next_year = date.today().year+1
+ next_year = date.today().year + 1
queryset.update(until=date(next_year, 12, 31))
+
+
renew.short_description = _("Renew selected time slots")
+
class ProgramSlotAdmin(admin.ModelAdmin):
actions = (renew,)
inlines = (TimeSlotInline,)
- list_display = ('show', 'byweekday', 'rrule', 'tstart', 'tend', 'until', 'timeslot_count')
+ list_display = ('show', 'byweekday', 'rrule', 'tstart', 'tend', 'until',
+ 'timeslot_count')
list_filter = ('byweekday', 'rrule', 'is_repetition')
ordering = ('byweekday', 'dstart')
save_on_top = True
search_fields = ('show__name',)
+
class ProgramSlotInline(admin.TabularInline):
model = ProgramSlot
+
class ShowAdmin(admin.ModelAdmin):
- filter_horizontal = ('hosts', 'owners', 'musicfocus', 'showinformation', 'showtopic')
+ filter_horizontal = ('hosts', 'owners', 'musicfocus', 'showinformation',
+ 'showtopic')
inlines = (ProgramSlotInline,)
- list_display = ('name', 'short_description', 'broadcastformat', 'has_active_programslots')
- list_filter = ('broadcastformat', 'showinformation', 'showtopic', 'musicfocus',)
+ list_display = ('name', 'short_description', 'broadcastformat',
+ 'has_active_programslots')
+ list_filter = ('broadcastformat', 'showinformation', 'showtopic',
+ 'musicfocus',)
ordering = ('slug',)
prepopulated_fields = {'slug': ('name',)}
search_fields = ('name', 'short_description', 'description')
fields = (
- 'predecessor', 'broadcastformat', 'name', 'slug', 'image', 'image_enabled', 'short_description', 'description', 'email',
- 'website', 'cba_series_id', 'automation_id', 'hosts', 'owners', 'showinformation', 'showtopic', 'musicfocus',
+ 'predecessor', 'broadcastformat', 'name', 'slug', 'image',
+ 'image_enabled', 'short_description', 'description',
+ 'email',
+ 'website', 'cba_series_id', 'automation_id', 'hosts', 'owners',
+ 'showinformation', 'showtopic', 'musicfocus',
)
+
admin.site.register(BroadcastFormat, BroadcastFormatAdmin)
admin.site.register(MusicFocus, MusicFocusAdmin)
admin.site.register(ShowInformation, ShowInformationAdmin)
diff --git a/program/forms.py b/program/forms.py
index 0ecd371..0c33b20 100644
--- a/program/forms.py
+++ b/program/forms.py
@@ -1,15 +1,16 @@
-from django import forms
+from django.forms import ModelForm, ValidationError
from django.core.files.images import get_image_dimensions
from program.models import MusicFocus, ShowInformation, ShowTopic
-class FormWithButton(forms.ModelForm):
+
+class FormWithButton(ModelForm):
def clean_button(self):
button = self.cleaned_data.get('button')
if button:
width, height = get_image_dimensions(button)
if width != 11 or height != 11:
- raise forms.ValidationError("width or height is not 11, (11x11)")
+ raise ValidationError("width or height is not 11, (11x11)")
return button
def clean_button_hover(self):
@@ -17,7 +18,7 @@ class FormWithButton(forms.ModelForm):
if button_hover:
width, height = get_image_dimensions(button_hover)
if width != 11 or height != 11:
- raise forms.ValidationError("width or height is not 11, (11x11)")
+ raise ValidationError("width or height is not 11, (11x11)")
return button_hover
def clean_big_button(self):
@@ -25,18 +26,20 @@ class FormWithButton(forms.ModelForm):
if big_button:
width, height = get_image_dimensions(big_button)
if width != 17 or height != 17:
- raise forms.ValidationError("width or height is not 17, (17x17)")
+ raise ValidationError("width or height is not 17, (17x17)")
return big_button
+
class MusicFocusForm(FormWithButton):
class Meta:
model = MusicFocus
+
class ShowInformationForm(FormWithButton):
class Meta:
model = ShowInformation
+
class ShowTopicForm(FormWithButton):
class Meta:
model = ShowTopic
-
diff --git a/program/management/__init__.py b/program/management/__init__.py
index 3aa4ca5..e69de29 100644
--- a/program/management/__init__.py
+++ b/program/management/__init__.py
@@ -1,2 +0,0 @@
-__author__ = 'ers'
- \ No newline at end of file
diff --git a/program/management/commands/__init__.py b/program/management/commands/__init__.py
index 3aa4ca5..e69de29 100644
--- a/program/management/commands/__init__.py
+++ b/program/management/commands/__init__.py
@@ -1,2 +0,0 @@
-__author__ = 'ers'
- \ No newline at end of file
diff --git a/program/models.py b/program/models.py
index 7cdc345..50b5889 100644
--- a/program/models.py
+++ b/program/models.py
@@ -1,5 +1,6 @@
from django.contrib.auth.models import User
-from django.core.exceptions import ObjectDoesNotExist, ValidationError, MultipleObjectsReturned
+from django.core.exceptions import (ObjectDoesNotExist, ValidationError,
+ MultipleObjectsReturned)
from django.db import models
from django.utils.translation import ugettext_lazy as _
@@ -11,11 +12,13 @@ from dateutil.rrule import rrule
from utils import get_automation_id_choices
+
class BroadcastFormat(models.Model):
format = models.CharField(_("Format"), max_length=32)
slug = models.SlugField(_("Slug"), max_length=32, unique=True)
color = models.CharField(_("Color"), max_length=7, default='#ffffff')
- text_color = models.CharField(_("Text color"), max_length=7, default='#000000')
+ text_color = models.CharField(_("Text color"), max_length=7,
+ default='#000000')
enabled = models.BooleanField(_("Enabled"), default=True)
class Meta:
@@ -24,20 +27,26 @@ class BroadcastFormat(models.Model):
verbose_name_plural = _("Broadcast formats")
def admin_color(self):
- return u'<span style="background-color: %s; color: %s; padding: 0.2em">%s/%s</span>' % (self.color, self.text_color, self.color, self.text_color)
+ return u'<span style="background-color: %s; color: %s; padding: 0.2em">%s/%s</span>' % (
+ self.color, self.text_color, self.color, self.text_color)
+
admin_color.short_description = _("Color")
admin_color.allow_tags = True
def __unicode__(self):
return u'%s' % self.format
+
class ShowInformation(models.Model):
information = models.CharField(_("Information"), max_length=32)
abbrev = models.CharField(_("Abbreviation"), max_length=4, unique=True)
slug = models.SlugField(_("Slug"), max_length=32, unique=True)
- button = models.ImageField(_("Button image"), blank=True, null=True, upload_to='buttons')
- button_hover = models.ImageField(_("Button image (hover)"), blank=True, null=True, upload_to='buttons')
- big_button = models.ImageField(_("Big button image"), blank=True, null=True, upload_to='buttons')
+ button = models.ImageField(_("Button image"), blank=True, null=True,
+ upload_to='buttons')
+ button_hover = models.ImageField(_("Button image (hover)"), blank=True,
+ null=True, upload_to='buttons')
+ big_button = models.ImageField(_("Big button image"), blank=True,
+ null=True, upload_to='buttons')
class Meta:
ordering = ('information',)
@@ -62,6 +71,7 @@ class ShowInformation(models.Model):
buttons.append(u'x')
return ' '.join(buttons)
+
admin_buttons.short_description = _("Buttons")
admin_buttons.allow_tags = True
@@ -86,13 +96,17 @@ class ShowInformation(models.Model):
def __unicode__(self):
return u'%s' % self.information
+
class ShowTopic(models.Model):
topic = models.CharField(_("Show topic"), max_length=32)
abbrev = models.CharField(_("Abbreviation"), max_length=4, unique=True)
slug = models.SlugField(_("Slug"), max_length=32, unique=True)
- button = models.ImageField(_("Button image"), blank=True, null=True, upload_to='buttons')
- button_hover = models.ImageField(_("Button image (hover)"), blank=True, null=True, upload_to='buttons')
- big_button = models.ImageField(_("Big button image"), blank=True, null=True, upload_to='buttons')
+ button = models.ImageField(_("Button image"), blank=True, null=True,
+ upload_to='buttons')
+ button_hover = models.ImageField(_("Button image (hover)"), blank=True,
+ null=True, upload_to='buttons')
+ big_button = models.ImageField(_("Big button image"), blank=True,
+ null=True, upload_to='buttons')
class Meta:
ordering = ('topic',)
@@ -117,6 +131,7 @@ class ShowTopic(models.Model):
buttons.append(u'x')
return ' '.join(buttons)
+
admin_buttons.short_description = _("Buttons")
admin_buttons.allow_tags = True
@@ -141,13 +156,17 @@ class ShowTopic(models.Model):
def __unicode__(self):
return u'%s' % self.topic
+
class MusicFocus(models.Model):
focus = models.CharField(_("Focus"), max_length=32)
abbrev = models.CharField(_("Abbreviation"), max_length=4, unique=True)
slug = models.SlugField(_("Slug"), max_length=32, unique=True)
- button = models.ImageField(_("Button image"), blank=True, null=True, upload_to='buttons')
- button_hover = models.ImageField(_("Button image (hover)"), blank=True, null=True, upload_to='buttons')
- big_button = models.ImageField(_("Big button image"), blank=True, null=True, upload_to='buttons')
+ button = models.ImageField(_("Button image"), blank=True, null=True,
+ upload_to='buttons')
+ button_hover = models.ImageField(_("Button image (hover)"), blank=True,
+ null=True, upload_to='buttons')
+ big_button = models.ImageField(_("Big button image"), blank=True,
+ null=True, upload_to='buttons')
class Meta:
ordering = ('focus',)
@@ -172,6 +191,7 @@ class MusicFocus(models.Model):
buttons.append(u'x')
return ' '.join(buttons)
+
admin_buttons.short_description = _("Buttons")
admin_buttons.allow_tags = True
@@ -196,15 +216,16 @@ class MusicFocus(models.Model):
def __unicode__(self):
return u'%s' % self.focus
+
class Host(models.Model):
name = models.CharField(_("Name"), max_length=128)
email = models.EmailField(_("E-Mail"), blank=True)
website = models.URLField(_("Website"), blank=True)
class Meta:
- ordering = ('name',)
- verbose_name = _("Host")
- verbose_name_plural = _("Hosts")
+ ordering = ('name',)
+ verbose_name = _("Host")
+ verbose_name_plural = _("Hosts")
def __unicode__(self):
return u'%s' % self.name
@@ -213,24 +234,43 @@ class Host(models.Model):
def get_absolute_url(self):
return ('host-detail', [str(self.id)])
+
class Show(models.Model):
- predecessor = models.ForeignKey('self', blank=True, null=True, related_name='successors', verbose_name=_("Predecessor"))
- hosts = models.ManyToManyField(Host, blank=True, null=True, related_name='shows', verbose_name=_("Hosts"))
- owners = models.ManyToManyField(User, blank=True, null=True, related_name='shows', verbose_name=_("Owners"))
- broadcastformat = models.ForeignKey(BroadcastFormat, related_name='shows', verbose_name=_("Broadcast format"))
- showinformation = models.ManyToManyField(ShowInformation, blank=True, null=True, related_name='shows', verbose_name=_("Show information"))
- showtopic = models.ManyToManyField(ShowTopic, blank=True, null=True, related_name='shows', verbose_name=_("Show topic"))
- musicfocus = models.ManyToManyField(MusicFocus, blank=True, null=True, related_name='shows', verbose_name=_("Music focus"))
+ predecessor = models.ForeignKey('self', blank=True, null=True,
+ related_name='successors',
+ verbose_name=_("Predecessor"))
+ hosts = models.ManyToManyField(Host, blank=True, null=True,
+ related_name='shows',
+ verbose_name=_("Hosts"))
+ owners = models.ManyToManyField(User, blank=True, null=True,
+ related_name='shows',
+ verbose_name=_("Owners"))
+ broadcastformat = models.ForeignKey(BroadcastFormat, related_name='shows',
+ verbose_name=_("Broadcast format"))
+ showinformation = models.ManyToManyField(ShowInformation, blank=True,
+ null=True, related_name='shows',
+ verbose_name=_("Show information"))
+ showtopic = models.ManyToManyField(ShowTopic, blank=True, null=True,
+ related_name='shows',
+ verbose_name=_("Show topic"))
+ musicfocus = models.ManyToManyField(MusicFocus, blank=True, null=True,
+ related_name='shows',
+ verbose_name=_("Music focus"))
name = models.CharField(_("Name"), max_length=255)
slug = models.CharField(_("Slug"), max_length=255, unique=True)
- image = models.ImageField(_("Image"), blank=True, null=True, upload_to='show_images')
- image_enabled = models.BooleanField(_("show Image"), default=True )
+ image = models.ImageField(_("Image"), blank=True, null=True,
+ upload_to='show_images')
+ image_enabled = models.BooleanField(_("show Image"), default=True)
short_description = models.CharField(_("Short description"), max_length=64)
- description = tinymce_models.HTMLField(_("Description"), blank=True, null=True)
+ description = tinymce_models.HTMLField(_("Description"), blank=True,
+ null=True)
email = models.EmailField(_("E-Mail"), blank=True, null=True)
website = models.URLField(_("Website"), blank=True, null=True)
- cba_series_id = models.IntegerField(_("CBA series ID"), blank=True, null=True)
- automation_id = models.IntegerField(_("Automation ID"), blank=True, null=True, choices=get_automation_id_choices())
+ cba_series_id = models.IntegerField(_("CBA series ID"), blank=True,
+ null=True)
+ automation_id = models.IntegerField(_("Automation ID"), blank=True,
+ null=True,
+ choices=get_automation_id_choices())
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
@@ -247,10 +287,12 @@ class Show(models.Model):
return ('show-detail', [self.slug])
def has_active_programslots(self):
- return self.programslots.filter(until__gt=date.today()).count() > 0
+ return self.programslots.filter(until__gt=date.today()).count() > 0
+
has_active_programslots.boolean = True
has_active_programslots.short_description = _("Has active program slots")
+
class RRule(models.Model):
FREQ_CHOICES = (
(1, _("Monthly")),
@@ -268,7 +310,8 @@ class RRule(models.Model):
name = models.CharField(_("Name"), max_length=32, unique=True)
freq = models.IntegerField(_("Frequency"), choices=FREQ_CHOICES)
interval = models.IntegerField(_("Interval"), default=1)
- bysetpos = models.IntegerField(_("Set position"), blank=True, choices=BYSETPOS_CHOICES, null=True)
+ bysetpos = models.IntegerField(_("Set position"), blank=True,
+ choices=BYSETPOS_CHOICES, null=True)
count = models.IntegerField(_("Count"), blank=True, null=True)
class Meta:
@@ -279,6 +322,7 @@ class RRule(models.Model):
def __unicode__(self):
return u'%s' % self.name
+
class ProgramSlot(models.Model):
BYWEEKDAY_CHOICES = (
(0, _("Monday")),
@@ -289,15 +333,19 @@ class ProgramSlot(models.Model):
(5, _("Saturday")),
(6, _("Sunday")),
)
- rrule = models.ForeignKey(RRule, related_name='programslots', verbose_name=_("Recurrence rule"))
+ rrule = models.ForeignKey(RRule, related_name='programslots',
+ verbose_name=_("Recurrence rule"))
byweekday = models.IntegerField(_("Weekday"), choices=BYWEEKDAY_CHOICES)
- show = models.ForeignKey(Show, related_name='programslots', verbose_name=_("Show"))
+ show = models.ForeignKey(Show, related_name='programslots',
+ verbose_name=_("Show"))
dstart = models.DateField(_("First date"))
tstart = models.TimeField(_("Start time"))
tend = models.TimeField(_("End time"))
until = models.DateField(_("Last date"))
is_repetition = models.BooleanField(_("Is repetition"), default=False)
- automation_id = models.IntegerField(_("Automation ID"), blank=True, null=True, choices=get_automation_id_choices())
+ automation_id = models.IntegerField(_("Automation ID"), blank=True,
+ null=True,
+ choices=get_automation_id_choices())
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
@@ -323,7 +371,13 @@ class ProgramSlot(models.Model):
def save(self, *args, **kwargs):
if self.pk:
old = ProgramSlot.objects.get(pk=self.pk)
- if self.rrule != old.rrule or self.byweekday != old.byweekday or self.show != old.show or self.dstart != old.dstart or self.tstart != old.tstart or self.tend != old.tend or self.is_repetition != old.is_repetition:
+ if self.rrule != old.rrule \
+ or self.byweekday != old.byweekday \
+ or self.show != old.show \
+ or self.dstart != old.dstart \
+ or self.tstart != old.tstart \
+ or self.tend != old.tend \
+ or self.is_repetition != old.is_repetition:
raise ValidationError(u"only until can be changed")
else:
old = False
@@ -353,28 +407,33 @@ class ProgramSlot(models.Model):
dend = self.dstart
starts = list(rrule(freq=self.rrule.freq,
- dtstart=datetime.combine(self.dstart, self.tstart),
- interval=self.rrule.interval,
- until=self.until+relativedelta(days=+1),
- bysetpos=self.rrule.bysetpos,
- byweekday=byweekday_start))
+ dtstart=datetime.combine(self.dstart, self.tstart),
+ interval=self.rrule.interval,
+ until=self.until + relativedelta(days=+1),
+ bysetpos=self.rrule.bysetpos,
+ byweekday=byweekday_start))
ends = list(rrule(freq=self.rrule.freq,
- dtstart=datetime.combine(dend, self.tend),
- interval=self.rrule.interval,
- until=self.until+relativedelta(days=+1),
- bysetpos=self.rrule.bysetpos,
- byweekday=byweekday_end))
+ dtstart=datetime.combine(dend, self.tend),
+ interval=self.rrule.interval,
+ until=self.until + relativedelta(days=+1),
+ bysetpos=self.rrule.bysetpos,
+ byweekday=byweekday_end))
if not old:
for k in range(min(len(starts), len(ends))):
- timeslot = TimeSlot.objects.create(programslot=self, start=starts[k], end=ends[k])
+ timeslot = TimeSlot.objects.create(programslot=self,
+ start=starts[k],
+ end=ends[k])
elif self.until > old.until:
for k in range(min(len(starts), len(ends))):
if starts[k].date() > old.until:
- timeslot = TimeSlot.objects.create(programslot=self, start=starts[k], end=ends[k])
+ timeslot = TimeSlot.objects.create(programslot=self,
+ start=starts[k],
+ end=ends[k])
def timeslot_count(self):
return self.timeslots.count()
+
timeslot_count.description = _("Time slot count")
def has_active_timeslot(self):
@@ -386,12 +445,15 @@ class ProgramSlot(models.Model):
else:
return False
+
class TimeSlotManager(models.Manager):
def get_or_create_current(self):
try:
- return TimeSlot.objects.get(start__lte=datetime.now(), end__gt=datetime.now())
+ return TimeSlot.objects.get(start__lte=datetime.now(),
+ end__gt=datetime.now())
except MultipleObjectsReturned:
- return TimeSlot.objects.filter(start__lte=datetime.now(), end__gt=datetime.now())[0]
+ return TimeSlot.objects.filter(start__lte=datetime.now(),
+ end__gt=datetime.now())[0]
except ObjectDoesNotExist:
once = RRule.objects.get(pk=1)
today = date.today().weekday()
@@ -403,7 +465,10 @@ class TimeSlotManager(models.Manager):
dstart, tstart = previous.end.date(), previous.end.time()
until, tend = next.start.date(), next.start.time()
- new_programslot = ProgramSlot(rrule=once, byweekday=today, show=default, dstart=dstart, tstart=tstart, tend=tend, until=until)
+ new_programslot = ProgramSlot(rrule=once, byweekday=today,
+ show=default, dstart=dstart,
+ tstart=tstart, tend=tend,
+ until=until)
try:
new_programslot.validate_unique()
new_programslot.save()
@@ -413,20 +478,26 @@ class TimeSlotManager(models.Manager):
return new_programslot.timeslots.all()[0]
def get_day_timeslots(self, day):
- today = datetime.combine(day, time(6,0))
+ today = datetime.combine(day, time(6, 0))
tomorrow = today + timedelta(days=1)
- return TimeSlot.objects.filter(models.Q(start__lte=today, end__gte=today) |
- models.Q(start__gt=today, start__lt=tomorrow)).exclude(end=today)
+ return TimeSlot.objects.filter(models.Q(start__lte=today,
+ end__gte=today) |
+ models.Q(start__gt=today,
+ start__lt=tomorrow)).exclude(end=today)
def get_24h_timeslots(self, start):
end = start + timedelta(hours=24)
- return TimeSlot.objects.filter(models.Q(start__lte=start, end__gte=start) |
- models.Q(start__gt=start, start__lt=end)).exclude(end=start)
+ return TimeSlot.objects.filter(models.Q(start__lte=start,
+ end__gte=start) |
+ models.Q(start__gt=start,
+ start__lt=end)).exclude(end=start)
+
class TimeSlot(models.Model):
- programslot = models.ForeignKey(ProgramSlot, related_name='timeslots', verbose_name=_("Program slot"))
+ programslot = models.ForeignKey(ProgramSlot, related_name='timeslots',
+ verbose_name=_("Program slot"))
start = models.DateTimeField(_("Start time"), unique=True)
end = models.DateTimeField(_("End time"))
show = models.ForeignKey(Show, editable=False, related_name='timeslots')
@@ -452,6 +523,7 @@ class TimeSlot(models.Model):
def get_absolute_url(self):
return ('timeslot-detail', [self.id])
+
class Note(models.Model):
STATUS_CHOICES = (
(0, _("Cancellation")),
@@ -461,8 +533,10 @@ class Note(models.Model):
timeslot = models.OneToOneField(TimeSlot, verbose_name=_("Time slot"))
title = models.CharField(_("Title"), max_length=128)
content = tinymce_models.HTMLField(_("Content"))
- status = models.IntegerField(_("Status"), choices=STATUS_CHOICES, default=1)
- cba_entry_id = models.IntegerField(_("CBA entry ID"), blank=True, null=True)
+ status = models.IntegerField(_("Status"), choices=STATUS_CHOICES,
+ default=1)
+ cba_entry_id = models.IntegerField(_("CBA entry ID"), blank=True,
+ null=True)
start = models.DateTimeField(editable=False)
show = models.ForeignKey(Show, editable=False, related_name='notes')
created = models.DateTimeField(auto_now_add=True, editable=False)
@@ -477,7 +551,7 @@ class Note(models.Model):
return u'%s - %s' % (self.title, self.timeslot)
def save(self, *args, **kwargs):
- self.start = self.timeslot.start
+ self.start = self.timeslot.start
self.show = self.timeslot.programslot.show
super(Note, self).save(*args, **kwargs)
diff --git a/program/templatetags/content_boxes.py b/program/templatetags/content_boxes.py
index b56f0d2..6e2b6c7 100644
--- a/program/templatetags/content_boxes.py
+++ b/program/templatetags/content_boxes.py
@@ -5,21 +5,25 @@ register = template.Library()
from program.models import BroadcastFormat, MusicFocus, ShowInformation, ShowTopic
+
@register.inclusion_tag('boxes/broadcastformat.html')
def broadcastformat():
broadcastformats = BroadcastFormat.objects.filter(enabled=True)
return {'broadcastformats': broadcastformats}
+
@register.inclusion_tag('boxes/musicfocus.html')
def musicfocus():
musicfoci = MusicFocus.objects.all()
return {'musicfoci': musicfoci}
+
@register.inclusion_tag('boxes/showinformation.html')
def showinformation():
showinformations = ShowInformation.objects.all()
return {'showinformations': showinformations}
+
@register.inclusion_tag('boxes/showtopic.html')
def showtopic():
showtopics = ShowTopic.objects.all()
diff --git a/program/templatetags/timeslots.py b/program/templatetags/timeslots.py
index 902de36..c2c44b5 100644
--- a/program/templatetags/timeslots.py
+++ b/program/templatetags/timeslots.py
@@ -4,19 +4,22 @@ register = template.Library()
from datetime import datetime, time, timedelta
+
@register.simple_tag
def duration(start, end):
return 'style="height: %dpx"' % ((end-start).seconds/60)
+
@register.simple_tag
def duration_until(end):
- start = datetime.combine(end.date(), time(6,0))
+ start = datetime.combine(end.date(), time(6, 0))
return 'style="height: %dpx"' % ((end-start).seconds/60)
+
@register.simple_tag
def duration_since(start):
- if start.time() < time(23,59):
- end = datetime.combine(start.date()+timedelta(days=1), time(6,0))
+ if start.time() < time(23, 59):
+ end = datetime.combine(start.date()+timedelta(days=1), time(6, 0))
else:
- end = datetime.combine(start.date(), time(6,0))
- return 'style="height: %dpx"' % ((end-start).seconds/60) \ No newline at end of file
+ end = datetime.combine(start.date(), time(6, 0))
+ return 'style="height: %dpx"' % ((end-start).seconds/60)
diff --git a/program/urls.py b/program/urls.py
index 59caa2a..fbdc037 100644
--- a/program/urls.py
+++ b/program/urls.py
@@ -4,16 +4,19 @@ from django.views.decorators.cache import cache_page
from django.views.generic.list_detail import object_detail, object_list
from models import Host, Show, TimeSlot
-from views import current_show, day_schedule, recommendations, show_list, week_schedule, styles
+from views import current_show, day_schedule, recommendations, show_list, \
+ week_schedule, styles
from datetime import date
hosts_dict = {
- 'queryset': Host.objects.filter(shows__programslots__until__gte=date.today()).distinct(),
+ 'queryset': Host.objects.filter(
+ shows__programslots__until__gte=date.today()).distinct(),
'template_object_name': 'host'
}
shows_dict = {
- 'queryset': Show.objects.filter(programslots__until__gt=date.today()).exclude(id=1).distinct(),
+ 'queryset': Show.objects.filter(
+ programslots__until__gt=date.today()).exclude(id=1).distinct(),
'template_object_name': 'show'
}
timeslots_dict = {
@@ -23,24 +26,38 @@ timeslots_dict = {
recommendations_dict = {'template_name': 'boxes/recommendations.html'}
urlpatterns = patterns('',
- url(r'^today/?$', day_schedule),
- url(r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/?$', day_schedule),
- url(r'^(?P<year>\d{4})/(?P<week>\d{1,2})/?$', week_schedule),
- url(r'^current_box/?$', cache_page(current_show, 60)),
- url(r'^hosts/?$', object_list, dict(hosts_dict, template_name='host_list.html')),
- url(r'^hosts/(?P<object_id>\d+)/?$', object_detail, dict(hosts_dict, template_name='host_detail.html'), name='host-detail'),
- url(r'^tips/?$', recommendations),
- url(r'^tips_box/?$', recommendations, recommendations_dict),
- url(r'^shows/?$', show_list),
- url(r'^shows/(?P<slug>[\w-]+)/?$', object_detail, dict(shows_dict, template_name='show_detail.html'), name='show-detail'),
- url(r'^(?P<object_id>\d+)/?$', object_detail, dict(timeslots_dict, template_name='timeslot_detail.html'), name='timeslot-detail'),
- url(r'^week/?$', week_schedule),
- url(r'^styles.css$', styles),
-)
+ url(r'^today/?$', day_schedule),
+ url(r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/?$',
+ day_schedule),
+ url(r'^(?P<year>\d{4})/(?P<week>\d{1,2})/?$',
+ week_schedule),
+ url(r'^current_box/?$', cache_page(current_show, 60)),
+ url(r'^hosts/?$',
+ object_list,
+ dict(hosts_dict, template_name='host_list.html')),
+ url(r'^hosts/(?P<object_id>\d+)/?$', object_detail,
+ dict(hosts_dict, template_name='host_detail.html'),
+ name='host-detail'),
+ url(r'^tips/?$', recommendations),
+ url(r'^tips_box/?$', recommendations,
+ recommendations_dict),
+ url(r'^shows/?$', show_list),
+ url(r'^shows/(?P<slug>[\w-]+)/?$', object_detail,
+ dict(shows_dict, template_name='show_detail.html'),
+ name='show-detail'),
+ url(r'^(?P<object_id>\d+)/?$', object_detail,
+ dict(timeslots_dict,
+ template_name='timeslot_detail.html'),
+ name='timeslot-detail'),
+ url(r'^week/?$', week_schedule),
+ url(r'^styles.css$', styles))
if settings.DEBUG:
import os
- PROGRAM_STATIC_DIR = os.path.join(os.path.dirname(__file__), '../site_media')
+
+ PROGRAM_STATIC_DIR = os.path.join(os.path.dirname(__file__),
+ '../site_media')
urlpatterns += patterns('',
- url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': PROGRAM_STATIC_DIR}),
- )
+ url(r'^static/(?P<path>.*)$',
+ 'django.views.static.serve',
+ {'document_root': PROGRAM_STATIC_DIR}))
diff --git a/program/views.py b/program/views.py
index bc7700e..e01868a 100644
--- a/program/views.py
+++ b/program/views.py
@@ -1,27 +1,31 @@
+from datetime import date, datetime, time, timedelta
+import json
+
from django.views.generic import list_detail, simple
from django.shortcuts import get_object_or_404
from django.db.models import Q
from django.http import HttpResponse
-from models import BroadcastFormat, MusicFocus, Note, Show, ShowInformation, ShowTopic, TimeSlot
+from models import (BroadcastFormat, MusicFocus, Note, Show, ShowInformation,
+ ShowTopic, TimeSlot)
-from datetime import date, datetime, time, timedelta
-
-import json
def show_list(request):
queryset = Show.objects.filter(programslots__until__gt=date.today()).exclude(id=1).distinct()
if 'broadcastformat' in request.GET:
- broadcastformat = get_object_or_404(BroadcastFormat, slug=request.GET['broadcastformat'])
+ broadcastformat = get_object_or_404(BroadcastFormat,
+ slug=request.GET['broadcastformat'])
queryset = queryset.filter(broadcastformat=broadcastformat)
elif 'musicfocus' in request.GET:
- musicfocus = get_object_or_404(MusicFocus, slug=request.GET['musicfocus'])
+ musicfocus = get_object_or_404(MusicFocus,
+ slug=request.GET['musicfocus'])
queryset = queryset.filter(musicfocus=musicfocus)
elif 'showinformation' in request.GET:
- showinformation = get_object_or_404(ShowInformation, slug=request.GET['showinformation'])
+ showinformation = get_object_or_404(ShowInformation,
+ slug=request.GET['showinformation'])
queryset = queryset.filter(showinformation=showinformation)
elif 'showtopic' in request.GET:
@@ -29,42 +33,57 @@ def show_list(request):
queryset = queryset.filter(showtopic=showtopic)
- return list_detail.object_list(request, queryset=queryset, template_object_name='show', template_name='show_list.html')
+ return list_detail.object_list(request, queryset=queryset,
+ template_object_name='show',
+ template_name='show_list.html')
+
def recommendations(request, template_name='recommendations.html'):
now = datetime.now()
end = now + timedelta(weeks=1)
- queryset = TimeSlot.objects.filter(Q(note__isnull=False, note__status=1, start__range=(now, end)) |
- Q(show__broadcastformat__slug='sondersendung', start__range=(now, end))).order_by('start')[:20]
- return list_detail.object_list(request, queryset=queryset, template_name=template_name, template_object_name='recommendation')
+ queryset = TimeSlot.objects.filter(Q(note__isnull=False, note__status=1,
+ start__range=(now, end)) |
+ Q(show__broadcastformat__slug='sondersendung',
+ start__range=(now, end))).order_by('start')[:20]
+ return list_detail.object_list(request, queryset=queryset,
+ template_name=template_name,
+ template_object_name='recommendation')
+
def day_schedule(request, year=None, month=None, day=None):
if year is None and month is None and day is None:
today = datetime.combine(date.today(), time(6, 0))
else:
- today = datetime.strptime('%s__%s__%s__06__00' % (year, month, day), '%Y__%m__%d__%H__%M')
+ today = datetime.strptime('%s__%s__%s__06__00' % (year, month, day),
+ '%Y__%m__%d__%H__%M')
- tomorrow = today+timedelta(days=1)
+ tomorrow = today + timedelta(days=1)
- recommendations = Note.objects.filter(status=1, timeslot__start__range=(today, tomorrow))
+ recommendations = Note.objects.filter(status=1,
+ timeslot__start__range=(today,
+ tomorrow))
default_show = Show.objects.get(pk=1)
- extra_context = dict(day=today, recommendations=recommendations, default_show=default_show)
+ extra_context = dict(day=today, recommendations=recommendations,
+ default_show=default_show)
timeslots = TimeSlot.objects.get_day_timeslots(today)
if 'broadcastformat' in request.GET:
- broadcastformat = get_object_or_404(BroadcastFormat, slug=request.GET['broadcastformat'])
+ broadcastformat = get_object_or_404(BroadcastFormat,
+ slug=request.GET['broadcastformat'])
extra_context['timeslots'] = timeslots.filter(show__broadcastformat=broadcastformat)
elif 'musicfocus' in request.GET:
- musicfocus = get_object_or_404(MusicFocus, slug=request.GET['musicfocus'])
+ musicfocus = get_object_or_404(MusicFocus,
+ slug=request.GET['musicfocus'])
extra_context['timeslots'] = timeslots.filter(show__musicfocus=musicfocus)
elif 'showinformation' in request.GET:
- showinformation = get_object_or_404(ShowInformation, slug=request.GET['showinformation'])
+ showinformation = get_object_or_404(ShowInformation,
+ slug=request.GET['showinformation'])
extra_context['timeslots'] = timeslots.filter(show__showinformation=showinformation)
elif 'showtopic' in request.GET:
@@ -74,7 +93,9 @@ def day_schedule(request, year=None, month=None, day=None):
else:
extra_context['timeslots'] = timeslots
- return simple.direct_to_template(request, extra_context=extra_context, template='day_schedule.html')
+ return simple.direct_to_template(request, extra_context=extra_context,
+ template='day_schedule.html')
+
def current_show(request):
current = TimeSlot.objects.get_or_create_current()
@@ -83,27 +104,32 @@ def current_show(request):
after_next = next.get_next_by_start()
extra_context = dict(current=current,
- previous=previous,
- next=next,
- after_next=after_next)
+ previous=previous,
+ next=next,
+ after_next=after_next)
+
+ return simple.direct_to_template(request, template='boxes/current.html',
+ extra_context=extra_context)
- return simple.direct_to_template(request, template='boxes/current.html', extra_context=extra_context)
def week_schedule(request, year=None, week=None):
if year is None and week is None:
year, week = datetime.strftime(datetime.now(), '%G__%V').split('__')
monday = tofirstdayinisoweek(int(year), int(week))
- tuesday = monday+timedelta(days=1)
- wednesday = monday+timedelta(days=2)
- thursday = monday+timedelta(days=3)
- friday = monday+timedelta(days=4)
- saturday = monday+timedelta(days=5)
- sunday = monday+timedelta(days=6)
+ tuesday = monday + timedelta(days=1)
+ wednesday = monday + timedelta(days=2)
+ thursday = monday + timedelta(days=3)
+ friday = monday + timedelta(days=4)
+ saturday = monday + timedelta(days=5)
+ sunday = monday + timedelta(days=6)
default_show = Show.objects.get(pk=1)
- extra_context = dict(monday=monday, tuesday=tuesday, wednesday=wednesday, thursday=thursday, friday=friday, saturday=saturday, sunday=sunday, default_show=default_show)
+ extra_context = dict(monday=monday, tuesday=tuesday, wednesday=wednesday,
+ thursday=thursday, friday=friday,
+ saturday=saturday, sunday=sunday,
+ default_show=default_show)
extra_context['monday_timeslots'] = TimeSlot.objects.get_day_timeslots(monday)
extra_context['tuesday_timeslots'] = TimeSlot.objects.get_day_timeslots(tuesday)
@@ -113,14 +139,21 @@ def week_schedule(request, year=None, week=None):
extra_context['saturday_timeslots'] = TimeSlot.objects.get_day_timeslots(saturday)
extra_context['sunday_timeslots'] = TimeSlot.objects.get_day_timeslots(sunday)
- extra_context['last_w'] = datetime.strftime(monday-timedelta(days=7), '%G/%V')
+ extra_context['last_w'] = datetime.strftime(monday - timedelta(days=7),
+ '%G/%V')
extra_context['cur_w'] = datetime.strftime(monday, '%G/%V')
- extra_context['next_w1'] = datetime.strftime(monday+timedelta(days=7), '%G/%V')
- extra_context['next_w2'] = datetime.strftime(monday+timedelta(days=14), '%G/%V')
- extra_context['next_w3'] = datetime.strftime(monday+timedelta(days=21), '%G/%V')
- extra_context['next_w4'] = datetime.strftime(monday+timedelta(days=28), '%G/%V')
+ extra_context['next_w1'] = datetime.strftime(monday + timedelta(days=7),
+ '%G/%V')
+ extra_context['next_w2'] = datetime.strftime(monday + timedelta(days=14),
+ '%G/%V')
+ extra_context['next_w3'] = datetime.strftime(monday + timedelta(days=21),
+ '%G/%V')
+ extra_context['next_w4'] = datetime.strftime(monday + timedelta(days=28),
+ '%G/%V')
+
+ return simple.direct_to_template(request, template='week_schedule.html',
+ extra_context=extra_context)
- return simple.direct_to_template(request, template='week_schedule.html', extra_context=extra_context)
def styles(request):
extra_context = dict()
@@ -128,25 +161,37 @@ def styles(request):
extra_context['musicfocus'] = MusicFocus.objects.all()
extra_context['showinformation'] = ShowInformation.objects.all()
extra_context['showtopic'] = ShowTopic.objects.all()
- return simple.direct_to_template(request, template='styles.css', mimetype='text/css', extra_context=extra_context)
+ return simple.direct_to_template(request, template='styles.css',
+ mimetype='text/css',
+ extra_context=extra_context)
+
def json_day_schedule(request, year=None, month=None, day=None):
if year is None and month is None and day is None:
today = datetime.combine(date.today(), time(0, 0))
else:
- today = datetime.strptime('%s__%s__%s__00__00' % (year, month, day), '%Y__%m__%d__%H__%M')
+ today = datetime.strptime('%s__%s__%s__00__00' % (year, month, day),
+ '%Y__%m__%d__%H__%M')
timeslots = TimeSlot.objects.get_24h_timeslots(today)
schedule = []
for ts in timeslots:
if ts.programslot.automation_id:
- schedule.append((ts.start.strftime('%H:%M:%S'), ts.programslot.show.name, ts.programslot.automation_id))
+ schedule.append((ts.start.strftime('%H:%M:%S'),
+ ts.programslot.show.name,
+ ts.programslot.automation_id))
elif ts.programslot.show.automation_id:
- schedule.append((ts.start.strftime('%H:%M:%S'), ts.programslot.show.name, ts.programslot.show.automation_id))
+ schedule.append(
+ (ts.start.strftime('%H:%M:%S'), ts.programslot.show.name,
+ ts.programslot.show.automation_id))
else:
- schedule.append((ts.start.strftime('%H:%M:%S'), ts.programslot.show.name, -1))
+ schedule.append((ts.start.strftime('%H:%M:%S'),
+ ts.programslot.show.name, -1))
+
+ return HttpResponse(json.dumps(schedule, ensure_ascii=False,
+ encoding='utf8').encode('utf8'),
+ content_type="application/json; charset=utf-8")
- return HttpResponse(json.dumps(schedule, ensure_ascii=False, encoding='utf8').encode('utf8'), content_type="application/json; charset=utf-8")
def tofirstdayinisoweek(year, week):
# http://stackoverflow.com/questions/5882405/get-date-from-iso-week-number-in-python