summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--locale/DE/LC_MESSAGES/django.mobin3435 -> 3761 bytes
-rw-r--r--locale/DE/LC_MESSAGES/django.po208
-rw-r--r--nop/dbrouter.py5
-rw-r--r--nop/migrations/0001_initial.py60
-rw-r--r--nop/migrations/__init__.py0
-rw-r--r--nop/models.py1
-rw-r--r--nop/urls.py15
-rw-r--r--nop/views.py21
-rw-r--r--program/admin.py58
-rw-r--r--program/forms.py18
-rw-r--r--program/management/__init__.py2
-rw-r--r--program/management/commands/__init__.py2
-rw-r--r--program/management/commands/update_hosts.py29
-rw-r--r--program/management/commands/update_programslots.py24
-rw-r--r--program/management/commands/update_shows.py29
-rw-r--r--program/migrations/0001_initial.py228
-rw-r--r--program/migrations/0002_host_is_always_visible.py19
-rw-r--r--program/migrations/0003_host_is_active.py19
-rw-r--r--program/migrations/0004_show_is_active.py19
-rw-r--r--program/migrations/0005_programslot_is_active.py19
-rw-r--r--program/migrations/__init__.py0
-rw-r--r--program/models.py143
-rw-r--r--program/templates/boxes/broadcastformat.html19
-rw-r--r--program/templates/boxes/current.html111
-rw-r--r--program/templates/boxes/musicfocus.html27
-rw-r--r--program/templates/boxes/recommendation.html39
-rw-r--r--program/templates/boxes/recommendations.html40
-rw-r--r--program/templates/boxes/showinformation.html28
-rw-r--r--program/templates/boxes/showtopic.html28
-rw-r--r--program/templates/day_schedule.html180
-rw-r--r--program/templates/host_detail.html16
-rw-r--r--program/templates/host_list.html14
-rw-r--r--program/templates/recommendation_list.html47
-rw-r--r--program/templates/recommendations.html45
-rw-r--r--program/templates/show_detail.html103
-rw-r--r--program/templates/show_list.html71
-rw-r--r--program/templates/styles.css4
-rw-r--r--program/templates/timeslot_detail.html74
-rw-r--r--program/templates/week_schedule.html26
-rw-r--r--program/templates/week_schedule_timeslot.html81
-rw-r--r--program/templatetags/content_boxes.py16
-rw-r--r--program/templatetags/timeslots.py13
-rw-r--r--program/urls.py62
-rw-r--r--program/utils.py9
-rw-r--r--program/views.py287
-rw-r--r--pv/settings.py42
-rw-r--r--pv/urls.py17
-rw-r--r--pv/wsgi.py5
-rw-r--r--requirements.txt8
50 files changed, 1484 insertions, 849 deletions
diff --git a/.gitignore b/.gitignore
index 0d113a0..3cd3c48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,5 @@ pv/local_settings.py
pv/site_media/buttons/b-*.png
pv/site_media/buttons/s-*.png
pv/site_media/buttons/r-*.png
+pv/site_media/show_images/*
+pv/cache/*
diff --git a/locale/DE/LC_MESSAGES/django.mo b/locale/DE/LC_MESSAGES/django.mo
index 6f1e394..9adeb17 100644
--- a/locale/DE/LC_MESSAGES/django.mo
+++ b/locale/DE/LC_MESSAGES/django.mo
Binary files differ
diff --git a/locale/DE/LC_MESSAGES/django.po b/locale/DE/LC_MESSAGES/django.po
index 063babb..1838efe 100644
--- a/locale/DE/LC_MESSAGES/django.po
+++ b/locale/DE/LC_MESSAGES/django.po
@@ -1,16 +1,16 @@
# Radio Helsinki program/schedule management
# Copyright (C) 2011, Ernesto Rico-Schmidt
# This file is distributed under the same license as the helsinki package.
-# Ernesto Rico-Schmidt <e.rico.schmidt@gmail.com>, 2011.
+# Ernesto Rico-Schmidt <e.rico.schmidt@gmail.com>, 2011-2016.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: helsinki-program\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-12-28 16:28+0100\n"
+"POT-Creation-Date: 2016-01-07 09:10+0100\n"
"PO-Revision-Date: 2011-06-02 22:25+0200\n"
-"Last-Translator: Ernesto Rico-Schmidt <e.rico.schmidt@gmail.com>\n"
+"Last-Translator: Ernesto Rico-Schmidt <ernesto@helsinki.at>\n"
"Language-Team: LANGUAGE <de@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
@@ -18,279 +18,321 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: program/admin.py:55
-msgid "Renew selected time slots"
+#: program/admin.py:77
+#, python-format
+msgid "1 program slot was renewed until %s"
+msgstr "eine Sendezeit wurde verlängert bis %s"
+
+#: program/admin.py:79
+#, python-format
+msgid "%s program slots were renewed until %s"
+msgstr "%s Sendezeiten wurden verlängert bis %s"
+
+#: program/admin.py:81
+msgid "Renew selected program slots"
msgstr "Ausgewählte Sendezeiten verlängern"
-#: program/models.py:13
+#: program/models.py:18
msgid "Format"
msgstr "Format"
-#: program/models.py:14 program/models.py:27 program/models.py:40
-#: program/models.py:53 program/models.py:89
+#: program/models.py:19 program/models.py:43 program/models.py:100
+#: program/models.py:157 program/models.py:239
msgid "Slug"
msgstr "Slug"
-#: program/models.py:18 program/models.py:84
+#: program/models.py:20 program/models.py:33
+msgid "Color"
+msgstr "Farbe"
+
+#: program/models.py:21
+msgid "Text color"
+msgstr "Textfarbe"
+
+#: program/models.py:22
+msgid "Enabled"
+msgstr "Aktiviert"
+
+#: program/models.py:26 program/models.py:234
msgid "Broadcast format"
msgstr "Sendungsformat"
-#: program/models.py:19
+#: program/models.py:27
msgid "Broadcast formats"
msgstr "Sendungsformate"
-#: program/models.py:25
+#: program/models.py:41
msgid "Information"
msgstr "Zusatzinformation"
-#: program/models.py:26 program/models.py:39 program/models.py:52
+#: program/models.py:42 program/models.py:99 program/models.py:156
msgid "Abbreviation"
msgstr "Abkürzung"
-#: program/models.py:31 program/models.py:32 program/models.py:85
+#: program/models.py:44 program/models.py:101 program/models.py:158
+msgid "Button image"
+msgstr "Bild-Button"
+
+#: program/models.py:45 program/models.py:102 program/models.py:159
+msgid "Button image (hover)"
+msgstr "Bild-Button (hover)"
+
+#: program/models.py:46 program/models.py:103 program/models.py:160
+msgid "Big button image"
+msgstr "Bild-Button groß"
+
+#: program/models.py:50 program/models.py:51 program/models.py:235
msgid "Show information"
msgstr "Zusatzinformation"
-#: program/models.py:38 program/models.py:44 program/models.py:86
+#: program/models.py:72 program/models.py:129 program/models.py:186
+msgid "Buttons"
+msgstr "Buttonts"
+
+#: program/models.py:98 program/models.py:107 program/models.py:236
msgid "Show topic"
msgstr "Thema/Schwerpunkt"
-#: program/models.py:45
+#: program/models.py:108
msgid "Show topics"
msgstr "Themen/Schwerpunkte"
-#: program/models.py:51
+#: program/models.py:155
msgid "Focus"
msgstr "Tendenz"
-#: program/models.py:57 program/models.py:58 program/models.py:87
+#: program/models.py:164 program/models.py:165 program/models.py:237
msgid "Music focus"
msgstr "Musiktendenz"
-#: program/models.py:64 program/models.py:88 program/models.py:130
+#: program/models.py:212 program/models.py:238 program/models.py:278
msgid "Name"
msgstr "Name"
-#: program/models.py:65 program/models.py:93
+#: program/models.py:213
+msgid "Always visible"
+msgstr "Immer sichtbar"
+
+#: program/models.py:214 program/models.py:246 program/models.py:311
+msgid "Is active"
+msgstr "Is aktiv"
+
+#: program/models.py:215 program/models.py:244
msgid "E-Mail"
msgstr "E-Mail"
-#: program/models.py:66 program/models.py:94
+#: program/models.py:216 program/models.py:245
msgid "Website"
msgstr "Website"
-#: program/models.py:70
+#: program/models.py:220
msgid "Host"
msgstr "Sendungsmacher"
-#: program/models.py:71 program/models.py:82
+#: program/models.py:221 program/models.py:232
msgid "Hosts"
msgstr "Sendungsmacher"
-#: program/models.py:81
+#: program/models.py:231
msgid "Predecessor"
msgstr "Vorgänger"
-#: program/models.py:83
+#: program/models.py:233
msgid "Owners"
msgstr "Eingentümer"
-#: program/models.py:90
+#: program/models.py:240
msgid "Image"
msgstr "Bild"
-#: program/models.py:91
+#: program/models.py:241
+msgid "show Image"
+msgstr "Zeige Bild"
+
+#: program/models.py:242
msgid "Short description"
msgstr "Kurzbeschreibung"
-#: program/models.py:92
+#: program/models.py:243
msgid "Description"
msgstr "Beschreibung"
-#: program/models.py:95
+#: program/models.py:247
msgid "CBA series ID"
msgstr "ID der Sendereihe auf CBA"
-#: program/models.py:101 program/models.py:156
+#: program/models.py:248 program/models.py:313
+msgid "Automation ID"
+msgstr "ID in der Automatiserung"
+
+#: program/models.py:254 program/models.py:306
msgid "Show"
msgstr "Sendung"
-#: program/models.py:102
+#: program/models.py:255
msgid "Shows"
msgstr "Sendungen"
-#: program/models.py:114
-msgid "Has active program slots"
-msgstr "Hat aktive Sendezeiten"
-
-#: program/models.py:118
+#: program/models.py:266
msgid "Monthly"
msgstr "monatlich"
-#: program/models.py:119
+#: program/models.py:267
msgid "Weekly"
msgstr "wöchentlich"
-#: program/models.py:120
+#: program/models.py:268
msgid "Daily"
msgstr "täglich"
-#: program/models.py:123
+#: program/models.py:271
msgid "First"
msgstr "Erster"
-#: program/models.py:124
+#: program/models.py:272
msgid "Second"
msgstr "Zweiter"
-#: program/models.py:125
+#: program/models.py:273
msgid "Third"
msgstr "Dritter"
-#: program/models.py:126
+#: program/models.py:274
msgid "Fourth"
msgstr "Vierter"
-#: program/models.py:127
+#: program/models.py:275
msgid "Fifth"
msgstr "Fünfter"
-#: program/models.py:128
+#: program/models.py:276
msgid "Last"
msgstr "Letzter"
-#: program/models.py:131
+#: program/models.py:279
msgid "Frequency"
msgstr "Häufigkeit"
-#: program/models.py:132
+#: program/models.py:280
msgid "Interval"
msgstr "Intervall"
-#: program/models.py:133
+#: program/models.py:281
msgid "Set position"
msgstr "Position"
-#: program/models.py:134
+#: program/models.py:283
msgid "Count"
msgstr "Zähler"
-#: program/models.py:138 program/models.py:154
+#: program/models.py:287 program/models.py:304
msgid "Recurrence rule"
msgstr "Wiederholungsregel"
-#: program/models.py:139
+#: program/models.py:288
msgid "Recurrence rules"
msgstr "Wiederholungsregel"
-#: program/models.py:146
+#: program/models.py:296
msgid "Monday"
msgstr "Montag"
-#: program/models.py:147
+#: program/models.py:297
msgid "Tuesday"
msgstr "Dienstag"
-#: program/models.py:148
+#: program/models.py:298
msgid "Wednesday"
msgstr "Mittwoch"
-#: program/models.py:149
+#: program/models.py:299
msgid "Thursday"
msgstr "Donnerstag"
-#: program/models.py:150
+#: program/models.py:300
msgid "Friday"
msgstr "Freitag"
-#: program/models.py:151
+#: program/models.py:301
msgid "Saturday"
msgstr "Samstag"
-#: program/models.py:152
+#: program/models.py:302
msgid "Sunday"
msgstr "Sonntag"
-#: program/models.py:155
+#: program/models.py:305
msgid "Weekday"
msgstr "Wochentag"
-#: program/models.py:157
+#: program/models.py:307
msgid "First date"
msgstr "Erstes Datum"
-#: program/models.py:158 program/models.py:277
+#: program/models.py:308 program/models.py:451
msgid "Start time"
msgstr "Beginnzeit"
-#: program/models.py:159 program/models.py:278
+#: program/models.py:309 program/models.py:452
msgid "End time"
msgstr "Endzeit"
-#: program/models.py:160
+#: program/models.py:310
msgid "Last date"
msgstr "Letztes Datum"
-#: program/models.py:161
+#: program/models.py:312
msgid "Is repetition"
msgstr "Is Wiederholung"
-#: program/models.py:168 program/models.py:276
+#: program/models.py:320 program/models.py:450
msgid "Program slot"
msgstr "Sendezeit"
-#: program/models.py:169
+#: program/models.py:321
msgid "Program slots"
msgstr "Sendezeiten"
-#: program/models.py:241
-msgid "Time slot count"
-msgstr "Zeitschlitze"
-
-#: program/models.py:285 program/models.py:308
+#: program/models.py:459 program/models.py:482
msgid "Time slot"
msgstr "Zeitschlitz"
-#: program/models.py:286
+#: program/models.py:460
msgid "Time slots"
msgstr "Zeitschlitze"
-#: program/models.py:304
+#: program/models.py:478
msgid "Cancellation"
msgstr "Ausfall"
-#: program/models.py:305
+#: program/models.py:479
msgid "Recommendation"
msgstr "Empfehlung"
-#: program/models.py:306
+#: program/models.py:480
msgid "Repetition"
msgstr "Wiederholung"
-#: program/models.py:309
-msgid "Owner"
-msgstr "Eigentümer"
-
-#: program/models.py:310
+#: program/models.py:483
msgid "Title"
msgstr "Titel"
-#: program/models.py:311
+#: program/models.py:484
msgid "Content"
msgstr "Inhalt"
-#: program/models.py:312
+#: program/models.py:485
msgid "Status"
msgstr "Status"
-#: program/models.py:313
+#: program/models.py:486
msgid "CBA entry ID"
msgstr "ID des Beitrags auf der CBA"
-#: program/models.py:321
+#: program/models.py:494
msgid "Note"
msgstr "Notiz"
-#: program/models.py:322
+#: program/models.py:495
msgid "Notes"
msgstr "Notizen"
diff --git a/nop/dbrouter.py b/nop/dbrouter.py
new file mode 100644
index 0000000..fd8aaad
--- /dev/null
+++ b/nop/dbrouter.py
@@ -0,0 +1,5 @@
+class NopRouter(object):
+ def allow_migrate(self, db, app_label, model_name=None, **hints):
+ if app_label == 'nop':
+ return db == 'nop'
+ return None
diff --git a/nop/migrations/0001_initial.py b/nop/migrations/0001_initial.py
new file mode 100644
index 0000000..67a04e8
--- /dev/null
+++ b/nop/migrations/0001_initial.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ app_label = 'nop'
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Master',
+ fields=[
+ ('timestamp', models.BigIntegerField(serialize=False, primary_key=True)),
+ ('cart', models.IntegerField()),
+ ('len', models.IntegerField(null=True, blank=True)),
+ ('showtitle', models.CharField(max_length=765, blank=True)),
+ ('title', models.CharField(max_length=765, blank=True)),
+ ('artist', models.CharField(max_length=765, blank=True)),
+ ('album', models.CharField(max_length=765, blank=True)),
+ ('ismusic', models.IntegerField(null=True, blank=True)),
+ ],
+ options={
+ 'ordering': ['-timestamp'],
+ 'db_table': 'master',
+ },
+ ),
+ migrations.CreateModel(
+ name='Standby',
+ fields=[
+ ('timestamp', models.BigIntegerField(serialize=False, primary_key=True)),
+ ('cart', models.IntegerField()),
+ ('len', models.IntegerField(null=True, blank=True)),
+ ('showtitle', models.CharField(max_length=765, blank=True)),
+ ('title', models.CharField(max_length=765, blank=True)),
+ ('artist', models.CharField(max_length=765, blank=True)),
+ ('album', models.CharField(max_length=765, blank=True)),
+ ('ismusic', models.IntegerField(null=True, blank=True)),
+ ],
+ options={
+ 'ordering': ['-timestamp'],
+ 'db_table': 'standby',
+ },
+ ),
+ migrations.CreateModel(
+ name='State',
+ fields=[
+ ('timestamp', models.BigIntegerField(serialize=False, primary_key=True)),
+ ('state', models.CharField(max_length=96, blank=True)),
+ ],
+ options={
+ 'ordering': ['-timestamp'],
+ 'db_table': 'state',
+ },
+ ),
+ ]
diff --git a/nop/migrations/__init__.py b/nop/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nop/migrations/__init__.py
diff --git a/nop/models.py b/nop/models.py
index 6aeb794..1b39eed 100644
--- a/nop/models.py
+++ b/nop/models.py
@@ -30,6 +30,7 @@ class Standby(models.Model):
db_table = u'standby'
ordering = ['-timestamp']
+
class State(models.Model):
timestamp = models.BigIntegerField(primary_key=True)
state = models.CharField(max_length=96, blank=True)
diff --git a/nop/urls.py b/nop/urls.py
index c4012a6..3cc97a4 100644
--- a/nop/urls.py
+++ b/nop/urls.py
@@ -1,14 +1,13 @@
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url
from views import get, get_current, nop_form
import os
-NOP_STATIC_DIR = os.path.join(os.path.dirname(__file__), 'site_media')
+NOP_SITE_MEDIA = os.path.join(os.path.dirname(__file__), 'site_media')
-urlpatterns = patterns(
- '',
- url(r'^/get_current/?$', get_current),
- url(r'^/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<hour>\d{1,2})/(?P<minute>\d{1,2})/?$', get),
- url(r'^/?$', nop_form),
- url(r'^/static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': NOP_STATIC_DIR}),
+urlpatterns = patterns('',
+ url(r'^/get_current/?$', get_current),
+ url(r'^/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<hour>\d{1,2})/(?P<minute>\d{1,2})/?$', get),
+ url(r'^/?$', nop_form),
+ url(r'^/static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': NOP_SITE_MEDIA}),
)
diff --git a/nop/views.py b/nop/views.py
index 6bbdcf8..12e2ada 100644
--- a/nop/views.py
+++ b/nop/views.py
@@ -5,7 +5,7 @@ from django.shortcuts import render_to_response
from django.http import HttpResponse
from django import forms
from models import Master, Standby, State
-from program.models import TimeSlot, Note
+from program.models import TimeSlot
import json
import time
@@ -60,7 +60,8 @@ def _which(timestamp=None):
def _get_show(datetime=None):
try:
if datetime:
- timeslot = TimeSlot.objects.get(start__lte=datetime, end__gt=datetime)
+ timeslot = TimeSlot.objects.get(start__lte=datetime,
+ end__gt=datetime)
else:
timeslot = TimeSlot.objects.get_or_create_current()
except (ObjectDoesNotExist, MultipleObjectsReturned):
@@ -83,7 +84,8 @@ def _current():
album = None
show = _get_show()
- if show['id'] in MUSIKPROG_IDS or (show['id'] in SPECIAL_PROGRAM_IDS and not show['note']):
+ if show['id'] in MUSIKPROG_IDS \
+ or (show['id'] in SPECIAL_PROGRAM_IDS and not show['note']):
result = _which().objects.using(DB).all()[0]
artist = result.artist
title = result.title
@@ -106,7 +108,8 @@ def _bydate(year=None, month=None, day=None, hour=None, minute=None):
'title': None,
'album': None}]
else:
- ts = int(time.mktime((int(year), int(month), int(day), int(hour), int(minute), 0, 0, 0, -1))) * 1000000
+ ts = int(time.mktime((int(year), int(month), int(day), int(hour),
+ int(minute), 0, 0, 0, -1))) * 1000000
result = _which(ts).objects.using(DB).filter(timestamp__lt=ts)[:5]
return [{'show': show['name'],
'start': _dtstring(time.localtime(item.timestamp//1000000)),
@@ -117,12 +120,12 @@ def _bydate(year=None, month=None, day=None, hour=None, minute=None):
def get_current(request):
response = json.dumps(_current())
- return HttpResponse(response, mimetype='application/json')
+ return HttpResponse(response, content_type='application/json')
def get(request, year=None, month=None, day=None, hour=None, minute=None):
response = json.dumps(_bydate(year, month, day, hour, minute))
- return HttpResponse(response, mimetype='application/json')
+ return HttpResponse(response, content_type='application/json')
def nop_form(request):
@@ -130,14 +133,16 @@ def nop_form(request):
date = None
time = None
- if request.method == 'GET' and ('date' in request.GET or 'time' in request.GET):
+ if request.method == 'GET' \
+ and ('date' in request.GET or 'time' in request.GET):
form = NopForm(request.GET)
if form.is_valid():
date = form.cleaned_data['date']
time = form.cleaned_data['time']
else:
- form = NopForm(initial={'date': datetime.date(datetime.now()), 'time': datetime.time(datetime.now())})
+ form = NopForm(initial={'date': datetime.date(datetime.now()),
+ 'time': datetime.time(datetime.now())})
if not date:
date = datetime.date(datetime.now())
diff --git a/program/admin.py b/program/admin.py
index 6a542bc..e6c331a 100644
--- a/program/admin.py
+++ b/program/admin.py
@@ -4,84 +4,106 @@ from django.utils.translation import ugettext_lazy as _
from models import BroadcastFormat, MusicFocus, ShowInformation, ShowTopic, Host, Note, ProgramSlot, Show, TimeSlot
from forms import MusicFocusForm
-from datetime import date
+from datetime import date, datetime, timedelta
+
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 HostAdmin(admin.ModelAdmin):
+ list_display = ('name',)
+ list_filter = ('is_always_visible', 'is_active')
+
+
class NoteAdmin(admin.ModelAdmin):
date_hierarchy = 'start'
list_display = ('title', 'show', 'start', 'status')
list_filter = ('status',)
ordering = ('timeslot',)
+ save_as = True
- def queryset(self, request):
+ def get_queryset(self, request):
shows = request.user.shows.all()
- return super(NoteAdmin, self).queryset(request).filter(show__in=shows)
+ return super(NoteAdmin, self).get_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):
+ four_weeks = datetime.now() - timedelta(weeks=4)
if db_field.name == 'timeslot':
shows = request.user.shows.all()
- kwargs['queryset'] = TimeSlot.objects.filter(show__in=shows)
+ kwargs['queryset'] = TimeSlot.objects.filter(show__in=shows, start__gt=four_weeks)
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
- queryset.update(until=date(next_year, 12, 31))
-renew.short_description = _("Renew selected time slots")
class ProgramSlotAdmin(admin.ModelAdmin):
- actions = (renew,)
+ actions = ('renew',)
inlines = (TimeSlotInline,)
- list_display = ('show', 'byweekday', 'rrule', 'tstart', 'tend', 'until', 'timeslot_count')
- list_filter = ('byweekday', 'rrule', 'is_repetition')
+ list_display = ('show', 'byweekday', 'rrule', 'tstart', 'tend', 'until')
+ list_filter = ('byweekday', 'rrule', 'is_repetition', 'is_active')
ordering = ('byweekday', 'dstart')
save_on_top = True
search_fields = ('show__name',)
+ def renew(self, request, queryset):
+ next_year = date.today().year + 1
+ until = date(next_year, 12, 31)
+ renewed = queryset.update(until=until)
+ if renewed == 1:
+ message = _("1 program slot was renewed until %s") % until
+ else:
+ message = _("%s program slots were renewed until %s") % until
+ self.message_user(request, message)
+ renew.short_description = _("Renew selected program slots")
+
+
class ProgramSlotInline(admin.TabularInline):
model = ProgramSlot
+
class ShowAdmin(admin.ModelAdmin):
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')
+ list_filter = ('broadcastformat', 'showinformation', 'showtopic', 'musicfocus', 'is_active')
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)
admin.site.register(ShowTopic, ShowTopicAdmin)
+admin.site.register(Host, HostAdmin)
admin.site.register(Note, NoteAdmin)
admin.site.register(ProgramSlot, ProgramSlotAdmin)
admin.site.register(Show, ShowAdmin)
-
-admin.site.register(Host)
diff --git a/program/forms.py b/program/forms.py
index 0ecd371..9bfb7ad 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,23 @@ 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
+ fields = '__all__'
+
class ShowInformationForm(FormWithButton):
class Meta:
model = ShowInformation
+ fields = '__all__'
+
class ShowTopicForm(FormWithButton):
class Meta:
model = ShowTopic
-
+ fields = '__all__'
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/management/commands/update_hosts.py b/program/management/commands/update_hosts.py
new file mode 100644
index 0000000..3cb143b
--- /dev/null
+++ b/program/management/commands/update_hosts.py
@@ -0,0 +1,29 @@
+from django.core.management.base import NoArgsCommand
+
+from program.models import Host
+
+
+class Command(NoArgsCommand):
+ help = 'update host by setting is_active'
+
+ def handle_noargs(self, **options):
+ activated = 0
+ deactivated = 0
+
+ for host in Host.objects.all():
+ active_shows = 0
+ for show in host.shows.all():
+ if show.is_active:
+ active_shows += 1
+ else:
+ active_shows -= 1
+
+ host.is_active = active_shows > 0
+ host.save()
+
+ if host.is_active:
+ activated += 1
+ else:
+ deactivated += 1
+
+ print "%s hosts activated, %s hosts de-activated " % (activated, deactivated)
diff --git a/program/management/commands/update_programslots.py b/program/management/commands/update_programslots.py
new file mode 100644
index 0000000..f0cc59d
--- /dev/null
+++ b/program/management/commands/update_programslots.py
@@ -0,0 +1,24 @@
+from django.core.management.base import NoArgsCommand
+
+from program.models import ProgramSlot
+
+from datetime import date
+
+
+class Command(NoArgsCommand):
+ help = 'update programslots by setting is_active'
+
+ def handle_noargs(self, **options):
+ activated = 0
+ deactivated = 0
+
+ for programslot in ProgramSlot.objects.all():
+ programslot.is_active = programslot.until > date.today()
+ programslot.save()
+
+ if programslot.is_active:
+ activated += 1
+ else:
+ deactivated += 1
+
+ print "%s program slots activated, %s program slots de-activated" % (activated, deactivated)
diff --git a/program/management/commands/update_shows.py b/program/management/commands/update_shows.py
new file mode 100644
index 0000000..a337f21
--- /dev/null
+++ b/program/management/commands/update_shows.py
@@ -0,0 +1,29 @@
+from django.core.management.base import NoArgsCommand
+
+from program.models import Show
+
+
+class Command(NoArgsCommand):
+ help = 'update shows by setting is_active'
+
+ def handle_noargs(self, **options):
+ activated = 0
+ deactivated = 0
+
+ for show in Show.objects.exclude(pk=1):
+ for programslot in show.programslots.all():
+ active_programslots = 0
+ if programslot.is_active:
+ active_programslots += 1
+ else:
+ active_programslots -= 1
+
+ show.is_active = active_programslots > 0
+ show.save()
+
+ if show.is_active:
+ activated += 1
+ else:
+ deactivated += 1
+
+ print "%s shows activated, %s shows de-activated" % (activated, deactivated)
diff --git a/program/migrations/0001_initial.py b/program/migrations/0001_initial.py
new file mode 100644
index 0000000..bb417c9
--- /dev/null
+++ b/program/migrations/0001_initial.py
@@ -0,0 +1,228 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import tinymce.models
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='BroadcastFormat',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('format', models.CharField(max_length=32, verbose_name='Format')),
+ ('slug', models.SlugField(unique=True, max_length=32, verbose_name='Slug')),
+ ('color', models.CharField(default=b'#ffffff', max_length=7, verbose_name='Color')),
+ ('text_color', models.CharField(default=b'#000000', max_length=7, verbose_name='Text color')),
+ ('enabled', models.BooleanField(default=True, verbose_name='Enabled')),
+ ],
+ options={
+ 'ordering': ('format',),
+ 'verbose_name': 'Broadcast format',
+ 'verbose_name_plural': 'Broadcast formats',
+ },
+ ),
+ migrations.CreateModel(
+ name='Host',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('name', models.CharField(max_length=128, verbose_name='Name')),
+ ('email', models.EmailField(max_length=254, verbose_name='E-Mail', blank=True)),
+ ('website', models.URLField(verbose_name='Website', blank=True)),
+ ],
+ options={
+ 'ordering': ('name',),
+ 'verbose_name': 'Host',
+ 'verbose_name_plural': 'Hosts',
+ },
+ ),
+ migrations.CreateModel(
+ name='MusicFocus',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('focus', models.CharField(max_length=32, verbose_name='Focus')),
+ ('abbrev', models.CharField(unique=True, max_length=4, verbose_name='Abbreviation')),
+ ('slug', models.SlugField(unique=True, max_length=32, verbose_name='Slug')),
+ ('button', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Button image', blank=True)),
+ ('button_hover', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Button image (hover)', blank=True)),
+ ('big_button', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Big button image', blank=True)),
+ ],
+ options={
+ 'ordering': ('focus',),
+ 'verbose_name': 'Music focus',
+ 'verbose_name_plural': 'Music focus',
+ },
+ ),
+ migrations.CreateModel(
+ name='Note',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('title', models.CharField(max_length=128, verbose_name='Title')),
+ ('content', tinymce.models.HTMLField(verbose_name='Content')),
+ ('status', models.IntegerField(default=1, verbose_name='Status', choices=[(0, 'Cancellation'), (1, 'Recommendation'), (2, 'Repetition')])),
+ ('cba_entry_id', models.IntegerField(null=True, verbose_name='CBA entry ID', blank=True)),
+ ('start', models.DateTimeField(editable=False)),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ('last_updated', models.DateTimeField(auto_now=True)),
+ ],
+ options={
+ 'ordering': ('timeslot',),
+ 'verbose_name': 'Note',
+ 'verbose_name_plural': 'Notes',
+ },
+ ),
+ migrations.CreateModel(
+ name='ProgramSlot',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('byweekday', models.IntegerField(verbose_name='Weekday', choices=[(0, 'Monday'), (1, 'Tuesday'), (2, 'Wednesday'), (3, 'Thursday'), (4, 'Friday'), (5, 'Saturday'), (6, 'Sunday')])),
+ ('dstart', models.DateField(verbose_name='First date')),
+ ('tstart', models.TimeField(verbose_name='Start time')),
+ ('tend', models.TimeField(verbose_name='End time')),
+ ('until', models.DateField(verbose_name='Last date')),
+ ('is_repetition', models.BooleanField(default=False, verbose_name='Is repetition')),
+ ('automation_id', models.IntegerField(blank=True, null=True, verbose_name='Automation ID', choices=[])),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ('last_updated', models.DateTimeField(auto_now=True)),
+ ],
+ options={
+ 'ordering': ('dstart', 'tstart'),
+ 'verbose_name': 'Program slot',
+ 'verbose_name_plural': 'Program slots',
+ },
+ ),
+ migrations.CreateModel(
+ name='RRule',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('name', models.CharField(unique=True, max_length=32, verbose_name='Name')),
+ ('freq', models.IntegerField(verbose_name='Frequency', choices=[(1, 'Monthly'), (2, 'Weekly'), (3, 'Daily')])),
+ ('interval', models.IntegerField(default=1, verbose_name='Interval')),
+ ('bysetpos', models.IntegerField(blank=True, null=True, verbose_name='Set position', choices=[(1, 'First'), (2, 'Second'), (3, 'Third'), (4, 'Fourth'), (5, 'Fifth'), (-1, 'Last')])),
+ ('count', models.IntegerField(null=True, verbose_name='Count', blank=True)),
+ ],
+ options={
+ 'ordering': ('-freq', 'interval', 'bysetpos'),
+ 'verbose_name': 'Recurrence rule',
+ 'verbose_name_plural': 'Recurrence rules',
+ },
+ ),
+ migrations.CreateModel(
+ name='Show',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('name', models.CharField(max_length=255, verbose_name='Name')),
+ ('slug', models.CharField(unique=True, max_length=255, verbose_name='Slug')),
+ ('image', models.ImageField(upload_to=b'show_images', null=True, verbose_name='Image', blank=True)),
+ ('image_enabled', models.BooleanField(default=True, verbose_name='show Image')),
+ ('short_description', models.CharField(max_length=64, verbose_name='Short description')),
+ ('description', tinymce.models.HTMLField(null=True, verbose_name='Description', blank=True)),
+ ('email', models.EmailField(max_length=254, null=True, verbose_name='E-Mail', blank=True)),
+ ('website', models.URLField(null=True, verbose_name='Website', blank=True)),
+ ('cba_series_id', models.IntegerField(null=True, verbose_name='CBA series ID', blank=True)),
+ ('automation_id', models.IntegerField(blank=True, null=True, verbose_name='Automation ID', choices=[])),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ('last_updated', models.DateTimeField(auto_now=True)),
+ ('broadcastformat', models.ForeignKey(related_name='shows', verbose_name='Broadcast format', to='program.BroadcastFormat')),
+ ('hosts', models.ManyToManyField(related_name='shows', verbose_name='Hosts', to='program.Host', blank=True)),
+ ('musicfocus', models.ManyToManyField(related_name='shows', verbose_name='Music focus', to='program.MusicFocus', blank=True)),
+ ('owners', models.ManyToManyField(related_name='shows', verbose_name='Owners', to=settings.AUTH_USER_MODEL, blank=True)),
+ ('predecessor', models.ForeignKey(related_name='successors', verbose_name='Predecessor', blank=True, to='program.Show', null=True)),
+ ],
+ options={
+ 'ordering': ('slug',),
+ 'verbose_name': 'Show',
+ 'verbose_name_plural': 'Shows',
+ },
+ ),
+ migrations.CreateModel(
+ name='ShowInformation',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('information', models.CharField(max_length=32, verbose_name='Information')),
+ ('abbrev', models.CharField(unique=True, max_length=4, verbose_name='Abbreviation')),
+ ('slug', models.SlugField(unique=True, max_length=32, verbose_name='Slug')),
+ ('button', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Button image', blank=True)),
+ ('button_hover', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Button image (hover)', blank=True)),
+ ('big_button', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Big button image', blank=True)),
+ ],
+ options={
+ 'ordering': ('information',),
+ 'verbose_name': 'Show information',
+ 'verbose_name_plural': 'Show information',
+ },
+ ),
+ migrations.CreateModel(
+ name='ShowTopic',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('topic', models.CharField(max_length=32, verbose_name='Show topic')),
+ ('abbrev', models.CharField(unique=True, max_length=4, verbose_name='Abbreviation')),
+ ('slug', models.SlugField(unique=True, max_length=32, verbose_name='Slug')),
+ ('button', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Button image', blank=True)),
+ ('button_hover', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Button image (hover)', blank=True)),
+ ('big_button', models.ImageField(upload_to=b'buttons', null=True, verbose_name='Big button image', blank=True)),
+ ],
+ options={
+ 'ordering': ('topic',),
+ 'verbose_name': 'Show topic',
+ 'verbose_name_plural': 'Show topics',
+ },
+ ),
+ migrations.CreateModel(
+ name='TimeSlot',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('start', models.DateTimeField(unique=True, verbose_name='Start time')),
+ ('end', models.DateTimeField(verbose_name='End time')),
+ ('programslot', models.ForeignKey(related_name='timeslots', verbose_name='Program slot', to='program.ProgramSlot')),
+ ('show', models.ForeignKey(related_name='timeslots', editable=False, to='program.Show')),
+ ],
+ options={
+ 'ordering': ('start', 'end'),
+ 'verbose_name': 'Time slot',
+ 'verbose_name_plural': 'Time slots',
+ },
+ ),
+ migrations.AddField(
+ model_name='show',
+ name='showinformation',
+ field=models.ManyToManyField(related_name='shows', verbose_name='Show information', to='program.ShowInformation', blank=True),
+ ),
+ migrations.AddField(
+ model_name='show',
+ name='showtopic',
+ field=models.ManyToManyField(related_name='shows', verbose_name='Show topic', to='program.ShowTopic', blank=True),
+ ),
+ migrations.AddField(
+ model_name='programslot',
+ name='rrule',
+ field=models.ForeignKey(related_name='programslots', verbose_name='Recurrence rule', to='program.RRule'),
+ ),
+ migrations.AddField(
+ model_name='programslot',
+ name='show',
+ field=models.ForeignKey(related_name='programslots', verbose_name='Show', to='program.Show'),
+ ),
+ migrations.AddField(
+ model_name='note',
+ name='show',
+ field=models.ForeignKey(related_name='notes', editable=False, to='program.Show'),
+ ),
+ migrations.AddField(
+ model_name='note',
+ name='timeslot',
+ field=models.OneToOneField(verbose_name='Time slot', to='program.TimeSlot'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='programslot',
+ unique_together=set([('rrule', 'byweekday', 'dstart', 'tstart')]),
+ ),
+ ]
diff --git a/program/migrations/0002_host_is_always_visible.py b/program/migrations/0002_host_is_always_visible.py
new file mode 100644
index 0000000..9abf2bd
--- /dev/null
+++ b/program/migrations/0002_host_is_always_visible.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('program', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='host',
+ name='is_always_visible',
+ field=models.BooleanField(default=False, verbose_name='Is always visible'),
+ ),
+ ]
diff --git a/program/migrations/0003_host_is_active.py b/program/migrations/0003_host_is_active.py
new file mode 100644
index 0000000..28c1049
--- /dev/null
+++ b/program/migrations/0003_host_is_active.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('program', '0002_host_is_always_visible'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='host',
+ name='is_active',
+ field=models.BooleanField(default=True, verbose_name='Is active', editable=False),
+ ),
+ ]
diff --git a/program/migrations/0004_show_is_active.py b/program/migrations/0004_show_is_active.py
new file mode 100644
index 0000000..26e3205
--- /dev/null
+++ b/program/migrations/0004_show_is_active.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('program', '0003_host_is_active'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='show',
+ name='is_active',
+ field=models.BooleanField(default=True, verbose_name='Is active', editable=False),
+ ),
+ ]
diff --git a/program/migrations/0005_programslot_is_active.py b/program/migrations/0005_programslot_is_active.py
new file mode 100644
index 0000000..31975c8
--- /dev/null
+++ b/program/migrations/0005_programslot_is_active.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('program', '0004_show_is_active'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='programslot',
+ name='is_active',
+ field=models.BooleanField(default=True, verbose_name='Is active', editable=False),
+ ),
+ ]
diff --git a/program/migrations/__init__.py b/program/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/program/migrations/__init__.py
diff --git a/program/models.py b/program/models.py
index 7cdc345..d755248 100644
--- a/program/models.py
+++ b/program/models.py
@@ -1,6 +1,8 @@
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist, ValidationError, MultipleObjectsReturned
+from django.core.urlresolvers import reverse
from django.db import models
+from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from tinymce import models as tinymce_models
@@ -11,6 +13,7 @@ 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)
@@ -24,13 +27,16 @@ 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)
@@ -62,6 +68,7 @@ class ShowInformation(models.Model):
buttons.append(u'x')
return ' '.join(buttons)
+
admin_buttons.short_description = _("Buttons")
admin_buttons.allow_tags = True
@@ -86,6 +93,7 @@ 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)
@@ -117,6 +125,7 @@ class ShowTopic(models.Model):
buttons.append(u'x')
return ' '.join(buttons)
+
admin_buttons.short_description = _("Buttons")
admin_buttons.allow_tags = True
@@ -141,6 +150,7 @@ 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)
@@ -172,6 +182,7 @@ class MusicFocus(models.Model):
buttons.append(u'x')
return ' '.join(buttons)
+
admin_buttons.short_description = _("Buttons")
admin_buttons.allow_tags = True
@@ -196,39 +207,43 @@ class MusicFocus(models.Model):
def __unicode__(self):
return u'%s' % self.focus
+
class Host(models.Model):
name = models.CharField(_("Name"), max_length=128)
+ is_always_visible = models.BooleanField(_("Is always visible"), default=False)
+ is_active = models.BooleanField(_("Is active"), default=True, editable=False)
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
- @models.permalink
def get_absolute_url(self):
- return ('host-detail', [str(self.id)])
+ return reverse('host-detail', args=[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"))
+ hosts = models.ManyToManyField(Host, blank=True, related_name='shows', verbose_name=_("Hosts"))
+ owners = models.ManyToManyField(User, blank=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"))
+ showinformation = models.ManyToManyField(ShowInformation, blank=True, related_name='shows', verbose_name=_("Show information"))
+ showtopic = models.ManyToManyField(ShowTopic, blank=True, related_name='shows', verbose_name=_("Show topic"))
+ musicfocus = models.ManyToManyField(MusicFocus, blank=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_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)
email = models.EmailField(_("E-Mail"), blank=True, null=True)
website = models.URLField(_("Website"), blank=True, null=True)
+ is_active = models.BooleanField(_("Is active"), default=True, editable=False)
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)
@@ -242,14 +257,9 @@ class Show(models.Model):
def __unicode__(self):
return u'%s' % self.name
- @models.permalink
def get_absolute_url(self):
- return ('show-detail', [self.slug])
+ return reverse('show-detail', args=[self.slug])
- def has_active_programslots(self):
- 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 = (
@@ -268,7 +278,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 +290,7 @@ class RRule(models.Model):
def __unicode__(self):
return u'%s' % self.name
+
class ProgramSlot(models.Model):
BYWEEKDAY_CHOICES = (
(0, _("Monday")),
@@ -296,6 +308,7 @@ class ProgramSlot(models.Model):
tstart = models.TimeField(_("Start time"))
tend = models.TimeField(_("End time"))
until = models.DateField(_("Last date"))
+ is_active = models.BooleanField(_("Is active"), default=True, editable=False)
is_repetition = models.BooleanField(_("Is repetition"), default=False)
automation_id = models.IntegerField(_("Automation ID"), blank=True, null=True, choices=get_automation_id_choices())
created = models.DateTimeField(auto_now_add=True, editable=False)
@@ -323,11 +336,20 @@ 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
+ self.is_active = self.until > date.today()
+ self.show.is_active = self.until > date.today()
+
super(ProgramSlot, self).save(*args, **kwargs)
if self.rrule.freq == 0:
@@ -353,41 +375,30 @@ 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.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])
-
- def timeslot_count(self):
- return self.timeslots.count()
- timeslot_count.description = _("Time slot count")
-
- def has_active_timeslot(self):
- if self.timeslots.count() > 0:
- start = self.timeslots.all().order_by("start")[0].start
- end = self.timeslots.all().order_by("-end")[0].end
- now = datetime.now()
- return (start < now and end > now)
- else:
- return False
+ TimeSlot.objects.create(programslot=self, start=starts[k], end=ends[k])
+
class TimeSlotManager(models.Manager):
- def get_or_create_current(self):
+ @staticmethod
+ def get_or_create_current():
try:
return TimeSlot.objects.get(start__lte=datetime.now(), end__gt=datetime.now())
except MultipleObjectsReturned:
@@ -397,13 +408,20 @@ class TimeSlotManager(models.Manager):
today = date.today().weekday()
default = Show.objects.get(pk=1)
- previous = TimeSlot.objects.filter(end__lte=datetime.now()).order_by('-start')[0]
- next = TimeSlot.objects.filter(start__gte=datetime.now())[0]
+ previous_timeslot = TimeSlot.objects.filter(end__lte=datetime.now()).order_by('-start')[0]
+ next_timeslot = TimeSlot.objects.filter(start__gte=datetime.now())[0]
+
+ dstart, tstart = previous_timeslot.end.date(), previous_timeslot.end.time()
+ until, tend = next_timeslot.start.date(), next_timeslot.start.time()
- 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()
@@ -412,18 +430,21 @@ class TimeSlotManager(models.Manager):
else:
return new_programslot.timeslots.all()[0]
- def get_day_timeslots(self, day):
- today = datetime.combine(day, time(6,0))
+ @staticmethod
+ def get_day_timeslots(day):
+ 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(Q(start__lte=today, end__gte=today) |
+ Q(start__gt=today, start__lt=tomorrow)).exclude(end=today)
- def get_24h_timeslots(self, start):
+ @staticmethod
+ def get_24h_timeslots(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(Q(start__lte=start, end__gte=start) |
+ 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"))
@@ -448,9 +469,9 @@ class TimeSlot(models.Model):
self.show = self.programslot.show
super(TimeSlot, self).save(*args, **kwargs)
- @models.permalink
def get_absolute_url(self):
- return ('timeslot-detail', [self.id])
+ return reverse('timeslot-detail', args=[str(self.id)])
+
class Note(models.Model):
STATUS_CHOICES = (
@@ -477,7 +498,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/templates/boxes/broadcastformat.html b/program/templates/boxes/broadcastformat.html
index 76ee382..8118cdb 100644
--- a/program/templates/boxes/broadcastformat.html
+++ b/program/templates/boxes/broadcastformat.html
@@ -1,10 +1,11 @@
-{% if broadcastformats %}
-<dl id="broadcastformat" class="portlet">
- <dt class="portletHeader"><span>Legende<span></dt>
- {% for broadcastformat in broadcastformats %}
- <dd class="portletItem bcformat bf-{{ broadcastformat.slug }}">
- <a title="Sendungen mit dem Sendungsformat {{broadcastformat.format}} anzeigen." href="?broadcastformat={{ broadcastformat.slug }}">{{ broadcastformat.format }}</a>
- </dd>
- {% endfor %}
-</dl>
+{% if broadcastformat_list %}
+ <dl id="broadcastformat" class="portlet">
+ <dt class="portletHeader"><span>Legende</span></dt>
+ {% for bf in broadcastformat_list %}
+ <dd class="portletItem bcformat bf-{{ bf.slug }}">
+ <a title="Sendungen mit dem Sendungsformat {{ bf.format }} anzeigen."
+ href="?broadcastformat={{ bf.slug }}">{{ bf.format }}</a>
+ </dd>
+ {% endfor %}
+ </dl>
{% endif %}
diff --git a/program/templates/boxes/current.html b/program/templates/boxes/current.html
index ba1df21..0ac5179 100644
--- a/program/templates/boxes/current.html
+++ b/program/templates/boxes/current.html
@@ -1,60 +1,65 @@
<!doctype html>
<html>
<head>
- <meta charset="utf-8"/>
- <title>Current program box</title>
+ <meta charset="utf-8"/>
+ <title>Current program box</title>
</head>
<body>
-
- {% if previous or current or next or after_next %}
- <dl id="program-current-box" class="portlet program-box">
- <dt class="portletHeader">Programm derzeit</dt>
- <dd class="portletItem">
- <table>
- <tr class="previous">
- <td class="start">{{ previous.start|date:"H:i" }}</td>
- <td class="format bf-{{ previous.show.broadcastformat.slug }}"
- title="{{ previous.show.broadcastformat.format }}">&nbsp;</td>
- <td class="show">
- <h3><a href="{% url timeslot-detail previous.id %}">{{ previous.show.name }}</a></h3>
- </td>
- <td class="show"></td>
- </tr>
- <tr class="current">
- <td class="start">{{ current.start|date:"H:i" }}</td>
- <td class="format bf-{{ current.show.broadcastformat.slug }}"
- title="{{ current.show.broadcastformat.format }}">&#x25B6;</td>
- <td class="show">
- <h3><a href="{% url timeslot-detail current.id %}">{{ current.show.name }}</a></h3>
- {% if current.note %}
- <p>{{ current.note.title }}</p>
- {% else %}
- <p>{{ current.show.short_description }}</p>
- {% endif %}
- </td>
- </tr>
- <tr class="next">
- <td class="start">{{ next.start|date:"H:i" }}</td>
- <td class="format bf-{{ next.show.broadcastformat.slug }}"
- title="{{ next.show.broadcastformat.format }}">&nbsp;</td>
- <td class="show">
- <h3><a href="{% url timeslot-detail next.id %}">{{ next.show.name }}</a></h3>
- </td>
- <td class="show"></td>
- </tr>
- <tr class="after_next">
- <td class="start">{{ after_next.start|date:"H:i" }}</td>
- <td class="format bf-{{ after_next.show.broadcastformat.slug }}"
- title="{{ after_next.show.broadcastformat.format }}">&nbsp;</td>
- <td class="show">
- <h3><a href="{% url timeslot-detail after_next.id %}">{{ after_next.show.name }}</a></h3>
- </td>
- <td class="show"></td>
- </tr>
- </table>
- </dd>
- </dl>
- {% endif %}
-
+{% if previous_timeslot or current_timeslot or next_timeslot or after_next_timeslot %}
+ <dl id="program-current-box" class="portlet program-box">
+ <dt class="portletHeader">Programm derzeit</dt>
+ <dd class="portletItem">
+ <table>
+ <tr class="previous">
+ <td class="start">{{ previous_timeslot.start|date:"H:i" }}</td>
+ <td class="format bf-{{ previous_timeslot.show.broadcastformat.slug }}"
+ title="{{ previous_timeslot.show.broadcastformat.format }}">&nbsp;</td>
+ <td class="show">
+ <h3>
+ <a href="{% url "timeslot-detail" previous_timeslot.id %}">{{ previous_timeslot.show.name }}</a>
+ </h3>
+ </td>
+ <td class="show"></td>
+ </tr>
+ <tr class="current">
+ <td class="start">{{ current_timeslot.start|date:"H:i" }}</td>
+ <td class="format bf-{{ current_timeslot.show.broadcastformat.slug }}"
+ title="{{ current_timeslot.show.broadcastformat.format }}">&#x25B6;</td>
+ <td class="show">
+ <h3>
+ <a href="{% url "timeslot-detail" current_timeslot.id %}">{{ current_timeslot.show.name }}</a>
+ </h3>
+ {% if current_timeslot.note %}
+ <p>{{ current_timeslot.note.title }}</p>
+ {% else %}
+ <p>{{ current_timeslot.show.short_description }}</p>
+ {% endif %}
+ </td>
+ </tr>
+ <tr class="next">
+ <td class="start">{{ next_timeslot.start|date:"H:i" }}</td>
+ <td class="format bf-{{ next_timeslot.show.broadcastformat.slug }}"
+ title="{{ next_timeslot.show.broadcastformat.format }}">&nbsp;</td>
+ <td class="show">
+ <h3><a href="{% url "timeslot-detail" next_timeslot.id %}">{{ next_timeslot.show.name }}</a>
+ </h3>
+ </td>
+ <td class="show"></td>
+ </tr>
+ <tr class="after_next">
+ <td class="start">{{ after_next_timeslot.start|date:"H:i" }}</td>
+ <td class="format bf-{{ after_next_timeslot.show.broadcastformat.slug }}"
+ title="{{ after_next_timeslot.show.broadcastformat.format }}">&nbsp;</td>
+ <td class="show">
+ <h3>
+ <a href="{% url "timeslot-detail" after_next_timeslot.id %}">{{ after_next_timeslot.show.name }}</a>
+ </h3>
+ </td>
+ <td class="show"></td>
+ </tr>
+ </table>
+ </dd>
+ </dl>
+{% endif %}
</body>
</html>
diff --git a/program/templates/boxes/musicfocus.html b/program/templates/boxes/musicfocus.html
index 01fffae..021185b 100644
--- a/program/templates/boxes/musicfocus.html
+++ b/program/templates/boxes/musicfocus.html
@@ -1,14 +1,15 @@
-{% if musicfoci %}
-<dl id="filterbox_musicfocus" class="portlet filterbox">
- <dt class="portletHeader"><span>Musiktendenz<span></dt>
- <dd class="portletItem">
- <ul>
- {% for item in musicfoci %}
- <li>
- <a title="Sendungen mit der Musiktendenz {{item.focus}} anzeigen." class="abbrev mf-{{ item.abbrev }}" href="?musicfocus={{ item.slug }}">{{ item }}</a>
- </li>
- {% endfor %}
- </ul>
- </dd>
-</dl>
+{% if musicfocus_list %}
+ <dl id="filterbox_musicfocus" class="portlet filterbox">
+ <dt class="portletHeader"><span>Musiktendenz<span></dt>
+ <dd class="portletItem">
+ <ul>
+ {% for mf in musicfocus_list %}
+ <li>
+ <a title="Sendungen mit der Musiktendenz {{ mf.focus }} anzeigen."
+ class="abbrev mf-{{ mf.abbrev }}" href="?musicfocus={{ mf.slug }}">{{ mf.focus }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ </dd>
+ </dl>
{% endif %}
diff --git a/program/templates/boxes/recommendation.html b/program/templates/boxes/recommendation.html
new file mode 100644
index 0000000..3f4429e
--- /dev/null
+++ b/program/templates/boxes/recommendation.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <title>Recomendations box</title>
+</head>
+<body>
+{% if recommendation_list %}
+ <dl id="recommendations" class="portlet program-box">
+ <dt class="portletHeader">Programmhinweise</dt>
+ <dd class="portletItem">
+ <table>
+ {% for recommendation in recommendation_list %}
+ <tr>
+ <td class="start">&nbsp;</td>
+ <td class="format bf-{{ recommendation.show.broadcastformat.slug }}"
+ title="{{ recommendation.show.broadcastformat.format }}">&nbsp;</td>
+ <td class="show">
+ {{ recommendation.start|date:"d.m. H:i" }} - {{ recommendation.end|date:"H:i" }}<br/>
+ <h3>
+ <a href="{% url "timeslot-detail" recommendation.id %}">{{ recommendation.show.name }}</a>
+ </h3>
+ <p class="note-title">
+ {% if recommendation.note %}
+ {{ recommendation.note.title }}<br/>
+ {% else %}
+ {{ recommendation.show.broadcastformat.format }}<br/>
+ {% endif %}
+ <a href="{% url "timeslot-detail" recommendation.id %}">[weiter]</a>
+ </p>
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+ </dd>
+ </dl>
+{% endif %}
+</body>
+</html>
diff --git a/program/templates/boxes/recommendations.html b/program/templates/boxes/recommendations.html
deleted file mode 100644
index 2174654..0000000
--- a/program/templates/boxes/recommendations.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8"/>
- <title>Recomendations box</title>
-</head>
-<body>
- {% if recommendation_list %}
- <dl id="recommendations" class="portlet program-box">
- <dt class="portletHeader">Programmhinweise</dt>
- <dd class="portletItem">
- <table>
- {% for item in recommendation_list %}
- <tr>
- <td class="start">&nbsp;</td>
- <td class="format bf-{{ item.show.broadcastformat.slug }}"
- title="{{ item.show.broadcastformat.format }}">&nbsp;</td>
- <td class="show">
- {{ item.start|date:"d.m. H:i" }} -
- {{ item.end|date:"H:i" }}<br />
- <h3>
- <a href="{% url timeslot-detail item.id %}">{{ item.show.name }}</a>
- </h3>
- <p class="note-title">
- {% if item.note %}
- {{ item.note.title }}<br />
- {% else %}
- {{ item.show.broadcastformat.format }}<br />
- {% endif %}
- <a href="{% url timeslot-detail item.id %}">[weiter]</a>
- </p>
- </td>
- </tr>
- {% endfor %}
- </table>
- </dd>
- </dl>
- {% endif %}
-</body>
-</html>
diff --git a/program/templates/boxes/showinformation.html b/program/templates/boxes/showinformation.html
index ac4dc2c..dbbe60d 100644
--- a/program/templates/boxes/showinformation.html
+++ b/program/templates/boxes/showinformation.html
@@ -1,14 +1,16 @@
-{% if showinformations %}
-<dl id="filterbox_showinformation" class="portlet filterbox">
- <dt class="portletHeader"><span>Sendungsinfo<span></dt>
- <dd class="portletItem">
- <ul>
- {% for item in showinformations %}
- <li>
- <a title="Sendungen mit der Information {{item.information}} anzeigen." class="abbrev si-{{ item.abbrev }}" href="?showinformation={{ item.slug }}">{{ item }}</a>
- </li>
- {% endfor %}
- </ul>
- </dd>
-</dl>
+{% if showinformation_list %}
+ <dl id="filterbox_showinformation" class="portlet filterbox">
+ <dt class="portletHeader"><span>Sendungsinfo<span></dt>
+ <dd class="portletItem">
+ <ul>
+ {% for si in showinformation_list %}
+ <li>
+ <a title="Sendungen mit der Information {{ si.information }} anzeigen."
+ class="abbrev si-{{ si.abbrev }}"
+ href="?showinformation={{ si.slug }}">{{ si.information }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ </dd>
+ </dl>
{% endif %}
diff --git a/program/templates/boxes/showtopic.html b/program/templates/boxes/showtopic.html
index 3a1938d..93e873a 100644
--- a/program/templates/boxes/showtopic.html
+++ b/program/templates/boxes/showtopic.html
@@ -1,14 +1,16 @@
-{% if showtopics %}
-<dl id="filterbox_showtopic" class="portlet filterbox">
- <dt class="portletHeader"><span>Thema / Schwerpunkt<span></dt>
- <dd class="portletItem">
- <ul>
- {% for item in showtopics %}
- <li>
- <a title="Sendungen mit dem Schwerpunkt {{item.topic}} anzeigen." class="abbrev st-{{ item.abbrev }}" href="?showtopic={{ item.slug }}">{{ item }}</a>
- </li>
- {% endfor %}
- </ul>
- </dd>
-</dl>
+{% if showtopic_list %}
+ <dl id="filterbox_showtopic" class="portlet filterbox">
+ <dt class="portletHeader"><span>Thema / Schwerpunkt<span></dt>
+ <dd class="portletItem">
+ <ul>
+ {% for showtopic in showtopic_list %}
+ <li>
+ <a title="Sendungen mit dem Schwerpunkt {{ showtopic.topic }} anzeigen."
+ class="abbrev st-{{ showtopic.abbrev }}"
+ href="?showtopic={{ showtopic.slug }}">{{ showtopic.topic }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ </dd>
+ </dl>
{% endif %}
diff --git a/program/templates/day_schedule.html b/program/templates/day_schedule.html
index f338940..61005dd 100644
--- a/program/templates/day_schedule.html
+++ b/program/templates/day_schedule.html
@@ -1,43 +1,41 @@
<html>
<head>
- <title>Tagesansicht {{ day|date:"l, d.m.Y" }} &mdash; Radio Helsinki - Freies Radio Graz</title>
- <link type="text/css" href="/program/static/js/jqueryui/jquery-ui.css" rel="stylesheet" />
-
- <script type="text/javascript" src="/program/static/js/jquery/jquery.min.js"></script>
- <script type="text/javascript" src="/program/static/js/jqueryui/jquery-ui.min.js"></script>
- <script type="text/javascript" src="/program/static/js/jqueryui/ui/jquery.ui.datepicker.min.js"></script>
- <script type="text/javascript">
-jQuery(document).ready(function() {
- jQuery("#calendar").datepicker({
- dateFormat: "yy.mm.dd",
- monthNames: [ "Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" ],
- monthNamesShort: [ "Jän", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" ],
- dayNames: [ "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" ],
- dayNamesMin: [ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" ],
- dayNamesShort: [ "Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam" ],
- firstDay: 1,
- nextText: "Weiter",
- prevText: "Zurück",
- defaultDate: location.href.split('/').slice(4, 7).join('.'),
- onSelect: function(dateText, inst) {
- location = '/programm/' + dateText.split('.').join('/');
- }
- });
-});
- </script>
+ <title>Tagesansicht {{ day|date:"l, d.m.Y" }} &mdash; Radio Helsinki - Freies Radio Graz</title>
+ <script type="text/javascript" src="/program/static/js/jquery/jquery.min.js"></script>
+ <script type="text/javascript" src="/program/static/js/jquery-ui/jquery-ui.min.js"></script>
+ <script type="text/javascript" src="/program/static/js/jquery-ui/ui/jquery.ui.datepicker.min.js"></script>
+ <script type="text/javascript">
+ jQuery(document).ready(function () {
+ jQuery("#calendar").datepicker({
+ dateFormat: "yy.mm.dd",
+ monthNames: ["Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
+ monthNamesShort: ["Jän", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
+ dayNames: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
+ dayNamesMin: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
+ dayNamesShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"],
+ firstDay: 1,
+ nextText: "Weiter",
+ prevText: "Zurück",
+ defaultDate: location.href.split('/').slice(4, 7).join('.'),
+ onSelect: function (dateText, inst) {
+ location = '/programm/' + dateText.split('.').join('/');
+ }
+ });
+ });
+ </script>
</head>
<body>
<dl id="box_calendar" class="portlet calendar">
- <dt class="portletHeader"><span>Kalender<span></dt>
- <dd class="portletItem">
- <div id="calendar"></div>
- </dd>
+ <dt class="portletHeader"><span>Kalender<span></dt>
+ <dd class="portletItem">
+ <div id="calendar"></div>
+ </dd>
</dl>
{% load content_boxes %}
<div id="filter-format">
-{% broadcastformat %}
+ {% broadcastformat %}
</div>
{% comment %}
@@ -56,70 +54,76 @@ jQuery(document).ready(function() {
<h1 id="date">{{ day|date:"l, d.m.Y" }}</h1>
<div id="timeslots">
- {% for timeslot in timeslots %}
- {% if forloop.first and timeslot.start != timeslot.get_previous_by_start.end %}
- <div class="timeslot bf-{{ default_show.broadcastformat.slug }}">
- <div class="show-start">{{ timeslot.get_previous_by_start.end|date:"H:i" }}</div>
- <div class="show-abbrevs">
- {% for item in default_show.showinformation.all %}
- <span title="{{item.information}}" class="abbrev si-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in default_show.showtopic.all %}
- <span title="{{item.topic}}" class="abbrev st-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in default_show.musicfocus.all %}
- <span title="{{item.focus}}" class="abbrev mf-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- </div>
- <div class="show-detail">
- <h3 class="show-title">{{ default_show.name }}</h3>
- <p class="show-description">{{ default_show.short_description }}</p>
- </div>
- </div>
- {% endif %}
- <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}">
- <div class="show-start">{{ timeslot.start|date:"H:i" }}</div>
- <div class="show-abbrevs">
- {% for item in timeslot.show.showinformation.all %}
- <span title="{{item.information}}" class="abbrev si-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in timeslot.show.showtopic.all %}
- <span title="{{item.topic}}" class="abbrev st-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in timeslot.show.musicfocus.all %}
- <span title="{{item.focus}}" class="abbrev mf-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- </div>
- <div class="show-detail">
- <h3 class="show-title"><a href="{% url timeslot-detail timeslot.id %}">{{ timeslot.show.name }}</a></h3>
- {% if timeslot.note %}
- <p class="note-title"><strong>Heute:</strong> {{ timeslot.note.title }}</p>
- {% else %}
- <p class="show-description">{{ timeslot.show.short_description }}</p>
+ {% for timeslot in timeslots %}
+ {% if forloop.first and timeslot.start != timeslot.get_previous_by_start.end %}
+ <div class="timeslot bf-{{ default_show.broadcastformat.slug }}">
+ <div class="show-start">{{ timeslot.get_previous_by_start.end|date:"H:i" }}</div>
+ <div class="show-abbrevs">
+ {% for si in default_show.showinformation.all %}
+ <span title="{{ si.information }}"
+ class="abbrev si-{{ si.abbrev }}"><span>{{ si.abbrev }}</span></span>
+ {% endfor %}
+ {% for st in default_show.showtopic.all %}
+ <span title="{{ st.topic }}" class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+ {% endfor %}
+ {% for mf in default_show.musicfocus.all %}
+ <span title="{{ mf.focus }}" class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
+ {% endfor %}
+ </div>
+ <div class="show-detail">
+ <h3 class="show-title">{{ default_show.name }}</h3>
+ <p class="show-description">{{ default_show.short_description }}</p>
+ </div>
+ </div>
{% endif %}
- </div>
- </div>
- {% if timeslot.end != timeslot.get_next_by_start.start %}
- <div class="timeslot bf-{{ default_show.broadcastformat.slug }}">
- <div class="show-start">{{ timeslot.end|date:"H:i" }}</div>
+ <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}">
+ <div class="show-start">{{ timeslot.start|date:"H:i" }}</div>
<div class="show-abbrevs">
- {% for item in default_show.showinformation.all %}
- <span title="{{item.information}}" class="abbrev si-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in default_show.showtopic.all %}
- <span title="{{item.topic}}" class="abbrev st-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in default_show.musicfocus.all %}
- <span title="{{item.focus}}" class="abbrev mf-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
+ {% for si in timeslot.show.showinformation.all %}
+ <span title="{{ si.information }}"
+ class="abbrev si-{{ si.abbrev }}"><span>{{ si.abbrev }}</span></span>
+ {% endfor %}
+ {% for st in timeslot.show.showtopic.all %}
+ <span title="{{ st.topic }}"
+ class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+ {% endfor %}
+ {% for mf in timeslot.show.musicfocus.all %}
+ <span title="{{ mf.focus }}"
+ class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
+ {% endfor %}
</div>
<div class="show-detail">
- <h3 class="show-title">{{ default_show.name }}</h3>
- <p class="show-description">{{ default_show.short_description }}</p>
+ <h3 class="show-title"><a
+ href="{% url "timeslot-detail" timeslot.id %}">{{ timeslot.show.name }}</a></h3>
+ {% if timeslot.note %}
+ <p class="note-title"><strong>Heute:</strong> {{ timeslot.note.title }}</p>
+ {% else %}
+ <p class="show-description">{{ timeslot.show.short_description }}</p>
+ {% endif %}
</div>
</div>
- {% endif %}
- {% endfor %}
+ {% if timeslot.end != timeslot.get_next_by_start.start %}
+ <div class="timeslot bf-{{ default_show.broadcastformat.slug }}">
+ <div class="show-start">{{ timeslot.end|date:"H:i" }}</div>
+ <div class="show-abbrevs">
+ {% for si in default_show.showinformation.all %}
+ <span title="{{ si.information }}"
+ class="abbrev si-{{ si.abbrev }}"><span>{{ si.abbrev }}</span></span>
+ {% endfor %}
+ {% for st in default_show.showtopic.all %}
+ <span title="{{ st.topic }}" class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+ {% endfor %}
+ {% for mf in default_show.musicfocus.all %}
+ <span title="{{ mf.focus }}" class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
+ {% endfor %}
+ </div>
+ <div class="show-detail">
+ <h3 class="show-title">{{ default_show.name }}</h3>
+ <p class="show-description">{{ default_show.short_description }}</p>
+ </div>
+ </div>
+ {% endif %}
+ {% endfor %}
</div>
</div>
diff --git a/program/templates/host_detail.html b/program/templates/host_detail.html
index bbe801e..73182d6 100644
--- a/program/templates/host_detail.html
+++ b/program/templates/host_detail.html
@@ -9,18 +9,22 @@
<div id="shows">
<div id="shows-title">Sendungen</div>
-
- {% for show in host.shows.all %}
- <div class="show {{ show.broadcastformat.slug }}"><a href="{% url show-detail show.slug %}">{{ show }}</a></div>
- {% endfor %}
+ {% for show in host.shows.all %}
+ {% if show.is_active %}
+ <div class="show {{ show.broadcastformat.slug }}"><a
+ href="{% url "show-detail" show.slug %}">{{ show }}</a></div>
+ {% else %}
+ <div class="show {{ show.broadcastformat.slug }}">{{ show }}</div>
+ {% endif %}
+ {% endfor %}
</div>
{% if host.email %}
- <div id="email">E-Mail Adresse: <a href="{{ host.email }}">{{ host.email }}</a></div>
+ <div id="email">E-Mail Adresse: <a href="{{ host.email }}">{{ host.email }}</a></div>
{% endif %}
{% if host.website %}
- <div id="website">Website: <a href="{{ host.website }}">{{ host.website }}</a></div>
+ <div id="website">Website: <a href="{{ host.website }}">{{ host.website }}</a></div>
{% endif %}
</div>
diff --git a/program/templates/host_list.html b/program/templates/host_list.html
index d1c8427..ada9bf1 100644
--- a/program/templates/host_list.html
+++ b/program/templates/host_list.html
@@ -5,14 +5,14 @@
<body>
<div id="content-main">
- <h1>Sendungsmachende A-Z</h1>
- <div class="host-list">
-{% for host in host_list %}
- <div class="host">
- <a href="{% url host-detail host.id %}">{{ host.name }}</a>
+ <h1>Sendungsmachende A-Z</h1>
+ <div class="host-list">
+ {% for host in host_list %}
+ <div class="host">
+ <a href="{% url "host-detail" host.id %}">{{ host.name }}</a>
+ </div>
+ {% endfor %}
</div>
-{% endfor %}
- </div>
</div>
</body>
diff --git a/program/templates/recommendation_list.html b/program/templates/recommendation_list.html
new file mode 100644
index 0000000..3fcc5d1
--- /dev/null
+++ b/program/templates/recommendation_list.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+ <title>Tipps &mdash; Radio Helsinki - Freies Radio Graz</title>
+</head>
+<body>
+
+<div id="content-main" class="recommendations">
+ <h1>Programmhinweise</h1>
+ <div id="shows">
+ {% for recommendation in recommendation_list %}
+ <div class="show recommendation bf-{{ recommendation.show.broadcastformat.slug }}">
+ <div class="show-abbrevs">
+ {% for si in recommendation.show.showinformation.all %}
+ <span title="{{ si.information }}"
+ class="abbrev si-{{ si.abbrev }}"><span>{{ si.abbrev }}</span></span>
+ {% endfor %}
+ {% for st in recommendation.show.showtopic.all %}
+ <span title="{{ st.topic }}"
+ class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+ {% endfor %}
+ {% for mf in recommendation.show.musicfocus.all %}
+ <span title="{{ mf.focus }}"
+ class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
+ {% endfor %}
+ </div>
+ <div class="show-detail">
+ <h4>
+ <a href="{% url "show-detail" recommendation.show.slug %}">{{ recommendation.show.name }}</a><br/>
+ vom {{ recommendation.start|date:"d.m. H:i" }}-{{ recommendation.end|date:"H:i" }}</h4>
+ {% if recommendation.note %}
+ <h3 class="show-title">
+ <a href="{% url "timeslot-detail" recommendation.id %}">{{ recommendation.note.title }}</a>
+ </h3>
+ <div class="note-content">{{ recommendation.note.content|safe }}</div>
+ {% else %}
+ <h3 class="show-title"><a
+ href="{% url "timeslot-detail" recommendation.id %}">{{ recommendation.show.broadcastformat.format }}</a>
+ </h3>
+ {% endif %}
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/program/templates/recommendations.html b/program/templates/recommendations.html
deleted file mode 100644
index ba9a719..0000000
--- a/program/templates/recommendations.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<html>
-<head>
- <title>Tipps &mdash; Radio Helsinki - Freies Radio Graz</title>
-</head>
-<body>
-
-<div id="content-main" class="recommendations">
- <h1>Programmhinweise</h1>
- <div id="shows">
-{% for item in recommendation_list %}
- <div class="show recommendation bf-{{ item.show.broadcastformat.slug }}">
- <div class="show-abbrevs">
- {% for ab in item.show.showinformation.all %}
- <span title="{{ab.information}}" class="abbrev si-{{ ab.abbrev }}"><span>{{ ab.abbrev }}</span></span>
- {% endfor %}
- {% for ab in item.show.showtopic.all %}
- <span title="{{ab.topic}}" class="abbrev st-{{ ab.abbrev }}"><span>{{ ab.abbrev }}</span></span>
- {% endfor %}
- {% for ab in item.show.musicfocus.all %}
- <span title="{{ab.focus}}" class="abbrev mf-{{ ab.abbrev }}"><span>{{ ab.abbrev }}</span></span>
- {% endfor %}
- </div>
- <div class="show-detail">
- <h4>
- <a href="{% url show-detail item.show.slug %}">{{ item.show.name }}</a><br />
- vom {{ item.start|date:"d.m. H:i" }}-{{ item.end|date:"H:i" }}
- </h4>
- {% if item.note %}
- <h3 class="show-title">
- <a href="{% url timeslot-detail item.id %}">{{ item.note.title }}</a>
- </h3>
- <div class="note-content">{{ item.note.content|safe}}</div>
- {% else %}
- <h3 class="show-title">
- <a href="{% url timeslot-detail item.id %}">{{ item.show.broadcastformat.format }}</a>
- </h3>
- {% endif %}
- </div>
- </div>
-{% endfor %}
- </div>
-</div>
-
-</body>
-</html>
diff --git a/program/templates/show_detail.html b/program/templates/show_detail.html
index 0f4b302..7993287 100644
--- a/program/templates/show_detail.html
+++ b/program/templates/show_detail.html
@@ -8,72 +8,73 @@
<div id="content-main" class="show-detail">
- <div class="show-detail-header bf-{{show.broadcastformat.slug}}">
- <div class="show-details">
- <h1 id="name">{{ show.name }}</h1>
- {% if show.id != 1 %}
- <p id="programslots">
- {% for slot in show.programslots.all %}
- {% if slot.has_active_timeslot %}
- <span class="programslot">{{ slot }}</span><br />
- {% endif %}
- {% endfor %}
- </p>
- {% endif %}
- </div>
+ <div class="show-detail-header bf-{{ show.broadcastformat.slug }}">
+ <div class="show-details">
+ <h1 id="name">{{ show.name }}</h1>
+ {% if show.id != 1 %}
+ <p id="programslots">
+ {% for slot in show.programslots.all %}
+ {% if slot.is_active %}
+ <span class="programslot">{{ slot }}</span><br/>
+ {% endif %}
+ {% endfor %}
+ </p>
+ {% endif %}
+ </div>
- <div class="show-categorization">
- <p id="broadcastformat">{{ show.broadcastformat.format }}</p>
- {% for item in show.showinformation.all %}
- <span title="{{item.information}}" class="abbrev si-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in show.showtopic.all %}
- <span title="{{item.topic}}" class="abbrev st-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in show.musicfocus.all %}
- <span title="{{item.focus}}" class="abbrev mf-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- </div>
+ <div class="show-categorization">
+ <p id="broadcastformat">{{ show.broadcastformat.format }}</p>
+ {% for si in show.showinformation.all %}
+ <span title="{{ si.information }}" class="abbrev si-{{ si.abbrev }}"><span>{{ si.abbrev }}</span></span>
+ {% endfor %}
+ {% for st in show.showtopic.all %}
+ <span title="{{ st.topic }}" class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+ {% endfor %}
+ {% for mf in show.musicfocus.all %}
+ <span title="{{ mf.focus }}" class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
+ {% endfor %}
+ </div>
- </div>
+ </div>
<div id="short-description" class="documentDescription">{{ show.short_description }}</div>
{% if show.description %}
- <div id="description">{{ show.description|safe }}</div>
+ <div id="description">{{ show.description|safe }}</div>
{% endif %}
{% if show.image and show.image_enabled %}
- <div id="image" style="float: right;"><img src="/program/static/{{ show.image }}" width="200" alt="image"></div>
+ <div id="image" style="float: right;"><img src="/program/static/{{ show.image }}" width="200" alt="image"></div>
{% endif %}
<p>
- {% for host in show.hosts.all %}
- <a href="{% url host-detail host.id %}">{{ host }}</a><br />
- {% endfor %}
- {% if show.email %}
- <strong>Email:</strong> <a href="mailto:{{ show.email }}">{{ show.email }}</a><br />
- {% endif %}
- {% if show.website %}
- <strong>Website:</strong> <a href="{{ show.website }}">{{ show.website }}</a><br />
- {% endif %}
- {% if show.cba_series_id %}
- <strong>CBA-Link:</strong> <a href="http://cba.fro.at/series/{{ show.cba_series_id }}">CBA</a><br />
- {% endif %}
+ {% for host in show.hosts.all %}
+ <a href="{% url "host-detail" host.id %}">{{ host }}</a><br/>
+ {% endfor %}
+ {% if show.email %}
+ <strong>Email:</strong> <a href="mailto:{{ show.email }}">{{ show.email }}</a><br/>
+ {% endif %}
+ {% if show.website %}
+ <strong>Website:</strong> <a href="{{ show.website }}">{{ show.website }}</a><br/>
+ {% endif %}
+ {% if show.cba_series_id %}
+ <strong>CBA-Link:</strong> <a href="http://cba.fro.at/series/{{ show.cba_series_id }}">CBA</a><br/>
+ {% endif %}
</p>
{% if show.notes.all %}
- <br />
- <h2>Sendungstipps</h2>
- <ul class="recommendations-list">
- {% for note in show.notes.all reversed %}
- <li>
- <a href="{% url timeslot-detail note.timeslot.id %}" title="{{ note.title }}">{{ note.start|date:"d. M Y" }}:</a>
- <div class="title">{{ note.title }}</div>
- </li>
- {% endfor %}
- </ul>
- {% endif %}
+ <br/>
+ <h2>Sendungstipps</h2>
+ <ul class="recommendations-list">
+ {% for note in show.notes.all reversed %}
+ <li>
+ <a href="{% url "timeslot-detail" note.timeslot.id %}"
+ title="{{ note.title }}">{{ note.start|date:"d. M Y" }}:</a>
+ <div class="title">{{ note.title }}</div>
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
</div>
diff --git a/program/templates/show_list.html b/program/templates/show_list.html
index 167a470..62594e9 100644
--- a/program/templates/show_list.html
+++ b/program/templates/show_list.html
@@ -6,48 +6,51 @@
{% load content_boxes %}
<div id="filter-format">
-{% broadcastformat %}
+ {% broadcastformat %}
</div>
<div id="filter-topic">
- <dl id="filter-header" class="portlet">
- <dt class="portletHeader"><span>Filter<span></dt>
- </dl>
-{% musicfocus %}
-{% showinformation %}
-{% showtopic %}
+ <dl id="filter-header" class="portlet">
+ <dt class="portletHeader"><span>Filter</span></dt>
+ </dl>
+ {% musicfocus %}
+ {% showinformation %}
+ {% showtopic %}
</div>
<div id="content-main" class="show-list">
- <h1>Sendungen A-Z</h1>
+ <h1>Sendungen A-Z</h1>
- <div id="shows">
- {% for show in show_list %}
- <div class="show bf-{{ show.broadcastformat.slug }}">
- <div class="show-abbrevs">
- {% for item in show.showinformation.all %}
- <span title="{{item.information}}" class="abbrev si-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
+ <div id="shows">
+ {% for show in show_list %}
+ <div class="show bf-{{ show.broadcastformat.slug }}">
+ <div class="show-abbrevs">
+ {% for si in show.showinformation.all %}
+ <span title="{{ si.information }}"
+ class="abbrev si-{{ si.abbrev }}"><span>{{ si.abbrev }}</span></span>
+ {% endfor %}
+ {% for st in show.showtopic.all %}
+ <span title="{{ st.topic }}"
+ class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+ {% endfor %}
+ {% for mf in show.musicfocus.all %}
+ <span title="{{ mf.focus }}"
+ class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
+ {% endfor %}
+ </div>
+ <div class="show-detail">
+ <h3 class="show-title"><a href="{% url "show-detail" show.slug %}">{{ show.name }}</a></h3>
+ <ul class="show-programslots">
+ {% for programslot in show.programslots.all %}
+ {% if programslot.is_active %}
+ <li class="show-programslot">{{ programslot }}</li>
+ {% endif %}
+ {% endfor %}
+ </ul>
+ <p class="show-description">{{ show.short_description }}</p>
+ </div>
+ </div>
{% endfor %}
- {% for item in show.showtopic.all %}
- <span title="{{item.topic}}" class="abbrev st-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in show.musicfocus.all %}
- <span title="{{item.focus}}" class="abbrev mf-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- </div>
- <div class="show-detail">
- <h3 class="show-title"><a href="{% url show-detail show.slug %}">{{ show.name }}</a></h3>
- <ul class="show-programslots">
- {% for slot in show.programslots.all %}
- {% if slot.has_active_timeslot %}
- <li class="show-programslot">{{ slot }}</li>
- {% endif %}
- {% endfor %}
- </ul>
- <p class="show-description">{{ show.short_description }}</p>
- </div>
</div>
- {% endfor %}
- </div>
</div>
diff --git a/program/templates/styles.css b/program/templates/styles.css
index 2934a7f..395be34 100644
--- a/program/templates/styles.css
+++ b/program/templates/styles.css
@@ -6,10 +6,12 @@
.mf-{{ mf.abbrev }} { background-image:url({{ mf.button_url }}); }
.filterbox .mf-{{ mf.abbrev }}:hover { background-image:url({{ mf.button_hover_url }}); }
{% endfor %}
+
{% for si in showinformation %}
.si-{{ si.abbrev }} { background-image:url({{ si.button_url }}); }
.filterbox .si-{{ si.abbrev }}:hover { background-image:url({{ si.button_hover_url }}); }
{% endfor %}
+
{% for st in showtopic %}
.st-{{ st.abbrev }} { background-image:url({{ st.button_url }}); }
.filterbox .st-{{ st.abbrev }}:hover { background-image:url({{ st.button_hover_url }}); }
@@ -18,9 +20,11 @@
{% for mf in musicfocus %}
.show-detail-header .mf-{{ mf.abbrev }} { background-image:url({{ mf.big_button_url }}); }
{% endfor %}
+
{% for si in showinformation %}
.show-detail-header .si-{{ si.abbrev }} { background-image:url({{ si.big_button_url }}); }
{% endfor %}
+
{% for st in showtopic %}
.show-detail-header .st-{{ st.abbrev }} { background-image:url({{ st.big_button_url }}); }
{% endfor %}
diff --git a/program/templates/timeslot_detail.html b/program/templates/timeslot_detail.html
index 856aef3..5133320 100644
--- a/program/templates/timeslot_detail.html
+++ b/program/templates/timeslot_detail.html
@@ -6,56 +6,54 @@
<div id="content-main" class="timeslot-detail">
- <div class="show-detail-header bf-{{timeslot.show.broadcastformat.slug}}">
- <h1 id="name">
- <a href="{% url show-detail timeslot.show.slug %}">{{ timeslot.show.name }}</a>
- </h1>
- {% if timeslot.note %}
- <h2>{{ timeslot.note.title }}</h2>
- {% endif %}
- <strong>Sendung am {{ timeslot.start|date:"d.m. H:i" }} bis {{ timeslot.end|date:"H:i" }}</strong>
-
- <div class="show-abbrevs">
- {% for item in timeslot.show.showinformation.all %}
- <span title="{{item.information}}" class="abbrev si-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in timeslot.show.showtopic.all %}
- <span title="{{item.topic}}" class="abbrev st-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- {% for item in timeslot.show.musicfocus.all %}
- <span title="{{item.focus}}" class="abbrev mf-{{ item.abbrev }}"><span>{{ item.abbrev }}</span></span>
- {% endfor %}
- </div>
-
- <p id="broadcastformat">{{ timeslot.show.broadcastformat.format }}</p>
+ <div class="show-detail-header bf-{{ timeslot.show.broadcastformat.slug }}">
+ <h1 id="name">
+ <a href="{% url "show-detail" timeslot.show.slug %}">{{ timeslot.show.name }}</a>
+ </h1>
+ {% if timeslot.note %}
+ <h2>{{ timeslot.note.title }}</h2>
+ {% endif %}
+ <strong>Sendung am {{ timeslot.start|date:"d.m. H:i" }} bis {{ timeslot.end|date:"H:i" }}</strong>
+
+ <div class="show-abbrevs">
+ {% for si in timeslot.show.showinformation.all %}
+ <span title="{{ si.information }}" class="abbrev si-{{ si.abbrev }}"><span>{{ si.abbrev }}</span></span>
+ {% endfor %}
+ {% for st in timeslot.show.showtopic.all %}
+ <span title="{{ st.topic }}" class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+ {% endfor %}
+ {% for mf in timeslot.show.musicfocus.all %}
+ <span title="{{ mf.focus }}" class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
+ {% endfor %}
+ </div>
+
+ <p id="broadcastformat">{{ timeslot.show.broadcastformat.format }}</p>
</div>
{% if timeslot.note %}
- <p class="timeslot-note">{{ timeslot.note.content|safe }}</p>
+ <p class="timeslot-note">{{ timeslot.note.content|safe }}</p>
{% endif %}
<div id="short-description" class="documentDescription">{{ timeslot.show.short_description }}</div>
{% if timeslot.show.description %}
- <div id="description">{{ timeslot.show.description|safe }}</div>
+ <div id="description">{{ timeslot.show.description|safe }}</div>
{% endif %}
<p>
- {% for host in timeslot.show.hosts.all %}
- <a href="{% url host-detail host.id %}">{{ host }}</a><br />
- {% endfor %}
- {% if timeslot.show.email %}
- <strong>Email:</strong> <a href="mailto:{{ timeslot.show.email }}">{{ timeslot.show.email }}</a><br />
- {% endif %}
- {% if timeslot.show.website %}
- <strong>Website:</strong> <a href="{{ timeslot.show.website }}">{{ timeslot.show.website }}</a><br />
- {% endif %}
- {% if timeslot.show.cba_series_id %}
- <strong>CBA-Link:</strong> <a href="http://cba.fro.at/series/{{ timeslot.show.cba_series_id }}">CBA</a><br />
- {% endif %}
+ {% for host in timeslot.show.hosts.all %}
+ <a href="{% url "host-detail" host.id %}">{{ host }}</a><br/>
+ {% endfor %}
+ {% if timeslot.show.email %}
+ <strong>Email:</strong> <a href="mailto:{{ timeslot.show.email }}">{{ timeslot.show.email }}</a><br/>
+ {% endif %}
+ {% if timeslot.show.website %}
+ <strong>Website:</strong> <a href="{{ timeslot.show.website }}">{{ timeslot.show.website }}</a><br/>
+ {% endif %}
+ {% if timeslot.show.cba_series_id %}
+ <strong>CBA-Link:</strong> <a href="http://cba.fro.at/series/{{ timeslot.show.cba_series_id }}">CBA</a><br/>
+ {% endif %}
</p>
-
-
</div>
</body>
diff --git a/program/templates/week_schedule.html b/program/templates/week_schedule.html
index a10a4c1..ad6b012 100644
--- a/program/templates/week_schedule.html
+++ b/program/templates/week_schedule.html
@@ -6,17 +6,17 @@
<body>
<div id="content-main" class="week-schedule">
- <table class="week-navigation">
- <tr>
- <td><a href="/program/{{ last_w }}">&lt;--</a></td>
- <td class="current">{{ cur_w }}</td>
- <td><a href="/program/{{ next_w1 }}">{{ next_w1 }}</a></td>
- <td><a href="/program/{{ next_w2 }}">{{ next_w2 }}</a></td>
- <td><a href="/program/{{ next_w3 }}">{{ next_w3 }}</a></td>
- <td><a href="/program/{{ next_w4 }}">{{ next_w4 }}</a></td>
- <td><a href="/program/{{ next_w1 }}">--&gt;</a></td>
- </tr>
- </table>
+ <table class="week-navigation">
+ <tr>
+ <td><a href="/program/{{ last_w }}">&lt;--</a></td>
+ <td class="current">{{ cur_w }}</td>
+ <td><a href="/program/{{ next_w1 }}">{{ next_w1 }}</a></td>
+ <td><a href="/program/{{ next_w2 }}">{{ next_w2 }}</a></td>
+ <td><a href="/program/{{ next_w3 }}">{{ next_w3 }}</a></td>
+ <td><a href="/program/{{ next_w4 }}">{{ next_w4 }}</a></td>
+ <td><a href="/program/{{ next_w1 }}">--&gt;</a></td>
+ </tr>
+ </table>
<div class="weekday-starts weekday-starts-left">
<div style="height: 43px;">&nbsp;</div>
<div style="height: 60px;">06:00</div>
@@ -119,8 +119,8 @@
<div style="height: 60px;">03:00</div>
<div style="height: 60px;">04:00</div>
<div style="height: 60px;">05:00</div>
- </div>
-
+ </div>
+
</div>
</body>
diff --git a/program/templates/week_schedule_timeslot.html b/program/templates/week_schedule_timeslot.html
index f1f6918..8942327 100644
--- a/program/templates/week_schedule_timeslot.html
+++ b/program/templates/week_schedule_timeslot.html
@@ -1,51 +1,54 @@
{% load timeslots %}
-{% if forloop.first %}
- {% if timeslot.start.hour < 6 %}
- {# the day starts with the first show until its end #}
- <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration_until timeslot.end %}>
- <div><a href="{% url timeslot-detail timeslot.id %}">{{ timeslot.show.name }}</a></div>
- </div>
- {% else %}
- {# the day starts with a default show until the start of first show #}
- <div class="timeslot bf-{{ default_show.broadcastformat.slug }}" {% duration_until timeslot.start %}>
- <div>{{ default_show.name }}</div>
- </div>
- <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration timeslot.start timeslot.end %}>
- <div><a href="{% url timeslot-detail timeslot.id %}">{{ timeslot.show.name }}</a></div>
- </div>
- {% endif %}
- {% if timeslot.end != timeslot.get_next_by_start.start %}
- {# a default show is needed to fill the time until the next show #}
- <div class="timeslot bf-{{ default_show.broadcastformat.slug }}" {% duration timeslot.end timeslot.get_next_by_start.start %}>
- <div>{{ default_show.name }}</div>
- </div>
- {% endif %}
-{% elif forloop.last %}
- {% if timeslot.end.hour < 6 %}
- {# the day ends with this show and a default show until 6 #}
- <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration timeslot.start timeslot.end %}>
- <div><a href="{% url timeslot-detail timeslot.id %}">{{ timeslot.show.name }}</a></div>
- </div>
- <div class="timeslot bf-{{ default_show.broadcastformat.slug }}" {% duration_since timeslot.end %}>
- <div>{{ default_show.name }}</div>
- </div>
- {% else %}
- {# the days ends with this show #}
- <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration_since timeslot.start %}>
- <div><a href="{% url timeslot-detail timeslot.id %}">{{ timeslot.show.name }}</a></div>
- </div>
- {% endif %}
-{% else %}
+{% if forloop.first and timeslot.start != timeslot.get_previous_by_start.end %}
+ <div class="timeslot bf-{{ default_show.broadcastformat.slug }}" {% duration_until timeslot.start %}>
+ <div>{{ default_show.name }}</div>
+ </div>
+{% endif %}
+
+{% if forloop.first and timeslot.start == timeslot.get_next_by_start.end and timeslot.start != "06:00" %}
<div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration timeslot.start timeslot.end %}>
- <div><a href="{% url timeslot-detail timeslot.id %}">{{ timeslot.show.name }}</a></div>
+ <div><a href="{% url "timeslot-detail" timeslot.id %}">{{ timeslot.show.name }}</a></div>
+ </div>
+{% endif %}
+
+{% if forloop.first and timeslot.start != "06:00" and timeslot.show == default_show %}
+ <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration_until timeslot.end %}>
+ <div><a href="{% url "timeslot-detail" timeslot.id %}">{{ timeslot.show.name }}</a></div>
+ </div>
+{% endif %}
+
+{% if forloop.first and timeslot.start != "06:00" and timeslot.show != default_show %}
+ <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration timeslot.start timeslot.end %}>
+ <div><a href="{% url "timeslot-detail" timeslot.id %}">{{ timeslot.show.name }}</a></div>
+ </div>
+{% endif %}
+
+{% if not forloop.first and not forloop.last %}
+ <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration timeslot.start timeslot.end %}>
+ <div><a href="{% url "timeslot-detail" timeslot.id %}">{{ timeslot.show.name }}</a></div>
</div>
{% if timeslot.end != timeslot.get_next_by_start.start %}
- {# a default show is needed to fill the time until the next show #}
<div class="timeslot bf-{{ default_show.broadcastformat.slug }}" {% duration timeslot.end timeslot.get_next_by_start.start %}>
<div>{{ default_show.name }}</div>
</div>
{% endif %}
{% endif %}
+{% if forloop.last and timeslot.end != "06:00" and timeslot.show == default_show %}
+ <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration_since timeslot.start %}>
+ <div><a href="{% url "timeslot-detail" timeslot.id %}">{{ timeslot.show.name }}</a></div>
+ </div>
+{% endif %}
+{% if forloop.last and timeslot.end != "06:00" and timeslot.show != default_show %}
+ <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}" {% duration timeslot.start timeslot.end %}>
+ <div><a href="{% url "timeslot-detail" timeslot.id %}">{{ timeslot.show.name }}</a></div>
+ </div>
+{% endif %}
+
+{% if forloop.last and timeslot.end != timeslot.get_next_by_start.start %}
+ <div class="timeslot bf-{{ default_show.broadcastformat.slug }}" {% duration_since timeslot.end %}>
+ <div>{{ default_show.name }}</div>
+ </div>
+{% endif %}
diff --git a/program/templatetags/content_boxes.py b/program/templatetags/content_boxes.py
index b56f0d2..7f176c6 100644
--- a/program/templatetags/content_boxes.py
+++ b/program/templatetags/content_boxes.py
@@ -5,22 +5,22 @@ 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}
+ return {'broadcastformat_list': BroadcastFormat.objects.filter(enabled=True)}
+
@register.inclusion_tag('boxes/musicfocus.html')
def musicfocus():
- musicfoci = MusicFocus.objects.all()
- return {'musicfoci': musicfoci}
+ return {'musicfocus_list': MusicFocus.objects.all()}
+
@register.inclusion_tag('boxes/showinformation.html')
def showinformation():
- showinformations = ShowInformation.objects.all()
- return {'showinformations': showinformations}
+ return {'showinformation_list': ShowInformation.objects.all()}
+
@register.inclusion_tag('boxes/showtopic.html')
def showtopic():
- showtopics = ShowTopic.objects.all()
- return {'showtopics': showtopics}
+ return {'showtopic_list': 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 328f4a1..18625a4 100644
--- a/program/urls.py
+++ b/program/urls.py
@@ -1,51 +1,29 @@
from django.conf import settings
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url
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
+import views
-from datetime import date
+import os
-hosts_dict = {
- 'queryset': Host.objects.filter(shows__programslots__until__gte=date.today()).distinct(),
- 'template_object_name': 'host'
-}
-shows_dict = {
- 'queryset': Show.objects.all(),
- 'template_object_name': 'show'
-}
-timeslots_dict = {
- 'queryset': TimeSlot.objects.all(),
- 'template_object_name': 'timeslot'
-}
-recommendations_dict = {'template_name': 'boxes/recommendations.html'}
+PROGRAM_SITE_MEDIA = os.path.join(os.path.dirname(__file__), '../site_media')
-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),
-)
+urlpatterns = patterns('',
+ url(r'^today/?$', views.DayScheduleView.as_view()),
+ url(r'^week/?$', views.WeekScheduleView.as_view()),
+ url(r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/?$', views.DayScheduleView.as_view()),
+ url(r'^(?P<year>\d{4})/(?P<week>\d{1,2})/?$', views.WeekScheduleView.as_view()),
+ url(r'^current_box/?$', cache_page(60)(views.CurrentShowBoxView.as_view())),
+ url(r'^hosts/?$', views.HostListView.as_view()),
+ url(r'^hosts/(?P<pk>\d+)/?$', views.HostDetailView.as_view(), name='host-detail'),
+ url(r'^tips/?$', views.RecommendationsListView.as_view()),
+ url(r'^tips_box/?$', views.RecommendationsBoxView.as_view()),
+ url(r'^shows/?$', views.ShowListView.as_view()),
+ url(r'^shows/(?P<slug>[\w-]+)/?$', views.ShowDetailView.as_view(), name='show-detail'),
+ url(r'^(?P<pk>\d+)/?$', views.TimeSlotDetailView.as_view(), name='timeslot-detail'),
+ url(r'^styles.css$', views.StylesView.as_view())
+ )
if settings.DEBUG:
- import os
-
- 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_SITE_MEDIA}))
diff --git a/program/utils.py b/program/utils.py
index 9a086da..587e83d 100644
--- a/program/utils.py
+++ b/program/utils.py
@@ -3,6 +3,7 @@ from django.conf import settings
import json
import urllib
from os.path import join
+from datetime import datetime, date, timedelta
def get_automation_id_choices():
@@ -26,3 +27,11 @@ def get_automation_id_choices():
shows = [(s['id'], s['title']) for s in shows_list]
return shows
+
+
+def tofirstdayinisoweek(year, week):
+ # http://stackoverflow.com/questions/5882405/get-date-from-iso-week-number-in-python
+ ret = datetime.strptime('%04d-%02d-1' % (year, week), '%Y-%W-%w')
+ if date(year, 1, 4).isoweekday() > 4:
+ ret -= timedelta(days=7)
+ return ret
diff --git a/program/views.py b/program/views.py
index bc7700e..29253c0 100644
--- a/program/views.py
+++ b/program/views.py
@@ -1,134 +1,193 @@
-from django.views.generic import list_detail, simple
-from django.shortcuts import get_object_or_404
+import json
+from datetime import date, datetime, time, timedelta
+
from django.db.models import Q
from django.http import HttpResponse
+from django.shortcuts import get_object_or_404
+from django.views.generic.base import TemplateView
+from django.views.generic.detail import DetailView
+from django.views.generic.list import ListView
-from models import BroadcastFormat, MusicFocus, Note, Show, ShowInformation, ShowTopic, TimeSlot
+from models import BroadcastFormat, MusicFocus, Note, Show, ShowInformation, ShowTopic, TimeSlot, Host
-from datetime import date, datetime, time, timedelta
+from program.utils import tofirstdayinisoweek
-import json
-def show_list(request):
- queryset = Show.objects.filter(programslots__until__gt=date.today()).exclude(id=1).distinct()
+class HostListView(ListView):
+ context_object_name = 'host_list'
+ queryset = Host.objects.filter(Q(is_active=True) | Q(is_always_visible=True)).distinct()
+ template_name = 'host_list.html'
- if 'broadcastformat' in request.GET:
- 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'])
+class HostDetailView(DetailView):
+ context_object_name = 'host'
+ queryset = Host.objects.filter(Q(is_active=True) | Q(is_always_visible=True)).distinct()
+ template_name = 'host_detail.html'
- queryset = queryset.filter(musicfocus=musicfocus)
- elif 'showinformation' in request.GET:
- showinformation = get_object_or_404(ShowInformation, slug=request.GET['showinformation'])
- queryset = queryset.filter(showinformation=showinformation)
- elif 'showtopic' in request.GET:
- showtopic = get_object_or_404(ShowTopic, slug=request.GET['showtopic'])
+class ShowListView(ListView):
+ context_object_name = 'show_list'
+ queryset = Show.objects.filter(is_active=True).exclude(id=1).distinct()
+ template_name = 'show_list.html'
- queryset = queryset.filter(showtopic=showtopic)
+ def get_queryset(self):
+ queryset = Show.objects.filter(programslots__until__gt=date.today()).exclude(id=1).distinct()
- return list_detail.object_list(request, queryset=queryset, template_object_name='show', template_name='show_list.html')
+ if 'broadcastformat' in self.request.GET:
+ broadcastformat = get_object_or_404(BroadcastFormat, slug=self.request.GET['broadcastformat'])
+ queryset = queryset.filter(broadcastformat=broadcastformat)
+ elif 'musicfocus' in self.request.GET:
+ musicfocus = get_object_or_404(MusicFocus, slug=self.request.GET['musicfocus'])
+ queryset = queryset.filter(musicfocus=musicfocus)
+ elif 'showinformation' in self.request.GET:
+ showinformation = get_object_or_404(ShowInformation, slug=self.request.GET['showinformation'])
+ queryset = queryset.filter(showinformation=showinformation)
+ elif 'showtopic' in self.request.GET:
+ showtopic = get_object_or_404(ShowTopic, slug=self.request.GET['showtopic'])
+ queryset = queryset.filter(showtopic=showtopic)
-def recommendations(request, template_name='recommendations.html'):
- now = datetime.now()
- end = now + timedelta(weeks=1)
+ return queryset
- 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')
+class ShowDetailView(DetailView):
+ queryset = Show.objects.filter(is_active=True).exclude(id=1).distinct()
+ template_name = 'show_detail.html'
- tomorrow = today+timedelta(days=1)
- recommendations = Note.objects.filter(status=1, timeslot__start__range=(today, tomorrow))
+class TimeSlotDetailView(DetailView):
+ queryset = TimeSlot.objects.all()
+ template_name = 'timeslot_detail.html'
- default_show = Show.objects.get(pk=1)
- extra_context = dict(day=today, recommendations=recommendations, default_show=default_show)
+class RecommendationsListView(ListView):
+ context_object_name = 'recommendation_list'
+ template_name = 'recommendation_list.html'
- timeslots = TimeSlot.objects.get_day_timeslots(today)
+ now = datetime.now()
+ end = now + timedelta(weeks=1)
- if 'broadcastformat' in request.GET:
- broadcastformat = get_object_or_404(BroadcastFormat, slug=request.GET['broadcastformat'])
+ 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]
- extra_context['timeslots'] = timeslots.filter(show__broadcastformat=broadcastformat)
- elif 'musicfocus' in request.GET:
- 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'])
+class RecommendationsBoxView(RecommendationsListView):
+ template_name = 'boxes/recommendation.html'
- extra_context['timeslots'] = timeslots.filter(show__showinformation=showinformation)
- elif 'showtopic' in request.GET:
- showtopic = get_object_or_404(ShowTopic, slug=request.GET['showtopic'])
- extra_context['showtopic'] = timeslots.filter(show__showtopic=showtopic)
- else:
- extra_context['timeslots'] = timeslots
-
- 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()
- previous = current.get_previous_by_start()
- next = current.get_next_by_start()
- after_next = next.get_next_by_start()
-
- extra_context = dict(current=current,
- previous=previous,
- next=next,
- after_next=after_next)
-
- 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)
-
- 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['monday_timeslots'] = TimeSlot.objects.get_day_timeslots(monday)
- extra_context['tuesday_timeslots'] = TimeSlot.objects.get_day_timeslots(tuesday)
- extra_context['wednesday_timeslots'] = TimeSlot.objects.get_day_timeslots(wednesday)
- extra_context['thursday_timeslots'] = TimeSlot.objects.get_day_timeslots(thursday)
- extra_context['friday_timeslots'] = TimeSlot.objects.get_day_timeslots(friday)
- 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['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')
-
- return simple.direct_to_template(request, template='week_schedule.html', extra_context=extra_context)
-
-def styles(request):
- extra_context = dict()
- extra_context['broadcastformats'] = BroadcastFormat.objects.filter(enabled=True)
- 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)
+class DayScheduleView(TemplateView):
+ template_name = 'day_schedule.html'
+
+ def get_context_data(self, **kwargs):
+ year = self.kwargs.get('year', None)
+ month = self.kwargs.get('month', None)
+ day = self.kwargs.get('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')
+
+ tomorrow = today + timedelta(days=1)
+
+ context = super(DayScheduleView, self).get_context_data(**kwargs)
+ context['day'] = today
+ context['recommendations'] = Note.objects.filter(status=1, timeslot__start__range=(today, tomorrow))
+ context['default_show'] = Show.objects.get(pk=1)
+
+ timeslots = TimeSlot.objects.get_day_timeslots(today)
+
+ if 'broadcastformat' in self.request.GET:
+ broadcastformat = get_object_or_404(BroadcastFormat, slug=self.request.GET['broadcastformat'])
+ context['timeslots'] = timeslots.filter(show__broadcastformat=broadcastformat)
+ elif 'musicfocus' in self.request.GET:
+ musicfocus = get_object_or_404(MusicFocus, slug=self.request.GET['musicfocus'])
+ context['timeslots'] = timeslots.filter(show__musicfocus=musicfocus)
+ elif 'showinformation' in self.request.GET:
+ showinformation = get_object_or_404(ShowInformation, slug=self.request.GET['showinformation'])
+ context['timeslots'] = timeslots.filter(show__showinformation=showinformation)
+ elif 'showtopic' in self.request.GET:
+ showtopic = get_object_or_404(ShowTopic, slug=self.request.GET['showtopic'])
+ context['showtopic'] = timeslots.filter(show__showtopic=showtopic)
+ else:
+ context['timeslots'] = timeslots
+ return context
+
+
+class CurrentShowBoxView(TemplateView):
+ context_object_name = 'recommendation_list'
+ template_name = 'boxes/current.html'
+
+ def get_context_data(self, **kwargs):
+ current_timeslot = TimeSlot.objects.get_or_create_current()
+ previous_timeslot = current_timeslot.get_previous_by_start()
+ next_timeslot = current_timeslot.get_next_by_start()
+ after_next_timeslot = next_timeslot.get_next_by_start()
+
+ context = super(CurrentShowBoxView, self).get_context_data(**kwargs)
+ context['current_timeslot'] = current_timeslot
+ context['previous_timeslot'] = previous_timeslot
+ context['next_timeslot'] = next_timeslot
+ context['after_next_timeslot'] = after_next_timeslot
+ return context
+
+
+class WeekScheduleView(TemplateView):
+ template_name = 'week_schedule.html'
+
+ def get_context_data(self, **kwargs):
+ year = self.kwargs.get('year', None)
+ week = self.kwargs.get('week', None)
+
+ if year is None and week is None:
+ year, week = datetime.now().strftime('%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)
+
+ context = super(WeekScheduleView, self).get_context_data()
+ context['monday'] = monday
+ context['tuesday'] = tuesday
+ context['wednesday'] = wednesday
+ context['thursday'] = thursday
+ context['friday'] = friday
+ context['saturday'] = saturday
+ context['sunday'] = sunday
+ context['default_show'] = Show.objects.get(pk=1)
+ context['monday_timeslots'] = TimeSlot.objects.get_day_timeslots(monday)
+ context['tuesday_timeslots'] = TimeSlot.objects.get_day_timeslots(tuesday)
+ context['wednesday_timeslots'] = TimeSlot.objects.get_day_timeslots(wednesday)
+ context['thursday_timeslots'] = TimeSlot.objects.get_day_timeslots(thursday)
+ context['friday_timeslots'] = TimeSlot.objects.get_day_timeslots(friday)
+ context['saturday_timeslots'] = TimeSlot.objects.get_day_timeslots(saturday)
+ context['sunday_timeslots'] = TimeSlot.objects.get_day_timeslots(sunday)
+ context['last_w'] = datetime.strftime(monday - timedelta(days=7), '%G/%V')
+ context['cur_w'] = datetime.strftime(monday, '%G/%V')
+ context['next_w1'] = datetime.strftime(monday + timedelta(days=7), '%G/%V')
+ context['next_w2'] = datetime.strftime(monday + timedelta(days=14), '%G/%V')
+ context['next_w3'] = datetime.strftime(monday + timedelta(days=21), '%G/%V')
+ context['next_w4'] = datetime.strftime(monday + timedelta(days=28), '%G/%V')
+ return context
+
+
+class StylesView(TemplateView):
+ template_name = 'styles.css'
+ content_type = 'text/css'
+
+ def get_context_data(self, **kwargs):
+ context = super(StylesView, self).get_context_data(**kwargs)
+ context['broadcastformats'] = BroadcastFormat.objects.filter(enabled=True)
+ context['musicfocus'] = MusicFocus.objects.all()
+ context['showinformation'] = ShowInformation.objects.all()
+ context['showtopic'] = ShowTopic.objects.all()
+ return context
+
def json_day_schedule(request, year=None, month=None, day=None):
if year is None and month is None and day is None:
@@ -139,18 +198,12 @@ def json_day_schedule(request, year=None, month=None, day=None):
timeslots = TimeSlot.objects.get_24h_timeslots(today)
schedule = []
for ts in timeslots:
+ entry = { 'start': ts.start.strftime('%H:%M:%S'), 'title': ts.programslot.show.name, 'id': -1 }
if ts.programslot.automation_id:
- schedule.append((ts.start.strftime('%H:%M:%S'), ts.programslot.show.name, ts.programslot.automation_id))
+ entry['id'] = 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))
- else:
- schedule.append((ts.start.strftime('%H:%M:%S'), ts.programslot.show.name, -1))
+ entry['id'] = ts.programslot.show.automation_id
- return HttpResponse(json.dumps(schedule, ensure_ascii=False, encoding='utf8').encode('utf8'), content_type="application/json; charset=utf-8")
+ schedule.append(entry)
-def tofirstdayinisoweek(year, week):
- # http://stackoverflow.com/questions/5882405/get-date-from-iso-week-number-in-python
- ret = datetime.strptime('%04d-%02d-1' % (year, week), '%Y-%W-%w')
- if date(year, 1, 4).isoweekday() > 4:
- ret -= timedelta(days=7)
- return ret
+ return HttpResponse(json.dumps(schedule, ensure_ascii=False, encoding='utf8').encode('utf8'), content_type="application/json; charset=utf-8")
diff --git a/pv/settings.py b/pv/settings.py
index cf1da74..e967b39 100644
--- a/pv/settings.py
+++ b/pv/settings.py
@@ -1,12 +1,12 @@
# Django settings for pv project.
import os.path
+
PROJECT_DIR = os.path.dirname(__file__)
DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-ADMINS = ( )
+ADMINS = ()
MANAGERS = ADMINS
@@ -21,6 +21,8 @@ DATABASES = {
}
}
+DATABASE_ROUTERS = ['nop.dbrouter.NopRouter']
+
TIME_ZONE = 'Europe/Vienna'
LANGUAGE_CODE = 'de'
@@ -30,20 +32,38 @@ SITE_ID = 1
USE_I18N = True
USE_L10N = True
-LOCALE_PATHS = os.path.join(PROJECT_DIR, 'locale')
+LOCALE_PATHS = (
+ os.path.join(PROJECT_DIR, 'locale'),
+)
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'site_media')
MEDIA_URL = '/site_media/'
+STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
STATIC_URL = '/static/'
SECRET_KEY = ''
-TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.Loader',
- 'django.template.loaders.app_directories.Loader',
-# 'django.template.loaders.eggs.Loader',
-)
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [
+ os.path.join(PROJECT_DIR, 'templates')
+ ],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.contrib.auth.context_processors.auth',
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.i18n',
+ 'django.template.context_processors.media',
+ 'django.template.context_processors.static',
+ 'django.template.context_processors.tz',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
@@ -55,10 +75,6 @@ MIDDLEWARE_CLASSES = (
ROOT_URLCONF = 'pv.urls'
-TEMPLATE_DIRS = (
- os.path.join(PROJECT_DIR, "templates"),
-)
-
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -74,7 +90,7 @@ INSTALLED_APPS = (
TINYMCE_JS_URL = '/static/js/tiny_mce/tiny_mce.js'
TINYMCE_DEFAULT_CONFIG = {
- 'plugins' : 'contextmenu',
+ 'plugins': 'contextmenu',
'theme': 'advanced',
'theme_advanced_toolbar_location': 'top',
}
diff --git a/pv/urls.py b/pv/urls.py
index e55dddc..ec1cdff 100644
--- a/pv/urls.py
+++ b/pv/urls.py
@@ -1,19 +1,20 @@
from django.conf import settings
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
from django.contrib import admin
admin.autodiscover()
from program.views import json_day_schedule
+
urlpatterns = patterns('',
- (r'^admin/', include(admin.site.urls)),
- (r'^program/', include('program.urls')),
- (r'^nop', include('nop.urls')),
- (r'^tinymce/', include('tinymce.urls')),
- url(r'^export/day_schedule/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$', json_day_schedule),
+ url(r'^admin/', include(admin.site.urls)),
+ url(r'^program/', include('program.urls')),
+ url(r'^nop', include('nop.urls')),
+ url(r'^tinymce/', include('tinymce.urls')),
+ url(r'^export/day_schedule/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$', json_day_schedule)
)
if settings.DEBUG:
urlpatterns += patterns('',
- (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT})
- )
+ (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT})
+)
diff --git a/pv/wsgi.py b/pv/wsgi.py
index 2ba7fe3..f704d30 100644
--- a/pv/wsgi.py
+++ b/pv/wsgi.py
@@ -13,9 +13,10 @@ middleware here, or combine a Django application with an application of another
framework.
"""
-import os, sys
+import os
+import sys
-sys.path.append('/var/www/pv')
+sys.path.append('/srv/pv/pv')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pv.settings")
diff --git a/requirements.txt b/requirements.txt
index 83303bc..22470f4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
-Django==1.4.15
+Django==1.8.8
MySQL-python==1.2.5
-Pillow==2.5.3
+Pillow==3.0.0
PyYAML==3.11
-django-tinymce==1.5.2
-python-dateutil==1.5
+django-tinymce==2.0.6
+python-dateutil==2.4.2