diff options
author | Christian Pointner <equinox@helsinki.at> | 2016-04-15 18:41:03 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2016-04-15 18:41:03 (GMT) |
commit | 17f110df8c14ea258d9227d08471a4a82bfa4657 (patch) | |
tree | f2aaf3e4bbf132fa3d0fbbbafca88a420f8225a7 | |
parent | 1d521e1c65babb8412b4959bd476596e0aa36aa6 (diff) | |
parent | 179a462bf561dc0cb4d19133e7e3684055278296 (diff) |
merged master into stable after new deployment
50 files changed, 1484 insertions, 849 deletions
@@ -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 Binary files differindex 6f1e394..9adeb17 100644 --- a/locale/DE/LC_MESSAGES/django.mo +++ b/locale/DE/LC_MESSAGES/django.mo 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 }}"> </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 }}">▶</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 }}"> </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 }}"> </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 }}"> </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 }}">▶</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 }}"> </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 }}"> </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"> </td> + <td class="format bf-{{ recommendation.show.broadcastformat.slug }}" + title="{{ recommendation.show.broadcastformat.format }}"> </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"> </td> - <td class="format bf-{{ item.show.broadcastformat.slug }}" - title="{{ item.show.broadcastformat.format }}"> </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" }} — 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" }} — 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 — 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 — 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 }}"><--</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 }}">--></a></td> - </tr> - </table> + <table class="week-navigation"> + <tr> + <td><a href="/program/{{ last_w }}"><--</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 }}">--></a></td> + </tr> + </table> <div class="weekday-starts weekday-starts-left"> <div style="height: 43px;"> </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', } @@ -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}) +) @@ -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 |