diff --git a/schedule.py b/schedule.py
new file mode 100755
index 0000000000000000000000000000000000000000..93f511f082b075aee34bb25ea4c9296557b49a84
--- /dev/null
+++ b/schedule.py
@@ -0,0 +1,57 @@
+from server import *
+
+@app.route('/schedule')
+@register_navbar('Drehplan', 'calendar')
+@mod_required
+def schedule():
+	if 'kw' not in request.args:
+		kw=0
+	else:
+		kw=int(request.args['kw'])
+	start = date.today() - timedelta(days=date.today().weekday() -7*kw)
+	days = [{'date': start, 'lectures': [], 'atonce':0, 'index': 0 }]
+	earlieststart=time(23,59)
+	latestend=time(0,0)
+	for i in range(1,7):
+		days.append({'date': days[i-1]['date'] + timedelta(days=1), 'atonce':0, 'index': i, 'lectures':[] })
+	for i in days:
+		# date and times are burning in sqlite
+		s = datetime.combine(i['date'],time())
+		e = datetime.combine(i['date'],time(23,59))
+		i['lectures'] = query ('''
+					SELECT lectures.*,courses.short
+					FROM lectures 
+					JOIN courses ON (lectures.course_id = courses.id) 
+					WHERE (time < ?) AND (time > ?) 
+					ORDER BY time ASC'''
+				,e,s);
+		# sweepline to find out how many lectures overlap
+		maxcol=0;
+		curcol=0;
+		freecol=[];
+		for l in i['lectures']:
+			# who the hell inserts lectures with zero length?!?!?
+			l['time_end'] = l['time']+timedelta(minutes=max(l['duration'],1))
+		for l in sorted([(l['time'],True,l) for l in i['lectures']] + [(l['time_end'],False,l) for l in i['lectures']],key=lambda t:(t[0],t[1])):
+			if l[1]:
+				curcol += 1
+				if curcol > maxcol:
+					maxcol = curcol
+				if len(freecol) == 0:
+					freecol.append(maxcol)
+				l[2]['schedule_col'] = freecol.pop()
+				if earlieststart > l[0].time():
+					earlieststart = l[0].time()
+			else:
+				curcol -= 1
+				freecol.append(l[2]['schedule_col'])
+				if latestend < l[0].time():
+					latestend = l[0].time()
+		i['maxcol'] = max(maxcol,1)
+	times=[]
+	s = min(earlieststart,time(8,0))
+	e = max(latestend,time(19,0))
+	for i in range(s.hour*4,min(int((60*e.hour/15)/4)*4+5,24*4)):
+		t = i*15
+		times.append(time(int(t/60),t%60))
+	return render_template('schedule.html',days=days,times=times,kw=kw)
diff --git a/server.py b/server.py
index 8c7a23e602f4a09bb972bed64fd84f4bc5ce1cd0..fe6bae47bb582d8cb95cfa4f57f7be0e6331025b 100755
--- a/server.py
+++ b/server.py
@@ -317,62 +317,6 @@ def auth(): # For use with nginx auth_request
 		return Response("Login required", 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})
 	return "Not allowed", 403
 
-@app.route('/schedule')
-@register_navbar('Drehplan', 'calendar')
-@mod_required
-def schedule():
-	if 'kw' not in request.args:
-		kw=0
-	else:
-		kw=int(request.args['kw'])
-	start = date.today() - timedelta(days=date.today().weekday() -7*kw)
-	days = [{'date': start, 'lectures': [], 'atonce':0, 'index': 0 }]
-	earlieststart=time(23,59)
-	latestend=time(0,0)
-	for i in range(1,7):
-		days.append({'date': days[i-1]['date'] + timedelta(days=1), 'atonce':0, 'index': i, 'lectures':[] })
-	for i in days:
-		# date and times are burning in sqlite
-		s = datetime.combine(i['date'],time())
-		e = datetime.combine(i['date'],time(23,59))
-		i['lectures'] = query ('''
-					SELECT lectures.*,courses.short
-					FROM lectures 
-					JOIN courses ON (lectures.course_id = courses.id) 
-					WHERE (time < ?) AND (time > ?) 
-					ORDER BY time ASC'''
-				,e,s);
-		# sweepline to find out how many lectures overlap
-		maxcol=0;
-		curcol=0;
-		freecol=[];
-		for l in i['lectures']:
-			# who the hell inserts lectures with zero length?!?!?
-			l['time_end'] = l['time']+timedelta(minutes=max(l['duration'],1))
-		for l in sorted([(l['time'],True,l) for l in i['lectures']] + [(l['time_end'],False,l) for l in i['lectures']],key=lambda t:(t[0],t[1])):
-			if l[1]:
-				curcol += 1
-				if curcol > maxcol:
-					maxcol = curcol
-				if len(freecol) == 0:
-					freecol.append(maxcol)
-				l[2]['schedule_col'] = freecol.pop()
-				if earlieststart > l[0].time():
-					earlieststart = l[0].time()
-			else:
-				curcol -= 1
-				freecol.append(l[2]['schedule_col'])
-				if latestend < l[0].time():
-					latestend = l[0].time()
-		i['maxcol'] = max(maxcol,1)
-	times=[]
-	s = min(earlieststart,time(8,0))
-	e = max(latestend,time(19,0))
-	for i in range(s.hour*4,min(int((60*e.hour/15)/4)*4+5,24*4)):
-		t = i*15
-		times.append(time(int(t/60),t%60))
-	return render_template('schedule.html',days=days,times=times,kw=kw)
-
 @app.route('/stats')
 @register_navbar('Statistiken', 'stats')
 @mod_required
@@ -407,3 +351,4 @@ def suggest_chapter(lectureid):
 
 import feeds
 import importer
+import schedule