From cbb689caa7a79311385fe7856f3a0255689fef33 Mon Sep 17 00:00:00 2001
From: ingo <ingo.leindecker@fro.at>
Date: Wed, 8 Nov 2017 20:06:00 +0100
Subject: [PATCH] Renamed classes/varnames and added fields according to our
 new datamodel. See #21

---
 program/admin.py                              | 137 +++++-----
 program/fixtures/broadcastformats.yaml        |  35 ---
 program/fixtures/categories.yaml              |  48 ++++
 program/fixtures/rtrcategories.yaml           |   6 +
 program/fixtures/showinformation.yaml         |  48 ----
 program/fixtures/shows.yaml                   |   5 +-
 .../fixtures/{showtopics.yaml => topics.yaml} |  10 +-
 program/fixtures/types.yaml                   |  35 +++
 program/forms.py                              |  10 +-
 .../commands/check_automation_ids.py          |   8 +-
 .../commands/cleanup_defaultshow.py           |  10 +-
 program/management/commands/export_showlog.py |   7 +-
 program/management/commands/importnotes.py    |   4 +-
 .../management/commands/importprogramslots.py |  14 +-
 .../commands/remove_automation_id.py          |   4 +-
 program/migrations/0012_auto_20171012_0056.py |  94 -------
 program/migrations/0012_auto_20171108_1846.py | 256 ++++++++++++++++++
 program/migrations/0013_auto_20171012_0108.py |  19 --
 program/migrations/0014_auto_20171012_1456.py |  19 --
 program/migrations/0015_auto_20171013_1638.py |  19 --
 program/migrations/0016_auto_20171017_2016.py |  20 --
 program/models.py                             | 161 ++++++-----
 program/templates/boxes/category.html         |  16 ++
 program/templates/boxes/current.html          |  18 +-
 program/templates/boxes/recommendation.html   |   8 +-
 program/templates/boxes/topic.html            |  16 ++
 program/templates/boxes/type.html             |  11 +
 program/templates/collisions.html             |  28 +-
 program/templates/day_schedule.html           |  48 ++--
 program/templates/host_detail.html            |   4 +-
 program/templates/recommendation_list.html    |  18 +-
 program/templates/show_detail.html            |  22 +-
 program/templates/show_list.html              |  30 +-
 program/templates/styles.css                  |  24 +-
 program/templates/timeslot_detail.html        |  14 +-
 program/templates/week_schedule_timeslot.html |  20 +-
 program/templatetags/content_boxes.py         |  20 +-
 program/views.py                              |  83 +++---
 38 files changed, 757 insertions(+), 592 deletions(-)
 delete mode 100644 program/fixtures/broadcastformats.yaml
 create mode 100644 program/fixtures/categories.yaml
 create mode 100644 program/fixtures/rtrcategories.yaml
 delete mode 100644 program/fixtures/showinformation.yaml
 rename program/fixtures/{showtopics.yaml => topics.yaml} (76%)
 create mode 100644 program/fixtures/types.yaml
 delete mode 100644 program/migrations/0012_auto_20171012_0056.py
 create mode 100644 program/migrations/0012_auto_20171108_1846.py
 delete mode 100644 program/migrations/0013_auto_20171012_0108.py
 delete mode 100644 program/migrations/0014_auto_20171012_1456.py
 delete mode 100644 program/migrations/0015_auto_20171013_1638.py
 delete mode 100644 program/migrations/0016_auto_20171017_2016.py
 create mode 100644 program/templates/boxes/category.html
 create mode 100644 program/templates/boxes/topic.html
 create mode 100644 program/templates/boxes/type.html

diff --git a/program/admin.py b/program/admin.py
index d1dfee24..2ea86784 100644
--- a/program/admin.py
+++ b/program/admin.py
@@ -3,11 +3,12 @@ from django.contrib import admin
 from django.utils.translation import ugettext_lazy as _
 from django.shortcuts import render
 
-from .models import BroadcastFormat, MusicFocus, ShowInformation, ShowTopic, Host, Note, RRule, ProgramSlot, Show, TimeSlot
+from .models import Type, MusicFocus, Category, Topic, RTRCategory, Host, Note, RRule, Schedule, Show, TimeSlot
 from .forms import MusicFocusForm, CollisionForm
 
 from datetime import date, datetime, time, timedelta
 
+
 class ActivityFilter(admin.SimpleListFilter):
     title = _("Activity")
 
@@ -18,40 +19,40 @@ class ActivityFilter(admin.SimpleListFilter):
         )
 
     def queryset(self, request, queryset):
-        if self.parameter_name == 'has_timeslots':  # active/inactive ProgramSlots
+        if self.parameter_name == 'has_timeslots':  # active/inactive Schedules
             if self.value() == 'yes':
                 return queryset.filter(until__gt=datetime.now()).distinct()
             if self.value() == 'no':
                 return queryset.filter(until__lt=datetime.now()).distinct()
 
-        if self.parameter_name == 'has_programslots_timeslots':  # active/inactive Shows
+        if self.parameter_name == 'has_schedules_timeslots':  # active/inactive Shows
             if self.value() == 'yes':
-                return queryset.filter(programslots__until__gt=datetime.now()).distinct()
+                return queryset.filter(schedules__until__gt=datetime.now()).distinct()
             if self.value() == 'no':
-                return queryset.filter(programslots__until__lt=datetime.now()).distinct()
+                return queryset.filter(schedules__until__lt=datetime.now()).distinct()
 
-        if self.parameter_name == 'has_shows_programslots_timeslots':  # active/inactive Hosts
+        if self.parameter_name == 'has_shows_schedules_timeslots':  # active/inactive Hosts
             if self.value() == 'yes':
-                return queryset.filter(shows__programslots__until__gt=datetime.now()).distinct()
+                return queryset.filter(shows__schedules__until__gt=datetime.now()).distinct()
             if self.value() == 'no':
-                return queryset.filter(shows__programslots__until__lt=datetime.now()).distinct()
+                return queryset.filter(shows__schedules__until__lt=datetime.now()).distinct()
 
 
-class ActiveProgramSlotsFilter(ActivityFilter):
+class ActiveSchedulesFilter(ActivityFilter):
     parameter_name = 'has_timeslots'
 
 
 class ActiveShowsFilter(ActivityFilter):
-    parameter_name = 'has_programslots_timeslots'
+    parameter_name = 'has_schedules_timeslots'
 
 
 class ActiveHostsFilter(ActivityFilter):
-    parameter_name = 'has_shows_programslots_timeslots'
+    parameter_name = 'has_shows_schedules_timeslots'
 
 
-class BroadcastFormatAdmin(admin.ModelAdmin):
-    list_display = ('format', 'admin_color', 'enabled')
-    prepopulated_fields = {'slug': ('format',)}
+class TypeAdmin(admin.ModelAdmin):
+    list_display = ('type', 'admin_color', 'enabled')
+    prepopulated_fields = {'slug': ('type',)}
 
 
 class MusicFocusAdmin(admin.ModelAdmin):
@@ -60,15 +61,18 @@ class MusicFocusAdmin(admin.ModelAdmin):
     prepopulated_fields = {'slug': ('focus',)}
 
 
-class ShowInformationAdmin(admin.ModelAdmin):
-    list_display = ('information', 'abbrev', 'admin_buttons')
-    prepopulated_fields = {'slug': ('information',)}
+class CategoryAdmin(admin.ModelAdmin):
+    list_display = ('category', 'abbrev', 'admin_buttons')
+    prepopulated_fields = {'slug': ('category',)}
 
 
-class ShowTopicAdmin(admin.ModelAdmin):
+class TopicAdmin(admin.ModelAdmin):
     list_display = ('topic', 'abbrev', 'admin_buttons')
     prepopulated_fields = {'slug': ('topic',)}
 
+class RTRCategoryAdmin(admin.ModelAdmin):
+    list_display = ('rtrcategory', 'abbrev', )
+    prepopulated_fields = {'slug': ('rtrcategory',)}
 
 class HostAdmin(admin.ModelAdmin):
     list_display = ('name',)
@@ -78,6 +82,7 @@ class HostAdmin(admin.ModelAdmin):
 class NoteAdmin(admin.ModelAdmin):
     date_hierarchy = 'start'
     list_display = ('title', 'show', 'start', 'status')
+    prepopulated_fields = {'slug': ('title',)}
     list_filter = ('status',)
     ordering = ('timeslot',)
     save_as = True
@@ -104,18 +109,17 @@ class NoteAdmin(admin.ModelAdmin):
     def save_model(self, request, obj, form, change):
         obj.save()
 
-
 class TimeSlotInline(admin.TabularInline):
     model = TimeSlot
     ordering = ('-end',)
 
 
-class ProgramSlotAdmin(admin.ModelAdmin):
+class ScheduleAdmin(admin.ModelAdmin):
     actions = ('renew',)
     inlines = (TimeSlotInline,)
     fields = (('rrule', 'byweekday'), ('dstart', 'tstart', 'tend'), 'until', 'is_repetition', 'automation_id')
     list_display = ('get_show_name', 'byweekday', 'rrule', 'tstart', 'tend', 'until')
-    list_filter = (ActiveProgramSlotsFilter, 'byweekday', 'rrule', 'is_repetition')
+    list_filter = (ActiveSchedulesFilter, 'byweekday', 'rrule', 'is_repetition')
     ordering = ('byweekday', 'dstart')
     save_on_top = True
     search_fields = ('show__name',)
@@ -125,11 +129,11 @@ class ProgramSlotAdmin(admin.ModelAdmin):
         until = date(next_year, 12, 31)
         renewed = queryset.update(until=until)
         if renewed == 1:
-            message = _("1 program slot was renewed until %s") % until
+            message = _("1 schedule was renewed until %s") % until
         else:
-            message = _("%s program slots were renewed until %s") % (renewed, until)
+            message = _("%s schedule were renewed until %s") % (renewed, until)
         self.message_user(request, message)
-    renew.short_description = _("Renew selected program slots")
+    renew.short_description = _("Renew selected schedules")
 
     def get_show_name(self, obj):
         return obj.show.name
@@ -137,22 +141,22 @@ class ProgramSlotAdmin(admin.ModelAdmin):
     get_show_name.short_description = "Show"
 
 
-class ProgramSlotInline(admin.TabularInline):
-    model = ProgramSlot
+class ScheduleInline(admin.TabularInline):
+    model = Schedule
     ordering = ('pk', '-until', 'byweekday')
 
 
 class ShowAdmin(admin.ModelAdmin):
-    filter_horizontal = ('hosts', 'owners', 'musicfocus', 'showinformation', 'showtopic')
-    inlines = (ProgramSlotInline,)
+    filter_horizontal = ('hosts', 'owners', 'musicfocus', 'category', 'topic')
+    inlines = (ScheduleInline,)
     list_display = ('name', 'short_description')
-    list_filter = (ActiveShowsFilter, 'broadcastformat', 'showinformation', 'showtopic', 'musicfocus')
+    list_filter = (ActiveShowsFilter, 'type', 'category', 'topic', 'musicfocus', 'rtrcategory')
     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', 'hosts', 'owners', 'showinformation', 'showtopic',
+        'predecessor', 'type', 'name', 'slug', 'image', 'short_description', 'description',
+        'email', 'website', 'hosts', 'owners', 'category', 'rtrcategory', 'topic',
         'musicfocus',
     )
 
@@ -184,12 +188,12 @@ class ShowAdmin(admin.ModelAdmin):
 
         Saves the show after first submit
 
-        If any changes in programslots happend
-          * added/changed programslots are used to generate new timeslots and
+        If any changes in schedules happened
+          * added/changed schedules are used to generate new timeslots and
             matched against existing ones, which will be displayed in the collision form
 
         If a collision form was submitted
-          * save the current programslot
+          * save the current schedule
           * delete/create timeslots and relink notes after confirmation
 
         Each step passes on to response_add or response_change which will
@@ -200,18 +204,18 @@ class ShowAdmin(admin.ModelAdmin):
 
         self.end_reached = False
 
-        programslot_instances = formset.save(commit=False)
+        schedule_instances = formset.save(commit=False)
 
-        # If there are no programslots to save, do nothing
-        if programslot_instances:
-            show_id = programslot_instances[0].show.id
+        # If there are no schedules to save, do nothing
+        if schedule_instances:
+            show_id = schedule_instances[0].show.id
         else:
             self.end_reached = True
 
-        programslot = []
+        schedule = []
         timeslots = []
 
-        max_steps = int(len(programslot_instances)) if len(programslot_instances) > 0 else 1
+        max_steps = int(len(schedule_instances)) if len(schedule_instances) > 0 else 1
         step = 1
 
         if request.POST.get('step') == None:
@@ -220,7 +224,7 @@ class ShowAdmin(admin.ModelAdmin):
             # Save show data only
             form.save();
 
-            # Delete programslots (as well as related timeslots and notes) if flagged as such
+            # Delete schedules (as well as related timeslots and notes) if flagged as such
             for obj in formset.deleted_objects:
                 obj.delete()
 
@@ -263,8 +267,8 @@ class ShowAdmin(admin.ModelAdmin):
                 num_ntids = int(request.POST.get('num_ntids'))
                 num_ntind = int(request.POST.get('num_ntind'))
 
-                # Retrieve POST vars of current programslot
-                programslot_id = int(request.POST.get('ps_save_id')) if request.POST.get('ps_save_id') != 'None' else None
+                # Retrieve POST vars of current schedule
+                schedule_id = int(request.POST.get('ps_save_id')) if request.POST.get('ps_save_id') != 'None' else None
                 rrule = RRule.objects.get(pk=int(request.POST.get('ps_save_rrule_id')))
                 show = Show.objects.get(pk=show_id)
                 byweekday = int(request.POST.get('ps_save_byweekday'))
@@ -303,14 +307,14 @@ class ShowAdmin(admin.ModelAdmin):
                             delete_timeslots.add(int(collisions[x]))
 
                 # Collect IDs of upcoming timeslots of the same schedule to delete except those in keep_collision
-                if programslot_id != None:
-                    for ts in TimeSlot.objects.filter(start__gte=dstart,end__lte=until,programslot_id=programslot_id).exclude(pk__in=keep_collisions).values_list('id', flat=True):
+                if schedule_id != None:
+                    for ts in TimeSlot.objects.filter(start__gte=dstart,end__lte=until,schedule_id=schedule_id).exclude(pk__in=keep_collisions).values_list('id', flat=True):
                         delete_timeslots.add(ts)
 
 
-                '''Save programslot'''
+                '''Save schedule'''
 
-                new_programslot = ProgramSlot(pk=programslot_id,
+                new_schedule = Schedule(pk=schedule_id,
                                               rrule=rrule,
                                               byweekday=byweekday,
                                               show=show,
@@ -321,9 +325,9 @@ class ShowAdmin(admin.ModelAdmin):
                                               is_repetition=is_repetition,
                                               automation_id=automation_id)
 
-                # Only save programslot if any timeslots changed
+                # Only save schedule if any timeslots changed
                 if len(resolved_timeslots) > 0:
-                    new_programslot.save()
+                    new_schedule.save()
 
 
                 '''Relink notes to existing timeslots and prepare those to be linked'''
@@ -353,7 +357,7 @@ class ShowAdmin(admin.ModelAdmin):
                         start_end = ts.split(' - ')
                         # Only create upcoming timeslots
                         if datetime.strptime(start_end[0], "%Y-%m-%d %H:%M:%S") > datetime.today():
-                            timeslot_created = TimeSlot.objects.create(programslot=new_programslot, start=start_end[0], end=start_end[1])
+                            timeslot_created = TimeSlot.objects.create(schedule=new_schedule, start=start_end[0], end=start_end[1])
 
                             # Link a note to the new timeslot
                             if idx in note_indices:
@@ -381,18 +385,18 @@ class ShowAdmin(admin.ModelAdmin):
         Everything below here is called when a new collision is loaded before being handed over to the client
         '''
 
-        # Generate timeslots from current programslot
+        # Generate timeslots from current schedule
         k = 1
-        for instance in programslot_instances:
-            if isinstance(instance, ProgramSlot):
+        for instance in schedule_instances:
+            if isinstance(instance, Schedule):
                 if k == step:
-                    timeslots = ProgramSlot.generate_timeslots(instance)
-                    programslot = instance
+                    timeslots = Schedule.generate_timeslots(instance)
+                    schedule = instance
                     break
                 k += 1
 
         # Get collisions for timeslots
-        collisions = ProgramSlot.get_collisions(timeslots)
+        collisions = Schedule.get_collisions(timeslots)
 
         # Get notes of colliding timeslots
         notes = []
@@ -402,13 +406,13 @@ class ShowAdmin(admin.ModelAdmin):
             except ObjectDoesNotExist:
                 pass
 
-        self.programslot = programslot
+        self.schedule = schedule
         self.timeslots = timeslots
         self.collisions = collisions
         self.num_collisions = len([ s for s in self.collisions if s != 'None']) # Number of real collisions displayed to the user
         self.notes = notes
         self.showform = form
-        self.programslotsform = formset
+        self.schedulesform = formset
         self.step = step + 1 # Becomes upcoming step
         self.max_steps = max_steps
 
@@ -426,8 +430,8 @@ class ShowAdmin(admin.ModelAdmin):
 
     def respond(self, request, obj):
         """
-        Redirects to the show-change-form if no programslots changed or resolving has been finished (or any other form validation error occured)
-        Displays the collision form for the current programslot otherwise
+        Redirects to the show-change-form if no schedules changed or resolving has been finished (or any other form validation error occured)
+        Displays the collision form for the current schedule otherwise
         """
 
         if self.end_reached:
@@ -440,9 +444,9 @@ class ShowAdmin(admin.ModelAdmin):
         return render(request, 'collisions.html', {'self' : self, 'obj': obj, 'request': request,
                                                    'timeslots': self.timeslots,
                                                    'collisions': self.collisions,
-                                                   'programslot': self.programslot,
+                                                   'schedule': self.schedule,
                                                    'timeslots_to_collisions': timeslots_to_collisions,
-                                                   'programslotsform': self.programslotsform,
+                                                   'schedulesform': self.schedulesform,
                                                    'showform': self.showform,
                                                    'num_inputs': len(self.timeslots),
                                                    'step': self.step,
@@ -451,12 +455,13 @@ class ShowAdmin(admin.ModelAdmin):
                                                    'num_collisions': self.num_collisions})
 
 
-admin.site.register(BroadcastFormat, BroadcastFormatAdmin)
+admin.site.register(Type, TypeAdmin)
 admin.site.register(MusicFocus, MusicFocusAdmin)
-admin.site.register(ShowInformation, ShowInformationAdmin)
-admin.site.register(ShowTopic, ShowTopicAdmin)
+admin.site.register(Category, CategoryAdmin)
+admin.site.register(Topic, TopicAdmin)
+admin.site.register(RTRCategory, RTRCategoryAdmin)
 admin.site.register(Host, HostAdmin)
 admin.site.register(Note, NoteAdmin)
-#admin.site.register(ProgramSlot, ProgramSlotAdmin)
+#admin.site.register(Schedule, ScheduleAdmin)
 #admin.site.register(TimeSlot, TimeSlotAdmin)
 admin.site.register(Show, ShowAdmin)
\ No newline at end of file
diff --git a/program/fixtures/broadcastformats.yaml b/program/fixtures/broadcastformats.yaml
deleted file mode 100644
index 84fa335a..00000000
--- a/program/fixtures/broadcastformats.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-- model: program.broadcastformat
-  pk: 1
-  fields:
-    format: Talk
-    slug: talk
-- model: program.broadcastformat
-  pk: 2
-  fields:
-    format: Musiksendung
-    slug: musiksendung
-- model: program.broadcastformat
-  pk: 3
-  fields:
-    format: Unmoderiertes Musikprogramm
-    slug: unmoderiertes-musikprogramm
-- model: program.broadcastformat
-  pk: 4
-  fields:
-    format: Feature/Magazin
-    slug: feature-magazin
-- model: program.broadcastformat
-  pk: 5
-  fields:
-    format: Experimentell
-    slug: experimentell
-- model: program.broadcastformat
-  pk: 6
-  fields:
-    format: Hörspiel/Literatur
-    slug: horspiel-literatur
-- model: program.broadcastformat
-  pk: 7
-  fields:
-    format: Vortrag/Diskussion
-    slug: vortrag-diskussion
\ No newline at end of file
diff --git a/program/fixtures/categories.yaml b/program/fixtures/categories.yaml
new file mode 100644
index 00000000..12d5e59a
--- /dev/null
+++ b/program/fixtures/categories.yaml
@@ -0,0 +1,48 @@
+- model: program.category
+  pk: 1
+  fields:
+    category: Interkulturell
+    abbrev: I
+    slug: interkulturell
+- model: program.category
+  pk: 2
+  fields:
+    category: Lokalbezug
+    abbrev: L
+    slug: lokalbezug
+- model: program.category
+  pk: 3
+  fields:
+    category: Minderheiten
+    abbrev: Mi
+    slug: minderheiten
+- model: program.category
+  pk: 4
+  fields:
+    category: Wiederholung
+    abbrev: W
+    slug: wiederholung
+- model: program.category
+  pk: 5
+  fields:
+    category: Mehr-/Fremdsprachig
+    abbrev: M
+    slug: mehr-fremdsprachig
+- model: program.category
+  pk: 6
+  fields:
+    category: Frauenschwerpunkt
+    abbrev: F
+    slug: frauenschwerpunkt
+- model: program.category
+  pk: 7
+  fields:
+    category: Österreichische Musik
+    abbrev: Ö
+    slug: osterreichische-musik
+- model: program.category
+  pk: 8
+  fields:
+    category: Sendungsübernahme
+    abbrev: U
+    slug: sendungsubernahme
\ No newline at end of file
diff --git a/program/fixtures/rtrcategories.yaml b/program/fixtures/rtrcategories.yaml
new file mode 100644
index 00000000..accf133f
--- /dev/null
+++ b/program/fixtures/rtrcategories.yaml
@@ -0,0 +1,6 @@
+- model: program.rtrcategory
+  pk: 1
+  fields:
+    rtrcategory: Standard
+    abbrev: S
+    slug: standard
\ No newline at end of file
diff --git a/program/fixtures/showinformation.yaml b/program/fixtures/showinformation.yaml
deleted file mode 100644
index cbde5291..00000000
--- a/program/fixtures/showinformation.yaml
+++ /dev/null
@@ -1,48 +0,0 @@
-- model: program.showinformation
-  pk: 1
-  fields:
-    information: Interkulturell
-    abbrev: I
-    slug: interkulturell
-- model: program.showinformation
-  pk: 2
-  fields:
-    information: Lokalbezug
-    abbrev: L
-    slug: lokalbezug
-- model: program.showinformation
-  pk: 3
-  fields:
-    information: Minderheiten
-    abbrev: Mi
-    slug: minderheiten
-- model: program.showinformation
-  pk: 4
-  fields:
-    information: Wiederholung
-    abbrev: W
-    slug: wiederholung
-- model: program.showinformation
-  pk: 5
-  fields:
-    information: Mehr-/Fremdsprachig
-    abbrev: M
-    slug: mehr-fremdsprachig
-- model: program.showinformation
-  pk: 6
-  fields:
-    information: Frauenschwerpunkt
-    abbrev: F
-    slug: frauenschwerpunkt
-- model: program.showinformation
-  pk: 7
-  fields:
-    information: Österreichische Musik
-    abbrev: Ö
-    slug: osterreichische-musik
-- model: program.showinformation
-  pk: 8
-  fields:
-    information: Sendungsübernahme
-    abbrev: U
-    slug: sendungsubernahme
\ No newline at end of file
diff --git a/program/fixtures/shows.yaml b/program/fixtures/shows.yaml
index 470fd806..8ff135df 100644
--- a/program/fixtures/shows.yaml
+++ b/program/fixtures/shows.yaml
@@ -2,11 +2,12 @@
   pk: 1
   fields:
     hosts: [1]
-    broadcastformat: 3
+    type: 3
+    rtrcategory: 1
     name: Musikprogramm
     slug: musikprogramm
     description: Unmoderiertes Musikprogramm
     short_description: Unmoderiertes Musikprogramm
     email: musikredaktion@helsinki.at
     created: 1970-01-01 00:00:00
-    last_updated: 1970-01-01 00:00:00
+    last_updated: 1970-01-01 00:00:00
\ No newline at end of file
diff --git a/program/fixtures/showtopics.yaml b/program/fixtures/topics.yaml
similarity index 76%
rename from program/fixtures/showtopics.yaml
rename to program/fixtures/topics.yaml
index 8f125087..7f98dc93 100644
--- a/program/fixtures/showtopics.yaml
+++ b/program/fixtures/topics.yaml
@@ -1,28 +1,28 @@
-- model: program.showtopic
+- model: program.topic
   pk: 1
   fields:
     topic: Politik/Gesellschaft
     abbrev: P
     slug: politik-gesellschaft
-- model: program.showtopic
+- model: program.topic
   pk: 2
   fields:
     topic: Natur/Klima/Tiere
     abbrev: N
     slug: natur-klima-tiere
-- model: program.showtopic
+- model: program.topic
   pk: 3
   fields:
     topic: Kultur/Kunst
     abbrev: K
     slug: kultur-kunst
-- model: program.showtopic
+- model: program.topic
   pk: 4
   fields:
     topic: Soziales
     abbrev: S
     slug: soziales
-- model: program.showtopic
+- model: program.topic
   pk: 5
   fields:
     topic: Wissenschaft/Philosophie
diff --git a/program/fixtures/types.yaml b/program/fixtures/types.yaml
new file mode 100644
index 00000000..7a9fb4b9
--- /dev/null
+++ b/program/fixtures/types.yaml
@@ -0,0 +1,35 @@
+- model: program.type
+  pk: 1
+  fields:
+    type: Talk
+    slug: talk
+- model: program.type
+  pk: 2
+  fields:
+    type: Musiksendung
+    slug: musiksendung
+- model: program.type
+  pk: 3
+  fields:
+    type: Unmoderiertes Musikprogramm
+    slug: unmoderiertes-musikprogramm
+- model: program.type
+  pk: 4
+  fields:
+    type: Feature/Magazin
+    slug: feature-magazin
+- model: program.type
+  pk: 5
+  fields:
+    type: Experimentell
+    slug: experimentell
+- model: program.type
+  pk: 6
+  fields:
+    type: Hörspiel/Literatur
+    slug: horspiel-literatur
+- model: program.type
+  pk: 7
+  fields:
+    type: Vortrag/Diskussion
+    slug: vortrag-diskussion
\ No newline at end of file
diff --git a/program/forms.py b/program/forms.py
index e134f3b2..28f04f1c 100644
--- a/program/forms.py
+++ b/program/forms.py
@@ -2,7 +2,7 @@ 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
+from program.models import MusicFocus, Category, Topic
 
 
 # Couldn't manage call/validation for collision usecase.
@@ -47,13 +47,13 @@ class MusicFocusForm(FormWithButton):
         fields = '__all__'
 
 
-class ShowInformationForm(FormWithButton):
+class CategoryForm(FormWithButton):
     class Meta:
-        model = ShowInformation
+        model = Category
         fields = '__all__'
 
 
-class ShowTopicForm(FormWithButton):
+class TopicForm(FormWithButton):
     class Meta:
-        model = ShowTopic
+        model = Topic
         fields = '__all__'
\ No newline at end of file
diff --git a/program/management/commands/check_automation_ids.py b/program/management/commands/check_automation_ids.py
index 95c35cbb..8bfe1643 100644
--- a/program/management/commands/check_automation_ids.py
+++ b/program/management/commands/check_automation_ids.py
@@ -4,7 +4,7 @@ from os.path import join
 from django.conf import settings
 from django.core.management.base import NoArgsCommand
 
-from program.models import ProgramSlot
+from program.models import Schedule
 
 
 class Command(NoArgsCommand):
@@ -23,8 +23,8 @@ class Command(NoArgsCommand):
                 rd_ids[show['id']] = show
 
             pv_ids = []
-            for programslot in ProgramSlot.objects.filter(automation_id__isnull=False):
-                pv_ids.append(int(programslot.automation_id))
+            for schedule in Schedule.objects.filter(automation_id__isnull=False):
+                pv_ids.append(int(schedule.automation_id))
 
             for automation_id in sorted(rd_ids.iterkeys()):
                 if rd_ids[automation_id]['type'] == 's':
@@ -41,4 +41,4 @@ class Command(NoArgsCommand):
 
             for automation_id in sorted(pv_ids):
                 if automation_id not in rd_ids:
-                    print '-', automation_id
+                    print '-', automation_id
\ No newline at end of file
diff --git a/program/management/commands/cleanup_defaultshow.py b/program/management/commands/cleanup_defaultshow.py
index 98d3f980..f27c4093 100644
--- a/program/management/commands/cleanup_defaultshow.py
+++ b/program/management/commands/cleanup_defaultshow.py
@@ -1,7 +1,7 @@
 from django.core.management.base import NoArgsCommand
 from django.db import transaction
 
-from program.models import Show, TimeSlot, ProgramSlot
+from program.models import Show, TimeSlot, Schedule
 
 
 class Command(NoArgsCommand):
@@ -13,10 +13,10 @@ class Command(NoArgsCommand):
         default_show = Show.objects.get(pk=1)
         try:
             TimeSlot.objects.filter(show=default_show, note__isnull=True).delete()
-            for programslot in ProgramSlot.objects.filter(show=default_show):
-                if programslot.timeslots.count() == 0:
-                    programslot.delete()
+            for schedule in Schedule.objects.filter(show=default_show):
+                if schedule.timeslots.count() == 0:
+                    schedule.delete()
         except:
             transaction.rollback()
         else:
-            transaction.commit()
+            transaction.commit()
\ No newline at end of file
diff --git a/program/management/commands/export_showlog.py b/program/management/commands/export_showlog.py
index da78cd23..0e26c011 100644
--- a/program/management/commands/export_showlog.py
+++ b/program/management/commands/export_showlog.py
@@ -29,7 +29,7 @@ class Command(BaseCommand):
         end = datetime.strptime('%d__01__01__00__00' % (year+1), '%Y__%m__%d__%H__%M')
 
         currentDate = None
-        for ts in TimeSlot.objects.filter(end__gt=start, start__lt=end).select_related('programslot').select_related('show'):
+        for ts in TimeSlot.objects.filter(end__gt=start, start__lt=end).select_related('schedule').select_related('show'):
             if currentDate == None or currentDate < ts.start.date():
                 if currentDate:
                     print "\n"
@@ -37,8 +37,7 @@ class Command(BaseCommand):
                 print currentDate.strftime("## %a %d.%m.%Y:\n")
 
             title = ts.show.name
-            if ts.programslot.is_repetition:
+            if ts.schedule.is_repetition:
                 title += " (WH)"
 
-            print " * **%s - %s**: %s" % (ts.start.strftime("%H:%M:%S"), ts.end.strftime("%H:%M:%S"), title)
-
+            print " * **%s - %s**: %s" % (ts.start.strftime("%H:%M:%S"), ts.end.strftime("%H:%M:%S"), title)
\ No newline at end of file
diff --git a/program/management/commands/importnotes.py b/program/management/commands/importnotes.py
index 0a1ab0fe..f835e37e 100644
--- a/program/management/commands/importnotes.py
+++ b/program/management/commands/importnotes.py
@@ -39,7 +39,7 @@ WHERE n.sendung_id in (SELECT id FROM sendungen WHERE letzter_termin > current_d
                     print 'show with name "%s" not found' % stitel
                 else:
                     try:
-                        timeslot = TimeSlot.objects.get(programslot__show=show, start__year=year, start__month=month,
+                        timeslot = TimeSlot.objects.get(schedule__show=show, start__year=year, start__month=month,
                                                         start__day=day)
                     except ObjectDoesNotExist:
                         print 'no timeslot found for sendung "%s" and datum "%s"' % (stitel, datum)
@@ -62,4 +62,4 @@ WHERE n.sendung_id in (SELECT id FROM sendungen WHERE letzter_termin > current_d
         cursor.close()
         connection.close()
 
-        print '%i notes imported' % counter
+        print '%i notes imported' % counter
\ No newline at end of file
diff --git a/program/management/commands/importprogramslots.py b/program/management/commands/importprogramslots.py
index b527f538..b6e54227 100644
--- a/program/management/commands/importprogramslots.py
+++ b/program/management/commands/importprogramslots.py
@@ -5,7 +5,7 @@ from django.utils.html import strip_tags
 from datetime import time
 import MySQLdb
 
-from program.models import Show, ProgramSlot, RRule
+from program.models import Show, Schedule, RRule
 
 USER = 'helsinki'
 PASSWD = 'helsinki'
@@ -20,7 +20,7 @@ RRULES = {
 
 
 class Command(NoArgsCommand):
-    help = 'Import programslots from the current program'
+    help = 'Import schedules from the current program'
 
     def handle_noargs(self, **options):
         connection = MySQLdb.connect(user=USER, passwd=PASSWD, db=DB)
@@ -50,10 +50,10 @@ WHERE letzter_termin > current_date AND titel NOT LIKE 'Musikprogramm' AND titel
                 except ObjectDoesNotExist:
                     print 'show with name "%s" not found' % titel
                 else:
-                    programslot = ProgramSlot(rrule=rrule, byweekday=termin, show=show, dstart=erster_termin,
+                    schedule = Schedule(rrule=rrule, byweekday=termin, show=show, dstart=erster_termin,
                                               tstart=tstart, tend=tend, until=letzter_termin)
                     try:
-                        programslot.save()
+                        schedule.save()
                         counter += 1
                     except:
                         pass
@@ -82,10 +82,10 @@ WHERE letzter_termin > current_date AND titel LIKE '%%(Wiederholung)'""")
                 except ObjectDoesNotExist:
                     print 'show with name "%s" not found' % titel
                 else:
-                    programslot = ProgramSlot(rrule=rrule, byweekday=termin, show=show, dstart=erster_termin,
+                    schedule = Schedule(rrule=rrule, byweekday=termin, show=show, dstart=erster_termin,
                                               tstart=tstart, tend=tend, until=letzter_termin, is_repetition=True)
                     try:
-                        programslot.save()
+                        schedule.save()
                         counter += 1
                     except:
                         pass
@@ -95,4 +95,4 @@ WHERE letzter_termin > current_date AND titel LIKE '%%(Wiederholung)'""")
         cursor.close()
         connection.close()
 
-        print '%i programslots imported' % counter
+        print '%i schedules imported' % counter
\ No newline at end of file
diff --git a/program/management/commands/remove_automation_id.py b/program/management/commands/remove_automation_id.py
index 4fb8ee7e..75da30c5 100644
--- a/program/management/commands/remove_automation_id.py
+++ b/program/management/commands/remove_automation_id.py
@@ -1,6 +1,6 @@
 from django.core.management.base import BaseCommand, CommandError
 
-from program.models import ProgramSlot
+from program.models import Schedule
 
 
 class Command(BaseCommand):
@@ -13,4 +13,4 @@ class Command(BaseCommand):
         else:
             raise CommandError('you must provide the automation_id')
 
-        ProgramSlot.objects.filter(automation_id=automation_id).update(automation_id=None)
+        Schedule.objects.filter(automation_id=automation_id).update(automation_id=None)
\ No newline at end of file
diff --git a/program/migrations/0012_auto_20171012_0056.py b/program/migrations/0012_auto_20171012_0056.py
deleted file mode 100644
index 754efbf8..00000000
--- a/program/migrations/0012_auto_20171012_0056.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.3 on 2017-10-12 00:56
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('program', '0011_programslot_remove_is_active'),
-    ]
-
-    operations = [
-        migrations.AlterModelOptions(
-            name='rrule',
-            options={'ordering': ('pk',), 'verbose_name': 'Recurrence rule', 'verbose_name_plural': 'Recurrence rules'},
-        ),
-        migrations.AlterField(
-            model_name='broadcastformat',
-            name='color',
-            field=models.CharField(default='#ffffff', max_length=7, verbose_name='Color'),
-        ),
-        migrations.AlterField(
-            model_name='broadcastformat',
-            name='text_color',
-            field=models.CharField(default='#000000', max_length=7, verbose_name='Text color'),
-        ),
-        migrations.AlterField(
-            model_name='musicfocus',
-            name='big_button',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Big button image'),
-        ),
-        migrations.AlterField(
-            model_name='musicfocus',
-            name='button',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image'),
-        ),
-        migrations.AlterField(
-            model_name='musicfocus',
-            name='button_hover',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image (hover)'),
-        ),
-        migrations.AlterField(
-            model_name='programslot',
-            name='created',
-            field=models.DateTimeField(auto_now_add=True, null=True),
-        ),
-        migrations.AlterField(
-            model_name='programslot',
-            name='last_updated',
-            field=models.DateTimeField(auto_now=True, null=True),
-        ),
-        migrations.AlterField(
-            model_name='rrule',
-            name='freq',
-            field=models.IntegerField(choices=[(1, 'Monthly'), (2, 'Weekly'), (3, 'Daily')], default=1, verbose_name='Frequency'),
-        ),
-        migrations.AlterField(
-            model_name='show',
-            name='image',
-            field=models.ImageField(blank=True, null=True, upload_to='show_images', verbose_name='Image'),
-        ),
-        migrations.AlterField(
-            model_name='showinformation',
-            name='big_button',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Big button image'),
-        ),
-        migrations.AlterField(
-            model_name='showinformation',
-            name='button',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image'),
-        ),
-        migrations.AlterField(
-            model_name='showinformation',
-            name='button_hover',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image (hover)'),
-        ),
-        migrations.AlterField(
-            model_name='showtopic',
-            name='big_button',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Big button image'),
-        ),
-        migrations.AlterField(
-            model_name='showtopic',
-            name='button',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image'),
-        ),
-        migrations.AlterField(
-            model_name='showtopic',
-            name='button_hover',
-            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image (hover)'),
-        ),
-    ]
diff --git a/program/migrations/0012_auto_20171108_1846.py b/program/migrations/0012_auto_20171108_1846.py
new file mode 100644
index 00000000..eddb203e
--- /dev/null
+++ b/program/migrations/0012_auto_20171108_1846.py
@@ -0,0 +1,256 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.3 on 2017-11-08 18:46
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import tinymce.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('program', '0011_programslot_remove_is_active'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Category',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('category', models.CharField(max_length=32, verbose_name='Category')),
+                ('abbrev', models.CharField(max_length=4, unique=True, verbose_name='Abbreviation')),
+                ('slug', models.SlugField(max_length=32, unique=True, verbose_name='Slug')),
+                ('button', models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image')),
+                ('button_hover', models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image (hover)')),
+                ('big_button', models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Big button image')),
+            ],
+            options={
+                'verbose_name': 'Category',
+                'verbose_name_plural': 'Categories',
+                'ordering': ('category',),
+            },
+        ),
+        migrations.CreateModel(
+            name='RTRCategory',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('rtrcategory', models.CharField(max_length=32, verbose_name='RTR Category')),
+                ('abbrev', models.CharField(max_length=4, unique=True, verbose_name='Abbreviation')),
+                ('slug', models.SlugField(max_length=32, unique=True, verbose_name='Slug')),
+            ],
+            options={
+                'verbose_name': 'RTR Category',
+                'verbose_name_plural': 'RTR Categories',
+                'ordering': ('rtrcategory',),
+            },
+        ),
+        migrations.CreateModel(
+            name='Schedule',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('byweekday', models.IntegerField(choices=[(0, 'Monday'), (1, 'Tuesday'), (2, 'Wednesday'), (3, 'Thursday'), (4, 'Friday'), (5, 'Saturday'), (6, 'Sunday')], verbose_name='Weekday')),
+                ('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')),
+                ('fallback_playlist', models.IntegerField(blank=True, null=True, verbose_name='Fallback Playlist')),
+                ('automation_id', models.IntegerField(blank=True, null=True, verbose_name='Automation ID')),
+                ('created', models.DateTimeField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+            ],
+            options={
+                'verbose_name': 'Schedule',
+                'verbose_name_plural': 'Schedules',
+                'ordering': ('dstart', 'tstart'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Topic',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('topic', models.CharField(max_length=32, verbose_name='Topic')),
+                ('abbrev', models.CharField(max_length=4, unique=True, verbose_name='Abbreviation')),
+                ('slug', models.SlugField(max_length=32, unique=True, verbose_name='Slug')),
+                ('button', models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image')),
+                ('button_hover', models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image (hover)')),
+                ('big_button', models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Big button image')),
+            ],
+            options={
+                'verbose_name': 'Topic',
+                'verbose_name_plural': 'Topics',
+                'ordering': ('topic',),
+            },
+        ),
+        migrations.CreateModel(
+            name='Type',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('type', models.CharField(max_length=32, verbose_name='Type')),
+                ('slug', models.SlugField(max_length=32, unique=True, verbose_name='Slug')),
+                ('color', models.CharField(default='#ffffff', max_length=7, verbose_name='Color')),
+                ('text_color', models.CharField(default='#000000', max_length=7, verbose_name='Text color')),
+                ('enabled', models.BooleanField(default=True, verbose_name='Enabled')),
+            ],
+            options={
+                'verbose_name': 'Type',
+                'verbose_name_plural': 'Types',
+                'ordering': ('type',),
+            },
+        ),
+        migrations.AlterUniqueTogether(
+            name='programslot',
+            unique_together=set([]),
+        ),
+        migrations.RemoveField(
+            model_name='programslot',
+            name='rrule',
+        ),
+        migrations.RemoveField(
+            model_name='programslot',
+            name='show',
+        ),
+        migrations.AlterModelOptions(
+            name='rrule',
+            options={'ordering': ('pk',), 'verbose_name': 'Recurrence rule', 'verbose_name_plural': 'Recurrence rules'},
+        ),
+        migrations.RemoveField(
+            model_name='show',
+            name='broadcastformat',
+        ),
+        migrations.RemoveField(
+            model_name='show',
+            name='image_enabled',
+        ),
+        migrations.RemoveField(
+            model_name='show',
+            name='showinformation',
+        ),
+        migrations.RemoveField(
+            model_name='show',
+            name='showtopic',
+        ),
+        migrations.RemoveField(
+            model_name='timeslot',
+            name='programslot',
+        ),
+        migrations.AddField(
+            model_name='note',
+            name='cba_id',
+            field=models.IntegerField(blank=True, null=True, verbose_name='CBA ID'),
+        ),
+        migrations.AddField(
+            model_name='note',
+            name='image',
+            field=models.ImageField(blank=True, null=True, upload_to='note_images', verbose_name='Featured image'),
+        ),
+        migrations.AddField(
+            model_name='note',
+            name='slug',
+            field=models.SlugField(default=1, max_length=32, unique=True, verbose_name='Slug'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='note',
+            name='summary',
+            field=tinymce.models.HTMLField(blank=True, verbose_name='Summary'),
+        ),
+        migrations.AddField(
+            model_name='note',
+            name='user',
+            field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='users', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AddField(
+            model_name='show',
+            name='cba_series_id',
+            field=models.IntegerField(blank=True, null=True, verbose_name='CBA Series ID'),
+        ),
+        migrations.AddField(
+            model_name='show',
+            name='fallback_pool',
+            field=models.CharField(blank=True, max_length=255, verbose_name='Fallback Pool'),
+        ),
+        migrations.AddField(
+            model_name='show',
+            name='logo',
+            field=models.ImageField(blank=True, null=True, upload_to='show_images', verbose_name='Logo'),
+        ),
+        migrations.AlterField(
+            model_name='musicfocus',
+            name='big_button',
+            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Big button image'),
+        ),
+        migrations.AlterField(
+            model_name='musicfocus',
+            name='button',
+            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image'),
+        ),
+        migrations.AlterField(
+            model_name='musicfocus',
+            name='button_hover',
+            field=models.ImageField(blank=True, null=True, upload_to='buttons', verbose_name='Button image (hover)'),
+        ),
+        migrations.AlterField(
+            model_name='show',
+            name='image',
+            field=models.ImageField(blank=True, null=True, upload_to='show_images', verbose_name='Image'),
+        ),
+        migrations.AlterField(
+            model_name='timeslot',
+            name='start',
+            field=models.DateTimeField(verbose_name='Start time'),
+        ),
+        migrations.DeleteModel(
+            name='BroadcastFormat',
+        ),
+        migrations.DeleteModel(
+            name='ProgramSlot',
+        ),
+        migrations.DeleteModel(
+            name='ShowInformation',
+        ),
+        migrations.DeleteModel(
+            name='ShowTopic',
+        ),
+        migrations.AddField(
+            model_name='schedule',
+            name='rrule',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='schedules', to='program.RRule', verbose_name='Recurrence rule'),
+        ),
+        migrations.AddField(
+            model_name='schedule',
+            name='show',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='schedules', to='program.Show', verbose_name='Show'),
+        ),
+        migrations.AddField(
+            model_name='show',
+            name='category',
+            field=models.ManyToManyField(blank=True, related_name='shows', to='program.Category', verbose_name='Category'),
+        ),
+        migrations.AddField(
+            model_name='show',
+            name='rtrcategory',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='shows', to='program.RTRCategory', verbose_name='RTR Category'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='show',
+            name='topic',
+            field=models.ManyToManyField(blank=True, related_name='shows', to='program.Topic', verbose_name='Topic'),
+        ),
+        migrations.AddField(
+            model_name='show',
+            name='type',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='shows', to='program.Type', verbose_name='Type'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='timeslot',
+            name='schedule',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='timeslots', to='program.Schedule', verbose_name='Schedule'),
+            preserve_default=False,
+        ),
+    ]
diff --git a/program/migrations/0013_auto_20171012_0108.py b/program/migrations/0013_auto_20171012_0108.py
deleted file mode 100644
index 0f061916..00000000
--- a/program/migrations/0013_auto_20171012_0108.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.3 on 2017-10-12 01:08
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('program', '0012_auto_20171012_0056'),
-    ]
-
-    operations = [
-        migrations.AlterUniqueTogether(
-            name='programslot',
-            unique_together=set([]),
-        ),
-    ]
diff --git a/program/migrations/0014_auto_20171012_1456.py b/program/migrations/0014_auto_20171012_1456.py
deleted file mode 100644
index b24346b2..00000000
--- a/program/migrations/0014_auto_20171012_1456.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.3 on 2017-10-12 14:56
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('program', '0013_auto_20171012_0108'),
-    ]
-
-    operations = [
-        migrations.AlterUniqueTogether(
-            name='programslot',
-            unique_together=set([('rrule', 'byweekday', 'dstart', 'tstart')]),
-        ),
-    ]
diff --git a/program/migrations/0015_auto_20171013_1638.py b/program/migrations/0015_auto_20171013_1638.py
deleted file mode 100644
index 5aa6ac26..00000000
--- a/program/migrations/0015_auto_20171013_1638.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.3 on 2017-10-13 16:38
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('program', '0014_auto_20171012_1456'),
-    ]
-
-    operations = [
-        migrations.AlterUniqueTogether(
-            name='programslot',
-            unique_together=set([]),
-        ),
-    ]
diff --git a/program/migrations/0016_auto_20171017_2016.py b/program/migrations/0016_auto_20171017_2016.py
deleted file mode 100644
index c6e876d9..00000000
--- a/program/migrations/0016_auto_20171017_2016.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.3 on 2017-10-17 20:16
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('program', '0015_auto_20171013_1638'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='timeslot',
-            name='start',
-            field=models.DateTimeField(verbose_name='Start time'),
-        ),
-    ]
diff --git a/program/models.py b/program/models.py
index 7eda390a..8404731a 100644
--- a/program/models.py
+++ b/program/models.py
@@ -15,17 +15,17 @@ from dateutil.rrule import rrule
 from .utils import get_automation_id_choices
 
 
-class BroadcastFormat(models.Model):
-    format = models.CharField(_("Format"), max_length=32)
+class Type(models.Model):
+    type = models.CharField(_("Type"), max_length=32)
     slug = models.SlugField(_("Slug"), max_length=32, unique=True)
     color = models.CharField(_("Color"), max_length=7, default='#ffffff')
     text_color = models.CharField(_("Text color"), max_length=7, default='#000000')
     enabled = models.BooleanField(_("Enabled"), default=True)
 
     class Meta:
-        ordering = ('format',)
-        verbose_name = _("Broadcast format")
-        verbose_name_plural = _("Broadcast formats")
+        ordering = ('type',)
+        verbose_name = _("Type")
+        verbose_name_plural = _("Types")
 
     def admin_color(self):
         return '<span style="background-color: %s; color: %s; padding: 0.2em">%s/%s</span>' % (
@@ -35,11 +35,11 @@ class BroadcastFormat(models.Model):
     admin_color.allow_tags = True
 
     def __str__(self):
-        return '%s' % self.format
+        return '%s' % self.type
 
 
-class ShowInformation(models.Model):
-    information = models.CharField(_("Information"), max_length=32)
+class Category(models.Model):
+    category = models.CharField(_("Category"), max_length=32)
     abbrev = models.CharField(_("Abbreviation"), max_length=4, unique=True)
     slug = models.SlugField(_("Slug"), max_length=32, unique=True)
     button = models.ImageField(_("Button image"), blank=True, null=True, upload_to='buttons')
@@ -47,9 +47,9 @@ class ShowInformation(models.Model):
     big_button = models.ImageField(_("Big button image"), blank=True, null=True, upload_to='buttons')
 
     class Meta:
-        ordering = ('information',)
-        verbose_name = _("Show information")
-        verbose_name_plural = _("Show information")
+        ordering = ('category',)
+        verbose_name = _("Category")
+        verbose_name_plural = _("Categories")
 
     def admin_buttons(self):
         buttons = []
@@ -92,11 +92,11 @@ class ShowInformation(models.Model):
             return '/site_media/buttons/default-17.png'
 
     def __str__(self):
-        return '%s' % self.information
+        return '%s' % self.category
 
 
-class ShowTopic(models.Model):
-    topic = models.CharField(_("Show topic"), max_length=32)
+class Topic(models.Model):
+    topic = models.CharField(_("Topic"), max_length=32)
     abbrev = models.CharField(_("Abbreviation"), max_length=4, unique=True)
     slug = models.SlugField(_("Slug"), max_length=32, unique=True)
     button = models.ImageField(_("Button image"), blank=True, null=True, upload_to='buttons')
@@ -105,8 +105,8 @@ class ShowTopic(models.Model):
 
     class Meta:
         ordering = ('topic',)
-        verbose_name = _("Show topic")
-        verbose_name_plural = _("Show topics")
+        verbose_name = _("Topic")
+        verbose_name_plural = _("Topics")
 
     def admin_buttons(self):
         buttons = []
@@ -209,6 +209,20 @@ class MusicFocus(models.Model):
         return '%s' % self.focus
 
 
+class RTRCategory(models.Model):
+    rtrcategory = models.CharField(_("RTR Category"), max_length=32)
+    abbrev = models.CharField(_("Abbreviation"), max_length=4, unique=True)
+    slug = models.SlugField(_("Slug"), max_length=32, unique=True)
+
+    class Meta:
+        ordering = ('rtrcategory',)
+        verbose_name = _("RTR Category")
+        verbose_name_plural = _("RTR Categories")
+
+    def __str__(self):
+        return '%s' % self.rtrcategory
+
+
 class Host(models.Model):
     name = models.CharField(_("Name"), max_length=128)
     is_always_visible = models.BooleanField(_("Is always visible"), default=False)
@@ -227,25 +241,28 @@ class Host(models.Model):
         return reverse('host-detail', args=[str(self.id)])
 
     def active_shows(self):
-        return self.shows.filter(programslots__until__gt=datetime.today())
+        return self.shows.filter(schedules__until__gt=datetime.today())
 
 
 class Show(models.Model):
     predecessor = models.ForeignKey('self', blank=True, null=True, related_name='successors', verbose_name=_("Predecessor"))
     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, related_name='shows', verbose_name=_("Show information"))
-    showtopic = models.ManyToManyField(ShowTopic, blank=True, related_name='shows', verbose_name=_("Show topic"))
+    type = models.ForeignKey(Type, related_name='shows', verbose_name=_("Type"))
+    category = models.ManyToManyField(Category, blank=True, related_name='shows', verbose_name=_("Category"))
+    rtrcategory = models.ForeignKey(RTRCategory, related_name='shows', verbose_name=_("RTR Category"))
+    topic = models.ManyToManyField(Topic, blank=True, related_name='shows', verbose_name=_("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)
+    logo = models.ImageField(_("Logo"), blank=True, null=True, upload_to='show_images')
     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)
+    cba_series_id = models.IntegerField(_("CBA Series ID"), blank=True, null=True)
+    fallback_pool = models.CharField(_("Fallback Pool"), max_length=255, blank=True)
     created = models.DateTimeField(auto_now_add=True, editable=False)
     last_updated = models.DateTimeField(auto_now=True, editable=False)
 
@@ -261,8 +278,8 @@ class Show(models.Model):
         return reverse('show-detail', args=[self.slug])
 
     # Called by show templates
-    def active_programslots(self):
-        return self.programslots.filter(until__gt=date.today())
+    def active_schedules(self):
+        return self.schedules.filter(until__gt=date.today())
 
 
 class RRule(models.Model):
@@ -297,7 +314,7 @@ class RRule(models.Model):
         return '%s' % self.name
 
 
-class ProgramSlot(models.Model):
+class Schedule(models.Model):
     BYWEEKDAY_CHOICES = (
         (0, _("Monday")),
         (1, _("Tuesday")),
@@ -308,9 +325,9 @@ class ProgramSlot(models.Model):
         (6, _("Sunday")),
     )
 
-    rrule = models.ForeignKey(RRule, related_name='programslots', verbose_name=_("Recurrence rule"))
+    rrule = models.ForeignKey(RRule, related_name='schedules', verbose_name=_("Recurrence rule"))
     byweekday = models.IntegerField(_("Weekday"), choices=BYWEEKDAY_CHOICES)
-    show = models.ForeignKey(Show, related_name='programslots', verbose_name=_("Show"))
+    show = models.ForeignKey(Show, related_name='schedules', verbose_name=_("Show"))
     dstart = models.DateField(_("First date"))
     tstart = models.TimeField(_("Start time"))
     tend = models.TimeField(_("End time"))
@@ -322,7 +339,7 @@ class ProgramSlot(models.Model):
 
     class Meta:
         ordering = ('dstart', 'tstart')
-        # Produces error when adding several programslots at the same time.
+        # Produces error when adding several schedules at the same time.
         # Do this test in another way, since it is quite unspecific anyway
         #unique_together = ('rrule', 'byweekday', 'dstart', 'tstart')
         verbose_name = _("Program slot")
@@ -341,55 +358,55 @@ class ProgramSlot(models.Model):
         else:
             return '%s, %s, %s - %s' % (weekday, self.rrule, tstart, tend)
 
-    def generate_timeslots(programslot):
+    def generate_timeslots(schedule):
         """
-        Returns a list of timeslot objects based on a programslot and its rrule
+        Returns a list of timeslot objects based on a schedule and its rrule
         Returns past timeslots as well starting from dstart (not today)
         """
 
         byweekno = None
         byweekno_end = None
-        byweekday_end = int(programslot.byweekday)
+        byweekday_end = int(schedule.byweekday)
         starts = []
         ends = []
         timeslots = []
 
         # Handle ending weekday for timeslots over midnight
-        if programslot.tend < programslot.tstart:
-            if programslot.byweekday < 6:
-                byweekday_end = int(programslot.byweekday + 1)
+        if schedule.tend < schedule.tstart:
+            if schedule.byweekday < 6:
+                byweekday_end = int(schedule.byweekday + 1)
             else:
                 byweekday_end = 0
 
         # Handle ending dates for timeslots over midnight
-        if programslot.tend < programslot.tstart:
-            dend = programslot.dstart + timedelta(days=+1)
+        if schedule.tend < schedule.tstart:
+            dend = schedule.dstart + timedelta(days=+1)
         else:
-            dend = programslot.dstart
+            dend = schedule.dstart
 
-        if programslot.rrule.freq == 0: # Ignore weekdays for one-time timeslots
+        if schedule.rrule.freq == 0: # Ignore weekdays for one-time timeslots
             byweekday_start = None
             byweekday_end = None
-        elif programslot.rrule.freq == 3 and programslot.rrule.pk == 2: # Daily timeslots
+        elif schedule.rrule.freq == 3 and schedule.rrule.pk == 2: # Daily timeslots
             byweekday_start = (0, 1, 2, 3, 4, 5, 6)
             byweekday_end = (0, 1, 2, 3, 4, 5, 6)
-        elif programslot.rrule.freq == 3 and programslot.rrule.pk == 3: # Business days MO - FR/SA
+        elif schedule.rrule.freq == 3 and schedule.rrule.pk == 3: # Business days MO - FR/SA
             byweekday_start = (0, 1, 2, 3, 4)
-            if programslot.tend < programslot.tstart:
+            if schedule.tend < schedule.tstart:
                 # End days for over midnight
                 byweekday_end = (1, 2, 3, 4, 5)
             else:
                 byweekday_end = (0, 1, 2, 3, 4)
-        elif programslot.rrule.freq == 2 and programslot.rrule.pk == 7: # Even calendar weeks
-            byweekday_start = int(programslot.byweekday)
+        elif schedule.rrule.freq == 2 and schedule.rrule.pk == 7: # Even calendar weeks
+            byweekday_start = int(schedule.byweekday)
             byweekno = list(range(2, 54, 2))
             # Reverse ending weeks if from Sun - Mon
             if byweekday_start == 6 and byweekday_end == 0:
                 byweekno_end = list(range(1, 54, 2))
             else:
                 byweekno_end = byweekno
-        elif programslot.rrule.freq == 2 and programslot.rrule.pk == 8: # Odd calendar weeks
-            byweekday_start = int(programslot.byweekday)
+        elif schedule.rrule.freq == 2 and schedule.rrule.pk == 8: # Odd calendar weeks
+            byweekday_start = int(schedule.byweekday)
             byweekno = list(range(1, 54, 2))
             # Reverse ending weeks if from Sun - Mon
             if byweekday_start == 6 and byweekday_end == 0:
@@ -397,31 +414,31 @@ class ProgramSlot(models.Model):
             else:
                 byweekno_end = byweekno
         else:
-            byweekday_start = int(programslot.byweekday)
+            byweekday_start = int(schedule.byweekday)
 
-        if programslot.rrule.freq == 0:
-            starts.append(datetime.combine(programslot.dstart, programslot.tstart))
-            ends.append(datetime.combine(dend, programslot.tend))
+        if schedule.rrule.freq == 0:
+            starts.append(datetime.combine(schedule.dstart, schedule.tstart))
+            ends.append(datetime.combine(dend, schedule.tend))
         else:
 
-            starts = list(rrule(freq=programslot.rrule.freq,
-                            dtstart=datetime.combine(programslot.dstart, programslot.tstart),
-                            interval=programslot.rrule.interval,
-                            until=programslot.until + relativedelta(days=+1),
-                            bysetpos=programslot.rrule.bysetpos,
+            starts = list(rrule(freq=schedule.rrule.freq,
+                            dtstart=datetime.combine(schedule.dstart, schedule.tstart),
+                            interval=schedule.rrule.interval,
+                            until=schedule.until + relativedelta(days=+1),
+                            bysetpos=schedule.rrule.bysetpos,
                             byweekday=byweekday_start,
                             byweekno=byweekno))
 
-            ends = list(rrule(freq=programslot.rrule.freq,
-                          dtstart=datetime.combine(dend, programslot.tend),
-                          interval=programslot.rrule.interval,
-                          until=programslot.until + relativedelta(days=+1),
-                          bysetpos=programslot.rrule.bysetpos,
+            ends = list(rrule(freq=schedule.rrule.freq,
+                          dtstart=datetime.combine(dend, schedule.tend),
+                          interval=schedule.rrule.interval,
+                          until=schedule.until + relativedelta(days=+1),
+                          bysetpos=schedule.rrule.bysetpos,
                           byweekday=byweekday_end,
                           byweekno=byweekno_end))
 
         for k in range(min(len(starts), len(ends))):
-            timeslots.append(TimeSlot(programslot=programslot, start=starts[k], end=ends[k]).generate())
+            timeslots.append(TimeSlot(schedule=schedule, start=starts[k], end=ends[k]).generate())
             print(str(starts[k]) + ' - ' + str(ends[k]))
 
         return timeslots
@@ -458,7 +475,8 @@ class ProgramSlot(models.Model):
         #if not self.id or self.id == None:
         #    self.created = datetime.today()
 
-        super(ProgramSlot, self).save(*args, **kwargs)
+        super(Schedule, self).save(*args, **kwargs)
+
 
 
 class TimeSlotManager(models.Manager):
@@ -479,7 +497,7 @@ class TimeSlotManager(models.Manager):
             dstart, tstart = previous_timeslot.end.date(), previous_timeslot.end.time()
             until, tend = next_timeslot.start.date(), next_timeslot.start.time()
 
-            new_programslot = ProgramSlot(rrule=once,
+            new_schedule = Schedule(rrule=once,
                                           byweekday=today,
                                           show=default,
                                           dstart=dstart,
@@ -488,12 +506,12 @@ class TimeSlotManager(models.Manager):
                                           until=until)
 
             try:
-                new_programslot.validate_unique()
-                new_programslot.save()
+                new_schedule.validate_unique()
+                new_schedule.save()
             except ValidationError:
                 pass
             else:
-                return new_programslot.timeslots.all()[0]
+                return new_schedule.timeslots.all()[0]
 
     @staticmethod
     def get_day_timeslots(day):
@@ -521,7 +539,7 @@ class TimeSlotManager(models.Manager):
 
 
 class TimeSlot(models.Model):
-    programslot = models.ForeignKey(ProgramSlot, related_name='timeslots', verbose_name=_("Program slot"))
+    schedule = models.ForeignKey(Schedule, related_name='timeslots', verbose_name=_("Schedule"))
     start = models.DateTimeField(_("Start time")) # Removed 'unique=True' because new Timeslots need to be created before deleting the old ones (otherwise linked notes get deleted first)
     end = models.DateTimeField(_("End time"))
     show = models.ForeignKey(Show, editable=False, related_name='timeslots')
@@ -540,13 +558,13 @@ class TimeSlot(models.Model):
         return '%s - %s  |  %s' % (start, end, self.show.name)
 
     def save(self, *args, **kwargs):
-        self.show = self.programslot.show
+        self.show = self.schedule.show
         super(TimeSlot, self).save(*args, **kwargs)
         return self;
 
     def generate(self, **kwargs):
         """Returns the object instance without saving"""
-        self.show = self.programslot.show
+        self.show = self.schedule.show
         return self;
 
     def get_absolute_url(self):
@@ -559,14 +577,19 @@ class Note(models.Model):
         (1, _("Recommendation")),
         (2, _("Repetition")),
     )
-    timeslot = models.OneToOneField(TimeSlot, verbose_name=_("Time slot"))
+    timeslot = models.OneToOneField(TimeSlot, verbose_name=_("Time slot"), unique=True)
     title = models.CharField(_("Title"), max_length=128)
+    slug = models.SlugField(_("Slug"), max_length=32, unique=True)
+    summary = tinymce_models.HTMLField(_("Summary"), blank=True)
     content = tinymce_models.HTMLField(_("Content"))
+    image = models.ImageField(_("Featured image"), blank=True, null=True, upload_to='note_images')
     status = models.IntegerField(_("Status"), choices=STATUS_CHOICES, default=1)
     start = models.DateTimeField(editable=False)
     show = models.ForeignKey(Show, editable=False, related_name='notes')
+    cba_id = models.IntegerField(_("CBA ID"), blank=True, null=True)
     created = models.DateTimeField(auto_now_add=True, editable=False)
     last_updated = models.DateTimeField(auto_now=True, editable=False)
+    user = models.ForeignKey(User, editable=False, related_name='users', default=1)
 
     class Meta:
         ordering = ('timeslot',)
@@ -578,6 +601,6 @@ class Note(models.Model):
 
     def save(self, *args, **kwargs):
         self.start = self.timeslot.start
-        self.show = self.timeslot.programslot.show
+        self.show = self.timeslot.schedule.show
 
         super(Note, self).save(*args, **kwargs)
\ No newline at end of file
diff --git a/program/templates/boxes/category.html b/program/templates/boxes/category.html
new file mode 100644
index 00000000..85520b1c
--- /dev/null
+++ b/program/templates/boxes/category.html
@@ -0,0 +1,16 @@
+{% if category_list %}
+    <dl id="filterbox_category" class="portlet filterbox">
+        <dt class="portletHeader"><span>Sendungsinfo<span></dt>
+        <dd class="portletItem">
+            <ul>
+                {% for ca in category_list %}
+                    <li>
+                        <a title="Sendungen mit der Kategorie {{ ca.category }} anzeigen."
+                           class="abbrev ca-{{ ca.abbrev }}"
+                           href="?category={{ ca.slug }}">{{ ca.category }}</a>
+                    </li>
+                {% endfor %}
+            </ul>
+        </dd>
+    </dl>
+{% endif %}
\ No newline at end of file
diff --git a/program/templates/boxes/current.html b/program/templates/boxes/current.html
index 0ac51799..add51f5e 100644
--- a/program/templates/boxes/current.html
+++ b/program/templates/boxes/current.html
@@ -12,8 +12,8 @@
             <table>
                 <tr class="previous">
                     <td class="start">{{ previous_timeslot.start|date:"H:i" }}</td>
-                    <td class="format bf-{{ previous_timeslot.show.broadcastformat.slug }}"
-                        title="{{ previous_timeslot.show.broadcastformat.format }}">&nbsp;</td>
+                    <td class="type ty-{{ previous_timeslot.show.type.slug }}"
+                        title="{{ previous_timeslot.show.type.type }}">&nbsp;</td>
                     <td class="show">
                         <h3>
                             <a href="{% url "timeslot-detail" previous_timeslot.id %}">{{ previous_timeslot.show.name }}</a>
@@ -23,8 +23,8 @@
                 </tr>
                 <tr class="current">
                     <td class="start">{{ current_timeslot.start|date:"H:i" }}</td>
-                    <td class="format bf-{{ current_timeslot.show.broadcastformat.slug }}"
-                        title="{{ current_timeslot.show.broadcastformat.format }}">&#x25B6;</td>
+                    <td class="type ty-{{ current_timeslot.show.type.slug }}"
+                        title="{{ current_timeslot.show.type.type }}">&#x25B6;</td>
                     <td class="show">
                         <h3>
                             <a href="{% url "timeslot-detail" current_timeslot.id %}">{{ current_timeslot.show.name }}</a>
@@ -38,8 +38,8 @@
                 </tr>
                 <tr class="next">
                     <td class="start">{{ next_timeslot.start|date:"H:i" }}</td>
-                    <td class="format bf-{{ next_timeslot.show.broadcastformat.slug }}"
-                        title="{{ next_timeslot.show.broadcastformat.format }}">&nbsp;</td>
+                    <td class="type ty-{{ next_timeslot.show.type.slug }}"
+                        title="{{ next_timeslot.show.type.type }}">&nbsp;</td>
                     <td class="show">
                         <h3><a href="{% url "timeslot-detail" next_timeslot.id %}">{{ next_timeslot.show.name }}</a>
                         </h3>
@@ -48,8 +48,8 @@
                 </tr>
                 <tr class="after_next">
                     <td class="start">{{ after_next_timeslot.start|date:"H:i" }}</td>
-                    <td class="format bf-{{ after_next_timeslot.show.broadcastformat.slug }}"
-                        title="{{ after_next_timeslot.show.broadcastformat.format }}">&nbsp;</td>
+                    <td class="type ty-{{ after_next_timeslot.show.type.slug }}"
+                        title="{{ after_next_timeslot.show.type.type }}">&nbsp;</td>
                     <td class="show">
                         <h3>
                             <a href="{% url "timeslot-detail" after_next_timeslot.id %}">{{ after_next_timeslot.show.name }}</a>
@@ -62,4 +62,4 @@
     </dl>
 {% endif %}
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/boxes/recommendation.html b/program/templates/boxes/recommendation.html
index 3f4429e0..9ac8625b 100644
--- a/program/templates/boxes/recommendation.html
+++ b/program/templates/boxes/recommendation.html
@@ -13,8 +13,8 @@
                 {% for recommendation in recommendation_list %}
                     <tr>
                         <td class="start">&nbsp;</td>
-                        <td class="format bf-{{ recommendation.show.broadcastformat.slug }}"
-                            title="{{ recommendation.show.broadcastformat.format }}">&nbsp;</td>
+                        <td class="type ty-{{ recommendation.show.type.slug }}"
+                            title="{{ recommendation.show.type.type }}">&nbsp;</td>
                         <td class="show">
                             {{ recommendation.start|date:"d.m. H:i" }} - {{ recommendation.end|date:"H:i" }}<br/>
                             <h3>
@@ -24,7 +24,7 @@
                                 {% if recommendation.note %}
                                     {{ recommendation.note.title }}<br/>
                                 {% else %}
-                                    {{ recommendation.show.broadcastformat.format }}<br/>
+                                    {{ recommendation.show.type.type }}<br/>
                                 {% endif %}
                                 <a href="{% url "timeslot-detail" recommendation.id %}">[weiter]</a>
                             </p>
@@ -36,4 +36,4 @@
     </dl>
 {% endif %}
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/boxes/topic.html b/program/templates/boxes/topic.html
new file mode 100644
index 00000000..7cbab0b6
--- /dev/null
+++ b/program/templates/boxes/topic.html
@@ -0,0 +1,16 @@
+{% if topic_list %}
+    <dl id="filterbox_topic" class="portlet filterbox">
+        <dt class="portletHeader"><span>Thema / Schwerpunkt<span></dt>
+        <dd class="portletItem">
+            <ul>
+                {% for topic in topic_list %}
+                    <li>
+                        <a title="Sendungen mit dem Schwerpunkt {{ topic.topic }} anzeigen."
+                           class="abbrev to-{{ topic.abbrev }}"
+                           href="?topic={{ topic.slug }}">{{ topic.topic }}</a>
+                    </li>
+                {% endfor %}
+            </ul>
+        </dd>
+    </dl>
+{% endif %}
\ No newline at end of file
diff --git a/program/templates/boxes/type.html b/program/templates/boxes/type.html
new file mode 100644
index 00000000..6fb2deff
--- /dev/null
+++ b/program/templates/boxes/type.html
@@ -0,0 +1,11 @@
+{% if type_list %}
+    <dl id="type" class="portlet">
+        <dt class="portletHeader"><span>Legende</span></dt>
+        {% for ty in type_list %}
+            <dd class="portletItem type ty-{{ ty.slug }}">
+                <a title="Sendungen mit dem Sendungsformat {{ ty.type }} anzeigen."
+                   href="?type={{ ty.slug }}">{{ type.type }}</a>
+            </dd>
+        {% endfor %}
+    </dl>
+{% endif %}
\ No newline at end of file
diff --git a/program/templates/collisions.html b/program/templates/collisions.html
index c6ac173c..e891b8dc 100644
--- a/program/templates/collisions.html
+++ b/program/templates/collisions.html
@@ -24,8 +24,8 @@
 
     <div id="content-main">
 
-      <strong>{{ programslot.show }}</strong>
-      <p>{{ programslot }}</p>
+      <strong>{{ schedule.show }}</strong>
+      <p>{{ schedule }}</p>
       <p>
         {{ timeslots|length }} Timeslots generiert.
         {% if self.num_collisions > 0 %}
@@ -33,7 +33,7 @@
         {% endif %}
       </p>
 
-      <form id="collisions_form" action="/admin/program/show/{{ programslot.show_id }}/change/" enctype="multipart/form-data" method="post">
+      <form id="collisions_form" action="/admin/program/show/{{ schedule.show_id }}/change/" enctype="multipart/form-data" method="post">
       {% csrf_token %}
 
         <table class="table">
@@ -127,16 +127,16 @@
           <input type="hidden" name="collisions[{{ forloop.counter0 }}]" value="{{ collision.id}}" />
         {% endfor %}
 
-        <input type="hidden" name="ps_save_id" value="{{ programslot.id }}" />
-        <input type="hidden" name="ps_save_rrule_id" value="{{ programslot.rrule_id }}" />
-        <input type="hidden" name="ps_save_byweekday" value="{{ programslot.byweekday }}" />
-        <input type="hidden" name="ps_save_dstart" value="{{ programslot.dstart|date:"Y-m-d" }}" />
-        <input type="hidden" name="ps_save_tstart" value="{{ programslot.tstart }}" />
-        <input type="hidden" name="ps_save_tend" value="{{ programslot.tend }}" />
-        <input type="hidden" name="ps_save_until" value="{{ programslot.until|date:"Y-m-d" }}" />
-        <input type="hidden" name="ps_save_is_repetition" value="{{ programslot.is_repetition }}" />
-        <input type="hidden" name="ps_save_automation_id" value="{{ programslot.automation_id }}" />
-        <input type="hidden" name="ps_save_show_id" value="{{ programslot.show_id }} " />
+        <input type="hidden" name="ps_save_id" value="{{ schedule.id }}" />
+        <input type="hidden" name="ps_save_rrule_id" value="{{ schedule.rrule_id }}" />
+        <input type="hidden" name="ps_save_byweekday" value="{{ schedule.byweekday }}" />
+        <input type="hidden" name="ps_save_dstart" value="{{ schedule.dstart|date:"Y-m-d" }}" />
+        <input type="hidden" name="ps_save_tstart" value="{{ schedule.tstart }}" />
+        <input type="hidden" name="ps_save_tend" value="{{ schedule.tend }}" />
+        <input type="hidden" name="ps_save_until" value="{{ schedule.until|date:"Y-m-d" }}" />
+        <input type="hidden" name="ps_save_is_repetition" value="{{ schedule.is_repetition }}" />
+        <input type="hidden" name="ps_save_automation_id" value="{{ schedule.automation_id }}" />
+        <input type="hidden" name="ps_save_show_id" value="{{ schedule.show_id }} " />
         <input type="hidden" name="num_inputs" value="{{ num_inputs }}" />
         <input type="hidden" name="step" value="{{ step }}" />
 
@@ -155,7 +155,7 @@
         </div>
 
         <div style="display:none;">
-         {{ programslotsform.as_ul }}
+         {{ schedulesform.as_ul }}
          {{ showform.as_ul }}
         </div>
 
diff --git a/program/templates/day_schedule.html b/program/templates/day_schedule.html
index eb0d3d75..e6272928 100644
--- a/program/templates/day_schedule.html
+++ b/program/templates/day_schedule.html
@@ -34,8 +34,8 @@
 </dl>
 
 {% load content_boxes %}
-<div id="filter-format">
-    {% broadcastformat %}
+<div id="filter-type">
+    {% type %}
 </div>
 
 {% comment %}
@@ -44,8 +44,8 @@
     <dt class="portletHeader"><span>Filter</span></dt>
   </dl>
 {% musicfocus %}
-{% showinformation %}
-{% showtopic %}
+{% category %}
+{% topic %}
 </div>
 {% endcomment %}
 
@@ -56,15 +56,15 @@
     <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="timeslot ty-{{ default_show.type.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>
+                        {% for ca in default_show.category.all %}
+                            <span title="{{ ca.category }}"
+                                  class="abbrev ca-{{ ca.abbrev }}"><span>{{ ca.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>
+                        {% for to in default_show.topic.all %}
+                            <span title="{{ to.topic }}" class="abbrev to-{{ to.abbrev }}"><span>{{ to.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>
@@ -76,16 +76,16 @@
                     </div>
                 </div>
             {% endif %}
-            <div class="timeslot bf-{{ timeslot.show.broadcastformat.slug }}">
+            <div class="timeslot bf-{{ timeslot.show.type.slug }}">
                 <div class="show-start">{{ timeslot.start|date:"H:i" }}</div>
                 <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>
+                    {% for ca in timeslot.show.category.all %}
+                        <span title="{{ ca.category }}"
+                              class="abbrev ca-{{ ca.abbrev }}"><span>{{ ca.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>
+                    {% for to in timeslot.show.topic.all %}
+                        <span title="{{ to.topic }}"
+                              class="abbrev to-{{ to.abbrev }}"><span>{{ to.abbrev }}</span></span>
                     {% endfor %}
                     {% for mf in timeslot.show.musicfocus.all %}
                         <span title="{{ mf.focus }}"
@@ -103,15 +103,15 @@
                 </div>
             </div>
             {% if timeslot.end != timeslot.get_next_by_start.start %}
-                <div class="timeslot bf-{{ default_show.broadcastformat.slug }}">
+                <div class="timeslot ty-{{ default_show.type.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>
+                        {% for ca in default_show.category.all %}
+                            <span title="{{ ca.category }}"
+                                  class="abbrev ca-{{ ca.abbrev }}"><span>{{ ca.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>
+                        {% for to in default_show.topic.all %}
+                            <span title="{{ to.topic }}" class="abbrev to-{{ to.abbrev }}"><span>{{ to.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>
@@ -128,4 +128,4 @@
 </div>
 
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/host_detail.html b/program/templates/host_detail.html
index e7aad16a..d8177481 100644
--- a/program/templates/host_detail.html
+++ b/program/templates/host_detail.html
@@ -10,7 +10,7 @@
     <div id="shows">
         <div id="shows-title">Sendungen</div>
         {% for show in host.active_shows %}
-            <div class="show {{ show.broadcastformat.slug }}"><a href="{% url "show-detail" show.slug %}"> {{ show.name }}</a></div>
+            <div class="show {{ show.type.slug }}"><a href="{% url "show-detail" show.slug %}"> {{ show.name }}</a></div>
         {% endfor %}
     </div>
 
@@ -24,4 +24,4 @@
 </div>
 
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/recommendation_list.html b/program/templates/recommendation_list.html
index 3fcc5d19..e0de7636 100644
--- a/program/templates/recommendation_list.html
+++ b/program/templates/recommendation_list.html
@@ -8,15 +8,15 @@
     <h1>Programmhinweise</h1>
     <div id="shows">
         {% for recommendation in recommendation_list %}
-            <div class="show recommendation  bf-{{ recommendation.show.broadcastformat.slug }}">
+            <div class="show recommendation  ty-{{ recommendation.show.type.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>
+                    {% for ca in recommendation.show.category.all %}
+                        <span title="{{ ca.category }}"
+                              class="abbrev ca-{{ ca.abbrev }}"><span>{{ ca.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>
+                    {% for to in recommendation.show.topic.all %}
+                        <span title="{{ to.topic }}"
+                              class="abbrev to-{{ to.abbrev }}"><span>{{ to.abbrev }}</span></span>
                     {% endfor %}
                     {% for mf in recommendation.show.musicfocus.all %}
                         <span title="{{ mf.focus }}"
@@ -34,7 +34,7 @@
                         <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>
+                                href="{% url "timeslot-detail" recommendation.id %}">{{ recommendation.show.type.type }}</a>
                         </h3>
                     {% endif %}
                 </div>
@@ -44,4 +44,4 @@
 </div>
 
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/show_detail.html b/program/templates/show_detail.html
index 2e45549b..43fd9a0b 100644
--- a/program/templates/show_detail.html
+++ b/program/templates/show_detail.html
@@ -8,25 +8,25 @@
 
 <div id="content-main" class="show-detail">
 
-    <div class="show-detail-header bf-{{ show.broadcastformat.slug }}">
+    <div class="show-detail-header ty-{{ show.type.slug }}">
         <div class="show-details">
             <h1 id="name">{{ show.name }}</h1>
             {% if show.id != 1 %}
-                <p id="programslots">
-                    {% for slot in show.active_programslots %}
-                        <span class="programslot">{{ slot }}</span><br/>
+                <p id="schedules">
+                    {% for schedule in show.active_schedules %}
+                        <span class="schedule">{{ schedule }}</span><br/>
                     {% endfor %}
                 </p>
             {% endif %}
         </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>
+            <p id="type">{{ show.type.type }}</p>
+            {% for ca in show.category.all %}
+                <span title="{{ ca.category }}" class="abbrev ca-{{ ca.abbrev }}"><span>{{ ca.abbrev }}</span></span>
             {% endfor %}
-            {% for st in show.showtopic.all %}
-                <span title="{{ st.topic }}" class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+            {% for to in show.topic.all %}
+                <span title="{{ to.topic }}" class="abbrev to-{{ to.abbrev }}"><span>{{ to.abbrev }}</span></span>
             {% endfor %}
             {% for mf in show.musicfocus.all %}
                 <span title="{{ mf.focus }}" class="abbrev mf-{{ mf.abbrev }}"><span>{{ mf.abbrev }}</span></span>
@@ -41,7 +41,7 @@
         <div id="description">{{ show.description|safe }}</div>
     {% endif %}
 
-    {% if show.image and show.image_enabled %}
+    {% if show.image %}
         <div id="image" style="float: right;"><img src="/program/static/{{ show.image }}" width="200" alt="image"></div>
     {% endif %}
 
@@ -85,4 +85,4 @@
 </div>
 
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/show_list.html b/program/templates/show_list.html
index d9b9a479..d16c90ea 100644
--- a/program/templates/show_list.html
+++ b/program/templates/show_list.html
@@ -5,16 +5,16 @@
 <body>
 
 {% load content_boxes %}
-<div id="filter-format">
-    {% broadcastformat %}
+<div id="filter-type">
+    {% type %}
 </div>
 <div id="filter-topic">
     <dl id="filter-header" class="portlet">
         <dt class="portletHeader"><span>Filter</span></dt>
     </dl>
     {% musicfocus %}
-    {% showinformation %}
-    {% showtopic %}
+    {% category %}
+    {% topic %}
 </div>
 
 <div id="content-main" class="show-list">
@@ -22,15 +22,15 @@
 
     <div id="shows">
         {% for show in show_list %}
-            <div class="show bf-{{ show.broadcastformat.slug }}">
+            <div class="show ty-{{ show.type.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>
+                    {% for ca in show.category.all %}
+                        <span title="{{ ca.category }}"
+                              class="abbrev ca-{{ ca.abbrev }}"><span>{{ ca.abbrev }}</span></span>
                     {% endfor %}
-                    {% for st in show.showtopic.all %}
-                        <span title="{{ st.topic }}"
-                              class="abbrev st-{{ st.abbrev }}"><span>{{ st.abbrev }}</span></span>
+                    {% for to in show.topic.all %}
+                        <span title="{{ to.topic }}"
+                              class="abbrev to-{{ to.abbrev }}"><span>{{ to.abbrev }}</span></span>
                     {% endfor %}
                     {% for mf in show.musicfocus.all %}
                         <span title="{{ mf.focus }}"
@@ -39,9 +39,9 @@
                 </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.active_program_slots %}
-                            <li class="show-programslot">{{ programslot }}</li>
+                    <ul class="show-schedules">
+                        {% for schedule in show.active_schedules %}
+                            <li class="show-schedule">{{ schedule }}</li>
                         {% endfor %}
                     </ul>
                     <p class="show-description">{{ show.short_description }}</p>
@@ -53,4 +53,4 @@
 </div>
 
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/styles.css b/program/templates/styles.css
index fbad3e9c..e9b98eec 100644
--- a/program/templates/styles.css
+++ b/program/templates/styles.css
@@ -1,5 +1,5 @@
-{% for bf in broadcastformats %}
-.bf-{{ bf.slug }} { background-color: {{ bf.color }}; color: {{ bf.text_color }}; }
+{% for ty in types %}
+.ty-{{ ty.slug }} { background-color: {{ ty.color }}; color: {{ ty.text_color }}; }
 {% endfor %}
 
 {% for mf in musicfocus %}
@@ -7,26 +7,26 @@
 .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 }}); }
+{% for ca in category %}
+.ca-{{ ca.abbrev }} { background-image:url({{ ca.button_url }}); }
+.filterbox .ca-{{ ca.abbrev }}:hover { background-image:url({{ ca.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 }}); }
+{% for to in topic %}
+.to-{{ to.abbrev }} { background-image:url({{ to.button_url }}); }
+.filterbox .to-{{ to.abbrev }}:hover { background-image:url({{ to.button_hover_url }}); }
 {% endfor %}
 
 {% 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 }}); }
+{% for ca in category %}
+.show-detail-header .ca-{{ ca.abbrev }} { background-image:url({{ ca.big_button_url }}); }
 {% endfor %}
 
-{% for st in showtopic %}
-.show-detail-header .st-{{ st.abbrev }} { background-image:url({{ st.big_button_url }}); }
+{% for to in topic %}
+.show-detail-header .to-{{ to.abbrev }} { background-image:url({{ to.big_button_url }}); }
 {% endfor %}
 
 
diff --git a/program/templates/timeslot_detail.html b/program/templates/timeslot_detail.html
index 88749a23..5914548d 100644
--- a/program/templates/timeslot_detail.html
+++ b/program/templates/timeslot_detail.html
@@ -6,7 +6,7 @@
 
 <div id="content-main" class="timeslot-detail">
 
-    <div class="show-detail-header bf-{{ timeslot.show.broadcastformat.slug }}">
+    <div class="show-detail-header ty-{{ timeslot.show.type.slug }}">
         <h1 id="name">
             <a href="{% url "show-detail" timeslot.show.slug %}">{{ timeslot.show.name }}</a>
         </h1>
@@ -16,18 +16,18 @@
         <strong>Sendung am {{ timeslot.start|date:"d.m.Y 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>
+            {% for ca in timeslot.show.category.all %}
+                <span title="{{ ca.category }}" class="abbrev ca-{{ ca.abbrev }}"><span>{{ ca.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>
+            {% for to in timeslot.show.topic.all %}
+                <span title="{{ to.topic }}" class="abbrev to-{{ to.abbrev }}"><span>{{ to.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>
+        <p id="type">{{ timeslot.show.type.type }}</p>
     </div>
 
     {% if timeslot.note %}
@@ -54,4 +54,4 @@
 </div>
 
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/program/templates/week_schedule_timeslot.html b/program/templates/week_schedule_timeslot.html
index 8942327b..12abade9 100644
--- a/program/templates/week_schedule_timeslot.html
+++ b/program/templates/week_schedule_timeslot.html
@@ -1,54 +1,54 @@
 {% load timeslots %}
 
 {% 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 class="timeslot ty-{{ default_show.type.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 class="timeslot ty-{{ timeslot.show.type.slug }}" {% duration timeslot.start 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_until timeslot.end %}>
+    <div class="timeslot ty-{{ timeslot.show.type.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 class="timeslot ty-{{ timeslot.show.type.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 class="timeslot ty-{{ timeslot.show.type.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 %}
-        <div class="timeslot bf-{{ default_show.broadcastformat.slug }}" {% duration timeslot.end timeslot.get_next_by_start.start %}>
+        <div class="timeslot ty-{{ default_show.type.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 class="timeslot ty-{{ timeslot.show.type.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 class="timeslot ty-{{ timeslot.show.type.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 class="timeslot ty-{{ default_show.type.slug }}" {% duration_since timeslot.end %}>
         <div>{{ default_show.name }}</div>
     </div>
-{% endif %}
+{% endif %}
\ No newline at end of file
diff --git a/program/templatetags/content_boxes.py b/program/templatetags/content_boxes.py
index 2d1745ed..f45ebaee 100644
--- a/program/templatetags/content_boxes.py
+++ b/program/templatetags/content_boxes.py
@@ -1,13 +1,13 @@
 from django import template
 
-from program.models import BroadcastFormat, MusicFocus, ShowInformation, ShowTopic
+from program.models import Type, MusicFocus, Category, Topic
 
 register = template.Library()
 
 
-@register.inclusion_tag('boxes/broadcastformat.html')
-def broadcastformat():
-    return {'broadcastformat_list': BroadcastFormat.objects.filter(enabled=True)}
+@register.inclusion_tag('boxes/type.html')
+def type():
+    return {'type_list': Type.objects.filter(enabled=True)}
 
 
 @register.inclusion_tag('boxes/musicfocus.html')
@@ -15,11 +15,11 @@ def musicfocus():
     return {'musicfocus_list': MusicFocus.objects.all()}
 
 
-@register.inclusion_tag('boxes/showinformation.html')
-def showinformation():
-    return {'showinformation_list': ShowInformation.objects.all()}
+@register.inclusion_tag('boxes/category.html')
+def category():
+    return {'category_list': Category.objects.all()}
 
 
-@register.inclusion_tag('boxes/showtopic.html')
-def showtopic():
-    return {'showtopic_list': ShowTopic.objects.all()}
+@register.inclusion_tag('boxes/topic.html')
+def topic():
+    return {'topic_list': Topic.objects.all()}
\ No newline at end of file
diff --git a/program/views.py b/program/views.py
index 1028f785..8258d6bd 100644
--- a/program/views.py
+++ b/program/views.py
@@ -9,9 +9,8 @@ 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 pprint import pprint
 
-from .models import BroadcastFormat, MusicFocus, Note, Show, ShowInformation, ShowTopic, TimeSlot, Host
+from .models import Type, MusicFocus, Note, Show, Category, Topic, TimeSlot, Host
 
 from program.utils import tofirstdayinisoweek, get_cached_shows
 
@@ -22,7 +21,7 @@ class CalendarView(TemplateView):
 
 class HostListView(ListView):
     context_object_name = 'host_list'
-    queryset = Host.objects.filter(Q(is_always_visible=True) | Q(shows__programslots__until__gt=datetime.now())).distinct()
+    queryset = Host.objects.filter(Q(is_always_visible=True) | Q(shows__schedules__until__gt=datetime.now())).distinct()
     template_name = 'host_list.html'
 
 
@@ -37,19 +36,23 @@ class ShowListView(ListView):
     template_name = 'show_list.html'
 
     def get_queryset(self):
-        queryset = Show.objects.filter(programslots__until__gt=date.today()).exclude(id=1).distinct()
-        if 'broadcastformat' in self.request.GET:
-            broadcastformat = get_object_or_404(BroadcastFormat, slug=self.request.GET['broadcastformat'])
-            queryset = queryset.filter(broadcastformat=broadcastformat)
+        queryset = Show.objects.filter(schedules__until__gt=date.today()).exclude(id=1).distinct()
+        if 'type' in self.request.GET:
+            type = get_object_or_404(Type, slug=self.request.GET['type'])
+            queryset = queryset.filter(type=type)
         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)
+        elif 'category' in self.request.GET:
+            category = get_object_or_404(Category, slug=self.request.GET['category'])
+            queryset = queryset.filter(category=category)
+        elif 'topic' in self.request.GET:
+            topic = get_object_or_404(Topic, slug=self.request.GET['topic'])
+            queryset = queryset.filter(topic=topic)
+        elif 'rtrcategory' in self.request.GET:
+            rtrcategory = get_object_or_404(RTRCategory, slug=self.request.GET['rtrcategory'])
+            queryset = queryset.filter(rtrcategory=rtrcategory)
+
 
         return queryset
 
@@ -73,7 +76,7 @@ class RecommendationsListView(ListView):
 
     queryset = TimeSlot.objects.filter(Q(note__isnull=False, note__status=1,
                                          start__range=(now, end)) |
-                                       Q(show__broadcastformat__slug='sondersendung',
+                                       Q(show__type__slug='sondersendung',
                                          start__range=(now, end))).order_by('start')[:20]
 
 
@@ -103,18 +106,18 @@ class DayScheduleView(TemplateView):
 
         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)
+        if 'type' in self.request.GET:
+            type = get_object_or_404(Type, slug=self.request.GET['type'])
+            context['timeslots'] = timeslots.filter(show__type=type)
         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)
+        elif 'category' in self.request.GET:
+            category = get_object_or_404(Category, slug=self.request.GET['category'])
+            context['timeslots'] = timeslots.filter(show__category=category)
+        elif 'topic' in self.request.GET:
+            topic = get_object_or_404(Topic, slug=self.request.GET['topic'])
+            context['topic'] = timeslots.filter(show__topic=topic)
         else:
             context['timeslots'] = timeslots
         return context
@@ -187,10 +190,10 @@ class StylesView(TemplateView):
 
     def get_context_data(self, **kwargs):
         context = super(StylesView, self).get_context_data(**kwargs)
-        context['broadcastformats'] = BroadcastFormat.objects.filter(enabled=True)
+        context['types'] = Type.objects.filter(enabled=True)
         context['musicfocus'] = MusicFocus.objects.all()
-        context['showinformation'] = ShowInformation.objects.all()
-        context['showtopic'] = ShowTopic.objects.all()
+        context['category'] = Category.objects.all()
+        context['topic'] = Topic.objects.all()
         return context
 
 
@@ -200,7 +203,7 @@ def json_day_schedule(request, year=None, month=None, day=None):
     else:
         today = datetime.strptime('%s__%s__%s__00__00' % (year, month, day), '%Y__%m__%d__%H__%M')
 
-    timeslots = TimeSlot.objects.get_24h_timeslots(today).select_related('programslot').select_related('show')
+    timeslots = TimeSlot.objects.get_24h_timeslots(today).select_related('schedule').select_related('show')
     schedule = []
     for ts in timeslots:
         entry = {
@@ -211,8 +214,8 @@ def json_day_schedule(request, year=None, month=None, day=None):
             'automation-id': -1
         }
 
-        if ts.programslot.automation_id:
-            entry['automation-id'] = ts.programslot.automation_id
+        if ts.schedule.automation_id:
+            entry['automation-id'] = ts.schedule.automation_id
 
         schedule.append(entry)
 
@@ -233,12 +236,12 @@ def json_week_schedule(request):
     else:
         start = datetime.combine( datetime.strptime(request.GET.get('start'), '%Y-%m-%d').date(), time(0, 0))
 
-    timeslots = TimeSlot.objects.get_7d_timeslots(start).select_related('programslot').select_related('show')
+    timeslots = TimeSlot.objects.get_7d_timeslots(start).select_related('schedule').select_related('show')
     schedule = []
     for ts in timeslots:
 
         # TODO: Will be a field of timeslots in the future
-        is_repetition = ' (WH)' if ts.programslot.is_repetition == 1 else ''
+        is_repetition = ' (WH)' if ts.schedule.is_repetition == 1 else ''
 
         entry = {
             'start': ts.start.strftime('%Y-%m-%dT%H:%M:%S'),
@@ -248,8 +251,8 @@ def json_week_schedule(request):
             'automation-id': -1
         }
 
-        if ts.programslot.automation_id:
-            entry['automation-id'] = ts.programslot.automation_id
+        if ts.schedule.automation_id:
+            entry['automation-id'] = ts.schedule.automation_id
 
         schedule.append(entry)
 
@@ -266,8 +269,8 @@ def json_timeslots_specials(request):
             specials[show['id']] = show
 
     for ts in TimeSlot.objects.filter(end__gt=datetime.now(),
-                                      programslot__automation_id__in=specials.iterkeys()).select_related('show'):
-        automation_id = ts.programslot.automation_id
+                                      schedule__automation_id__in=specials.iterkeys()).select_related('show'):
+        automation_id = ts.schedule.automation_id
         start = ts.start.strftime('%Y-%m-%d_%H:%M:%S')
         end = ts.end.strftime('%Y-%m-%d_%H:%M:%S')
         if specials[automation_id]['pv_id'] != -1:
@@ -284,8 +287,8 @@ def json_timeslots_specials(request):
 
 
 def json_get_timeslot(request):
-   if request.method == 'GET':
-      try:
-         return JsonResponse( model_to_dict(TimeSlot.objects.select_related('programslot').select_related('show').get(pk=int(request.GET.get('timeslot_id')))))
-      except ObjectDoesNotExist:
-         return JsonResponse( list('Error') );
\ No newline at end of file
+    if request.method == 'GET':
+        try:
+            return JsonResponse( model_to_dict(TimeSlot.objects.select_related('schedule').select_related('show').get(pk=int(request.GET.get('timeslot_id')))))
+        except ObjectDoesNotExist:
+            return JsonResponse( list('Error') );
\ No newline at end of file
-- 
GitLab