diff --git a/db_schema.sql b/db_schema.sql
index 484b008c0ce965251d3ac4fa55db0e9291e0f84d..e39e0096c00e754088552eaa23c0f76ffbfc62cd 100644
--- a/db_schema.sql
+++ b/db_schema.sql
@@ -99,6 +99,15 @@ CREATE TABLE IF NOT EXISTS `site_texts` (
   `modified_when` datetime NOT NULL,
   `modified_by` text NOT NULL
 );
+CREATE TABLE IF NOT EXISTS `log` (
+	`ip` varchar(64),
+	`id` varchar(64),
+	`time` datetime NOT NULL,
+	`object` varchar(10),
+	`obj_id` INTEGER,
+	`path` varchar(255) NOT NULL,
+	PRIMARY KEY (ip, id, time, path)
+);
 CREATE TABLE IF NOT EXISTS `streams` (
   `handle` varchar(32) NOT NULL PRIMARY KEY,
   `active` INTEGER NOT NULL,
diff --git a/server.py b/server.py
index 99a53dfb7a5cefb942ab972a2ae0b9538c76376d..024e1b08566db91d44bc60ac8e3ed762297ced81 100755
--- a/server.py
+++ b/server.py
@@ -2,6 +2,7 @@
 
 from flask import *
 from functools import wraps
+import datetime
 import sqlite3
 import os
 import re
@@ -55,6 +56,7 @@ def query(operation, *params):
 		if 'db' not in g:
 			g.db = sqlite3.connect(config['SQLITE_DB'])
 			g.db.row_factory = dict_factory
+			g.db.isolation_level = None
 		if not hasattr(request, 'db'):
 			request.db = g.db.cursor()
 		request.db.execute(operation, params)
@@ -62,6 +64,12 @@ def query(operation, *params):
 		return []
 	return request.db.fetchall()
 
+@app.teardown_request
+def commit_db(*args):
+	if hasattr(request, 'db'):
+		request.db.close()
+		g.db.commit()
+
 def searchquery(text, columns, match, tables, suffix, *suffixparams):
 	params = []
 	subexprs = []
@@ -235,7 +243,7 @@ def edit():
 	tabs = {
 		'courses': ('courses_data', 'id', ['visible', 'listed', 'title', 'short',
 				'handle', 'organizer', 'subject', 'credits', 'semester', 'downloadable',
-				'internal', 'responsible']),
+				'internal', 'responsible', 'description']),
 		'lectures': ('lectures_data', 'id', ['visible', 'title', 'comment',
 				'internal', 'speaker', 'place', 'time', 'duration', 'jumplist',
 				'titlefile']),
@@ -262,16 +270,18 @@ def auth(): # For use with nginx auth_request
 	if 'X-Original-Uri' not in request.headers:
 		return 'Internal Server Error', 500
 	url = request.headers['X-Original-Uri'].lstrip(config['VIDEOPREFIX'])
-	videos = query('''SELECT videos.path
+	ip = request.headers.get('X-Real-IP', '')
+	videos = query('''SELECT videos.path, videos.id
 			FROM videos
 			JOIN lectures ON (videos.lecture_id = lectures.id)
 			JOIN courses ON (lectures.course_id = courses.id)
 			WHERE videos.path = ?
 			AND (? OR (courses.visible AND lectures.visible AND videos.visible))''',
 			url, ismod())
-	if videos and url.startswith('pub'):
+	if videos and (url.startswith('pub') or ismod()):
+		query('INSERT INTO log VALUES (?, "", ?, "video", ?, ?)', ip, datetime.datetime.now(), videos[0]['id'], url)
 		return "OK", 200
-	elif videos and ismod():
+	elif url.endswith('jpg'):
 		return "OK", 200
 	else:
 		return "Not allowed", 403