From a1d4a0f73a5490da1d850af59651ff44248f73af Mon Sep 17 00:00:00 2001
From: Julian Rother <julianr@fsmpi.rwth-aachen.de>
Date: Mon, 5 Sep 2016 00:24:09 +0200
Subject: [PATCH] Rename endpoints for better comprehensibility

---
 feeds.py                                      |  4 +-
 server.py                                     | 30 ++++----
 templates/{log.html => changelog.html}        |  0
 templates/course.html                         | 73 +++++++++----------
 templates/course_id.html                      | 42 -----------
 templates/courses.html                        | 43 +++++++++++
 .../{feed_courses.atom => courses_feed.atom}  |  4 +-
 templates/feed.atom                           | 10 +--
 templates/import_campus.html                  |  2 +-
 templates/{play.html => lecture.html}         |  2 +-
 templates/macros.html                         |  8 +-
 templates/schedule.html                       |  2 +-
 12 files changed, 110 insertions(+), 110 deletions(-)
 rename templates/{log.html => changelog.html} (100%)
 delete mode 100644 templates/course_id.html
 create mode 100644 templates/courses.html
 rename templates/{feed_courses.atom => courses_feed.atom} (86%)
 rename templates/{play.html => lecture.html} (87%)

diff --git a/feeds.py b/feeds.py
index d4c5976..52aec62 100644
--- a/feeds.py
+++ b/feeds.py
@@ -44,7 +44,7 @@ def feed(handle=None):
 	return Response(render_template('feed.atom', course=course, entries=entries), 200, {'Content-Type': 'application/atom+xml'})
 
 @app.route('/course/feed')
-def feed_courses():
+def courses_feed():
 	courses = query('SELECT * FROM courses WHERE visible AND listed ORDER BY time_created DESC LIMIT 100')
 	atomid = gen_atomid('Video AG, courses')
 	updated = None
@@ -52,4 +52,4 @@ def feed_courses():
 		course['updated'] = max(course['time_created'], course['time_updated'], key=fixdate)
 		course['atomid'] = gen_atomid('Video AG, courses['+str(course['id'])+']: '+course['handle'])
 		updated = max(updated, course['updated'], key=fixdate)
-	return Response(render_template('feed_courses.atom', updated=updated, atomid=atomid, courses=courses), 200, {'Content-Type': 'application/atom+xml'})
+	return Response(render_template('courses_feed.atom', updated=updated, atomid=atomid, courses=courses), 200, {'Content-Type': 'application/atom+xml'})
diff --git a/server.py b/server.py
index 26a90ed..947b896 100755
--- a/server.py
+++ b/server.py
@@ -131,7 +131,7 @@ def index():
 
 @app.route('/course')
 @register_navbar('Videos', icon='film')
-def course():
+def courses():
 	courses = query('SELECT * FROM courses WHERE (? OR (visible AND listed))', ismod())
 	for course in courses:
 		if course['semester'] == '':
@@ -139,16 +139,16 @@ def course():
 	groupedby = request.args.get('groupedby')
 	if groupedby not in ['title', 'semester', 'organizer']:
 		groupedby = 'semester'
-	return render_template('course.html', courses=courses, groupedby=groupedby)
+	return render_template('courses.html', courses=courses, groupedby=groupedby)
 
-@app.route('/course/<id>')
-@app.route('/course/<int:numid>')
+@app.route('/course/<handle>')
+@app.route('/course/<int:id>')
 @handle_errors('course', 'Diese Veranstaltung existiert nicht!', 404, IndexError)
-def course_id(numid=None, id=None):
-	if numid:
-		courses = query('SELECT * FROM courses WHERE id = ? AND (? OR visible)', numid, ismod())[0]
+def course(id=None, handle=None):
+	if id:
+		courses = query('SELECT * FROM courses WHERE id = ? AND (? OR visible)', id, ismod())[0]
 	else:
-		courses = query('SELECT * FROM courses WHERE handle = ? AND (? OR visible)', id, ismod())[0]
+		courses = query('SELECT * FROM courses WHERE handle = ? AND (? OR visible)', handle, ismod())[0]
 	lectures = query('SELECT * FROM lectures WHERE course_id = ? AND (? OR visible)', courses['id'], ismod())
 	videos = query('''
 			SELECT videos.*, (videos.downloadable AND courses.downloadable) as downloadable, formats.description AS format_description
@@ -159,7 +159,7 @@ def course_id(numid=None, id=None):
 			WHERE lectures.course_id= ? AND (? OR videos.visible)
 			ORDER BY lectures.time, formats.prio DESC
 			''', courses['id'], ismod())
-	return render_template('course_id.html', course=courses, lectures=lectures, videos=videos)
+	return render_template('course.html', course=courses, lectures=lectures, videos=videos)
 
 @app.route('/faq')
 @register_navbar('FAQ', icon='question-sign')
@@ -168,7 +168,7 @@ def faq():
 
 @app.route('/play/<int:id>')
 @handle_errors('course', 'Diese Vorlesung existiert nicht!', 404, IndexError)
-def play(id):
+def lecture(id):
 	lectures = query('SELECT * FROM lectures WHERE id = ? AND (? OR visible)', id, ismod())
 	videos = query('SELECT videos.*, formats.description AS format_description FROM videos JOIN formats ON (videos.video_format = formats.id) WHERE lecture_id = ? AND (? OR visible)', id, ismod())
 	if not videos:
@@ -176,7 +176,7 @@ def play(id):
 	courses = query('SELECT * FROM courses WHERE id = ? AND (? OR (visible AND listed))', lectures[0]['course_id'], ismod())
 	if not courses:
 		return render_endpoint('course', 'Diese Veranstaltung existiert nicht!'), 404
-	return render_template('play.html', course=courses[0], lecture=lectures[0], videos=videos)
+	return render_template('lecture.html', course=courses[0], lecture=lectures[0], videos=videos)
 
 @app.route('/search')
 def search():
@@ -246,7 +246,7 @@ def edit(prefix="", ignore=[]):
 
 @app.route('/newcourse', methods=['GET', 'POST'])
 @mod_required
-def newcourse():
+def new_course():
 	id = query('''
 		INSERT INTO courses_data
 			(visible, title, short, handle, organizer, subject, created_by, time_created,
@@ -261,7 +261,7 @@ def newcourse():
 
 @app.route('/newlecture/<courseid>', methods=['GET', 'POST'])
 @mod_required
-def newlecture(courseid):
+def new_lecture(courseid):
 	id = query('''
 		INSERT INTO lectures_data
 			(course_id, visible, drehplan, title, comment, internal, speaker, place,
@@ -380,9 +380,9 @@ def stats():
 @app.route('/log')
 @register_navbar('Changelog', 'book')
 @mod_required
-def log():
+def changelog():
 	changelog = query('SELECT *, ( "table" || "." || id_value || "." ||field) as path FROM changelog LEFT JOIN users ON (changelog.who = users.id) ORDER BY "when" DESC LIMIT 50')
-	return render_template('log.html', changelog=changelog)
+	return render_template('changelog.html', changelog=changelog)
 
 @app.route('/files/<filename>')
 def files(filename):
diff --git a/templates/log.html b/templates/changelog.html
similarity index 100%
rename from templates/log.html
rename to templates/changelog.html
diff --git a/templates/course.html b/templates/course.html
index 00adb52..6417296 100644
--- a/templates/course.html
+++ b/templates/course.html
@@ -1,43 +1,42 @@
-{% from 'macros.html' import course_list_item %}
+{% from 'macros.html' import lecture_list_item %}
+{% from 'macros.html' import valueeditor %}
+{% from 'macros.html' import valuecheckbox %}
+{% from 'macros.html' import preview %}
 {% extends "base.html" %}
 {% block content %}
-<div class="row">
-	<div class="col-xs-12 dropdown" style="margin-bottom: 10px;">
-		<span class="pull-right">
-			 <a class="fa fa-rss-square pull-right btn btn-default" aria-hidden="true" href="{{url_for('feed_courses')}}"></a>
-			{% if ismod() %} <a class="btn btn-default" style="margin-right: 5px;" href="{{ url_for('newcourse', ref=request.url) }}">Neue Veranstaltung</a> {% endif %}
-		
-		<button class="btn btn-primary dropdown-toggle pull-right" type="button" data-toggle="dropdown">Gruppierung
-		<span class="caret"></span></button>
-		<ul class="dropdown-menu dropdown-menu-right">
-			<li><a href="?groupedby=semester">Semester</a></li>
-			<li><a href="?groupedby=title">Veranstaltungen</a></li>
-			<li><a href="?groupedby=organizer">Dozenten</a></li>
-		</ul>
-		</span>
+<div class="panel panel-default">
+	<div class="panel-heading">
+		<h1 class="panel-title">{{ valueeditor(['courses',course.id,'title'], course.title)}}</h1>
 	</div>
-</div>
-{% for g in courses|groupby(groupedby)|reverse %}
-<div class="row panel-group">
-	<div class="col-xs-12"><div class="panel panel-default">
-		<div class="panel-heading">
-			{% if groupedby == 'semester' %}
-			<h1 class="panel-title">{{g.grouper|semester(long=True)}}</h1>
-			{% else %}
-			<h1 class="panel-title">{{g.grouper}}</h1>
-			{% endif %}
+	<div class="row panel-body">
+		<div class="col-xs-12">
+			<table class="table-condensed">
+				<tbody>
+					<tr><td>Semester:</td><td>{{ valueeditor(['courses',course.id,'semester'], course.semester) }}</td></tr>
+					<tr><td>Veranstalter:</td><td>{{ valueeditor(['courses',course.id,'organizer'], course.organizer) }}</td></tr>
+					<tr><td>Bemerkungen:</td><td>{{ valueeditor(['courses',course.id,'description'], course.description) }}</td></tr>
+					{% if ismod() %}
+					<tr><td>Sichtbar:</td><td>{{ valuecheckbox(['courses',course.id,'visible'], course.visible) }}</td></tr>
+					<tr><td>Gelistet:</td><td>{{ valuecheckbox(['courses',course.id,'listed'], course.listed) }}</td></tr>
+					<tr><td>Short:</td><td>{{ valueeditor(['courses',course.id,'short'], course.short) }}</td></tr>
+					<tr><td>Handle:</td><td>{{ valueeditor(['courses',course.id,'handle'], course.handle) }}</td></tr>
+					<tr><td>Downloadable:</td><td>{{ valuecheckbox(['courses',course.id,'downloadable'], course.downloadable) }}</td></tr>
+					<tr><td>Thema:</td><td>{{ valueeditor(['courses',course.id,'subject'], course.subject) }}</td></tr>
+					<tr><td>Zuständig:</td><td>{{ valueeditor(['courses',course.id,'responsible'], course.responsible) }}</td></tr>
+					{% endif %}
+				</tbody>
+			</table>
 		</div>
-		<ul class="{% if not ismod() %}courses-list {% endif %}list-group">
-			{% for i in g.list %}
-				{% if groupedby == 'semester' %}
-					{{ course_list_item(i) }}
-				{% else %}
-					{{ course_list_item(i,true) }}
-				{% endif %}
-			{% endfor %}
-		</ul>
-	</div></div>
+	</div>
+</div>
+<div class="panel panel-default">
+	<div class="panel-heading">
+		<h1 class="panel-title">Videos{% if ismod() %} <a class="btn btn-default" style="margin-right: 5px;" href="{{ url_for('new_lecture', courseid=course.id, ref=request.url) }}">Neuer Termin</a><a class="btn btn-default" style="margin-right: 5px;" href="{{url_for('import_from', id=course['id'])}}">Campus Import</a>{% endif %} <a class="fa fa-rss-square pull-right" aria-hidden="true" href="{{url_for('feed', handle=course.handle)}}"></a> </h1>
+	</div>
+	<ul class="list-group lectureslist">
+		{% for l in lectures %}
+			{{ lecture_list_item(l,videos|selectattr('lecture_id','equalto',l.id)|list) }}
+		{% endfor %}
+	</ul>
 </div>
-{% endfor %}
-
 {% endblock %}
diff --git a/templates/course_id.html b/templates/course_id.html
deleted file mode 100644
index bfc0153..0000000
--- a/templates/course_id.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% from 'macros.html' import lecture_list_item %}
-{% from 'macros.html' import valueeditor %}
-{% from 'macros.html' import valuecheckbox %}
-{% from 'macros.html' import preview %}
-{% extends "base.html" %}
-{% block content %}
-<div class="panel panel-default">
-	<div class="panel-heading">
-		<h1 class="panel-title">{{ valueeditor(['courses',course.id,'title'], course.title)}}</h1>
-	</div>
-	<div class="row panel-body">
-		<div class="col-xs-12">
-			<table class="table-condensed">
-				<tbody>
-					<tr><td>Semester:</td><td>{{ valueeditor(['courses',course.id,'semester'], course.semester) }}</td></tr>
-					<tr><td>Veranstalter:</td><td>{{ valueeditor(['courses',course.id,'organizer'], course.organizer) }}</td></tr>
-					<tr><td>Bemerkungen:</td><td>{{ valueeditor(['courses',course.id,'description'], course.description) }}</td></tr>
-					{% if ismod() %}
-					<tr><td>Sichtbar:</td><td>{{ valuecheckbox(['courses',course.id,'visible'], course.visible) }}</td></tr>
-					<tr><td>Gelistet:</td><td>{{ valuecheckbox(['courses',course.id,'listed'], course.listed) }}</td></tr>
-					<tr><td>Short:</td><td>{{ valueeditor(['courses',course.id,'short'], course.short) }}</td></tr>
-					<tr><td>Handle:</td><td>{{ valueeditor(['courses',course.id,'handle'], course.handle) }}</td></tr>
-					<tr><td>Downloadable:</td><td>{{ valuecheckbox(['courses',course.id,'downloadable'], course.downloadable) }}</td></tr>
-					<tr><td>Thema:</td><td>{{ valueeditor(['courses',course.id,'subject'], course.subject) }}</td></tr>
-					<tr><td>Zuständig:</td><td>{{ valueeditor(['courses',course.id,'responsible'], course.responsible) }}</td></tr>
-					{% endif %}
-				</tbody>
-			</table>
-		</div>
-	</div>
-</div>
-<div class="panel panel-default">
-	<div class="panel-heading">
-		<h1 class="panel-title">Videos{% if ismod() %} <a class="btn btn-default" style="margin-right: 5px;" href="{{ url_for('newlecture', courseid=course.id, ref=request.url) }}">Neuer Termin</a><a class="btn btn-default" style="margin-right: 5px;" href="{{url_for('import_from', id=course['id'])}}">Campus Import</a>{% endif %} <a class="fa fa-rss-square pull-right" aria-hidden="true" href="{{url_for('feed', handle=course.handle)}}"></a> </h1>
-	</div>
-	<ul class="list-group lectureslist">
-		{% for l in lectures %}
-			{{ lecture_list_item(l,videos|selectattr('lecture_id','equalto',l.id)|list) }}
-		{% endfor %}
-	</ul>
-</div>
-{% endblock %}
diff --git a/templates/courses.html b/templates/courses.html
new file mode 100644
index 0000000..39958dc
--- /dev/null
+++ b/templates/courses.html
@@ -0,0 +1,43 @@
+{% from 'macros.html' import course_list_item %}
+{% extends "base.html" %}
+{% block content %}
+<div class="row">
+	<div class="col-xs-12 dropdown" style="margin-bottom: 10px;">
+		<span class="pull-right">
+			 <a class="fa fa-rss-square pull-right btn btn-default" aria-hidden="true" href="{{url_for('courses_feed')}}"></a>
+			{% if ismod() %} <a class="btn btn-default" style="margin-right: 5px;" href="{{ url_for('new_course', ref=request.url) }}">Neue Veranstaltung</a> {% endif %}
+		
+		<button class="btn btn-primary dropdown-toggle pull-right" type="button" data-toggle="dropdown">Gruppierung
+		<span class="caret"></span></button>
+		<ul class="dropdown-menu dropdown-menu-right">
+			<li><a href="?groupedby=semester">Semester</a></li>
+			<li><a href="?groupedby=title">Veranstaltungen</a></li>
+			<li><a href="?groupedby=organizer">Dozenten</a></li>
+		</ul>
+		</span>
+	</div>
+</div>
+{% for g in courses|groupby(groupedby)|reverse %}
+<div class="row panel-group">
+	<div class="col-xs-12"><div class="panel panel-default">
+		<div class="panel-heading">
+			{% if groupedby == 'semester' %}
+			<h1 class="panel-title">{{g.grouper|semester(long=True)}}</h1>
+			{% else %}
+			<h1 class="panel-title">{{g.grouper}}</h1>
+			{% endif %}
+		</div>
+		<ul class="{% if not ismod() %}courses-list {% endif %}list-group">
+			{% for i in g.list %}
+				{% if groupedby == 'semester' %}
+					{{ course_list_item(i) }}
+				{% else %}
+					{{ course_list_item(i,true) }}
+				{% endif %}
+			{% endfor %}
+		</ul>
+	</div></div>
+</div>
+{% endfor %}
+
+{% endblock %}
diff --git a/templates/feed_courses.atom b/templates/courses_feed.atom
similarity index 86%
rename from templates/feed_courses.atom
rename to templates/courses_feed.atom
index 69e4e88..1e63708 100644
--- a/templates/feed_courses.atom
+++ b/templates/courses_feed.atom
@@ -13,7 +13,7 @@ Veranstalter: {{ course.organizer }}<br>
 		<name>Video AG, FSMPI, RWTH Aachen</name>
 		<email>video@fsmpi.rwth-aachen.de</email>
 	</author>
-	<link rel="alternate" href="{{ url_for('course', _external=True) }}"/>
+	<link rel="alternate" href="{{ url_for('courses', _external=True) }}"/>
 	<link rel="self" href="{{ request.url }}"/>
 	<icon>{{ url_for('static', filename='favicon.png', _external=True) }}</icon>
 	<logo>https://videoag.fsmpi.rwth-aachen.de/site/video-logo-150px.png</logo>
@@ -29,7 +29,7 @@ Veranstalter: {{ course.organizer }}<br>
 			<name>{{ course.organizer|e }}</name>
 		</author>
 		{% endif %}
-		<link rel="alternate" href="{{ url_for('course_id', id=course.handle, _external=True) }}"/>
+		<link rel="alternate" href="{{ url_for('course', handle=course.handle, _external=True) }}"/>
 		<link rel="alternate" href="{{ url_for('feed', handle=course.handle, _external=True) }}" type="application/atom+xml" title="Feed"/>
 		<summary type="html">{{ summary(course)|e }}</summary>
 	</entry>
diff --git a/templates/feed.atom b/templates/feed.atom
index 1464775..8bd9ce8 100644
--- a/templates/feed.atom
+++ b/templates/feed.atom
@@ -1,6 +1,6 @@
 {% macro summary(entry) %}
 	{% if not course.handle %}
-Veranstaltung: <a href="{{ url_for('course_id', id=entry.course_handle) }}">{{entry.course_title}}</a><br>
+Veranstaltung: <a href="{{ url_for('course', handle=entry.course_handle) }}">{{entry.course_title}}</a><br>
 		{% if entry.course_organizer %}
 Veranstalter: {{ entry.course_organizer }}<br>
 		{% endif %}
@@ -11,7 +11,7 @@ Gehalten von {{ entry.speaker }}<br>
 {{ entry.comment }}
 {% endmacro %}
 {% macro subtitle() %}
-Veranstaltung: <a href="{{ url_for('course_id', id=course.handle) }}">{{course.title}}</a><br>
+Veranstaltung: <a href="{{ url_for('course', handle=course.handle) }}">{{course.title}}</a><br>
 	{% if course.organizer %}
 Veranstalter: {{ course.organizer }}<br>
 	{% endif %}
@@ -26,9 +26,9 @@ Veranstalter: {{ course.organizer }}<br>
 		<email>video@fsmpi.rwth-aachen.de</email>
 	</author>
 	{% if not course.handle %}
-	<link rel="alternate" href="{{ url_for('course', _external=True) }}" />
+	<link rel="alternate" href="{{ url_for('courses', _external=True) }}" />
 	{% else %}
-	<link rel="alternate" href="{{ url_for('course_id', id=course.handle, _external=True) }}" />
+	<link rel="alternate" href="{{ url_for('course', handle=course.handle, _external=True) }}" />
 	{% endif %}
 	<link rel="self" href="{{ request.url }}" />
 	<icon>{{ url_for('static', filename='favicon.png', _external=True) }}</icon>
@@ -53,7 +53,7 @@ Veranstalter: {{ course.organizer }}<br>
 			<name>{{ entry.speaker }}</name>
 		</author>
 		{% endif %}
-		<link rel="alternate" href="{{ url_for('play', id=entry.id, _external=True) }}"/>
+		<link rel="alternate" href="{{ url_for('lecture', id=entry.id, _external=True) }}"/>
 		<link rel="enclosure" href="{{ url_for('files', filename=entry.path, _external=True)}}" length="{{ entry.file_size }}"/>
 		<id>{{ entry.atomid }}</id>
 		<updated>{{ entry.updated|rfc3339 }}</updated>
diff --git a/templates/import_campus.html b/templates/import_campus.html
index 6471f47..cb727be 100644
--- a/templates/import_campus.html
+++ b/templates/import_campus.html
@@ -4,7 +4,7 @@
 <div class="panel-group">
 	<div class="panel panel-default">
 		<div class="panel-heading">
-			<h1 class="panel-title">Campus Import für <strong>{{course.title}}</strong> <span><a href="{{url_for('course_id', numid=course.id)}}" class="btn btn-default" >Zur Veranstaltungsseite</a><span> </h1>
+			<h1 class="panel-title">Campus Import für <strong>{{course.title}}</strong> <span><a href="{{url_for('course', handle=course.handle)}}" class="btn btn-default" >Zur Veranstaltungsseite</a><span> </h1>
 		</div>
 		<div class="panel-body">
 			<div>
diff --git a/templates/play.html b/templates/lecture.html
similarity index 87%
rename from templates/play.html
rename to templates/lecture.html
index 50951de..1e84d59 100644
--- a/templates/play.html
+++ b/templates/lecture.html
@@ -13,7 +13,7 @@
 		<div class="row" style="padding: 0px;">
 			<div class="col-sm-6 col-xs-12" style="padding-bottom: 5px;">
 				<span>
-					<a href="{{url_for('course_id', numid=course.id)}}#lecture-{{lecture.id}}" class="btn btn-default" >Zur Veranstaltungsseite</a>
+					<a href="{{url_for('course', handle=course.handle)}}#lecture-{{lecture.id}}" class="btn btn-default" >Zur Veranstaltungsseite</a>
 				<span>
 			</div>
 			<div class="col-sm-6 col-xs-12">
diff --git a/templates/macros.html b/templates/macros.html
index b7ce893..4c7a73e 100644
--- a/templates/macros.html
+++ b/templates/macros.html
@@ -1,6 +1,6 @@
 {% macro preview(lecture) %}
 <li class="list-group-item">
-	<a class="hidden-xs" href="{{url_for('play', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}">
+	<a class="hidden-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}">
 		<div class="row">
 			<img class="col-xs-4" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild">
 			<div class="col-xs-4">
@@ -16,7 +16,7 @@
 			</div>
 		</div>
 	</a>
-	<a class="visible-xs" href="{{url_for('play', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}">
+	<a class="visible-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}">
 		<div class="row">
 			<img class="col-xs-12" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild">
 		</div>
@@ -72,7 +72,7 @@
 {% macro course_list_item(course,show_semester=False) %}
 <li class="list-group-item {% if (not course.visible) or (not course.listed) %}list-group-item-danger{% endif %}">
 	<div class="row">
-		<a href="{{url_for('course_id', numid=course.id)}}">
+		<a href="{{url_for('course', handle=course.handle)}}">
 			{% if show_semester %}
 				<span class="col-xs-1">
 					{{ course.semester }}
@@ -157,7 +157,7 @@ $('#embedcodebtn').popover(
 				<span>
 					{{ video_download_btn(videos) }}
 				</span>
-				<a href="{{url_for('play', id=lecture.id)}}" class="btn btn-default {% if videos|length is equalto 0 %}disabled{% endif %}">
+				<a href="{{url_for('lecture', id=lecture.id)}}" class="btn btn-default {% if videos|length is equalto 0 %}disabled{% endif %}">
 					<span class="glyphicon glyphicon-play"></span>
 					Play
 				</a>
diff --git a/templates/schedule.html b/templates/schedule.html
index 8a6a883..f666ac6 100644
--- a/templates/schedule.html
+++ b/templates/schedule.html
@@ -24,7 +24,7 @@
 						{% for l in d.lectures|selectattr('schedule_col','equalto',i) if (((l.time.time() > t) and (l.time.time() < times[time_loop.index+1])) != (l.time.time() == t ) ) %}
 						<td rowspan="{{l.duration / 15}}" style="background: lightgrey;">
 							<p class="small">
-							<strong><a href="{{url_for('course_id', numid=l['course_id'])}}#lecture-{{l.id}}">{{l.short}}</a></strong><br>
+							<strong><a href="{{url_for('course', handle=l.handle)}}#lecture-{{l.id}}">{{l.short}}</a></strong><br>
 								{{l.time.strftime("%H:%M")}} - {{l.time_end.strftime("%H:%M")}}<br>
 								{{l.place}}</p>
 						</td>
-- 
GitLab