Skip to content
Snippets Groups Projects
Commit aced3754 authored by Andreas Valder's avatar Andreas Valder Committed by Andreas Valder
Browse files

Merge branch 'master' of git.fsmpi.rwth-aachen.de:videoagwebsite/videoagwebsite

parents 9fa646eb 0f2a3cb3
No related branches found
No related tags found
No related merge requests found
from server import * from server import *
import sqlite3
import re import re
if config['DB_ENGINE'] == 'sqlite': if config['DB_ENGINE'] == 'sqlite':
created = not os.path.exists(config['SQLITE_DB']) import sqlite3
db = sqlite3.connect(config['SQLITE_DB'])
cur = db.cursor()
if config['SQLITE_INIT_SCHEMA']:
cur.executescript(open(config['DB_SCHEMA']).read())
if config['SQLITE_INIT_DATA'] and created:
cur.executescript(open(config['DB_DATA']).read())
db.commit()
db.close()
# Row wrapper for sqlite
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
if type(row[idx]) == str:
d[col[0].split('.')[-1]] = row[idx].replace('\\n','\n').replace('\\r','\r')
else:
d[col[0].split('.')[-1]] = row[idx]
return d
# From sqlite3 module, but with error catching # From sqlite3 module, but with error catching
def convert_timestamp(val): def convert_timestamp(val):
...@@ -38,37 +19,68 @@ def convert_timestamp(val): ...@@ -38,37 +19,68 @@ def convert_timestamp(val):
sqlite3.register_converter('datetime', convert_timestamp) sqlite3.register_converter('datetime', convert_timestamp)
sqlite3.register_converter('timestamp', convert_timestamp) sqlite3.register_converter('timestamp', convert_timestamp)
def query(operation, *params): if config['DB_ENGINE'] == 'sqlite':
_params = [] created = not os.path.exists(config['SQLITE_DB'])
for p in params: db = sqlite3.connect(config['SQLITE_DB'])
if isinstance(p, datetime): cur = db.cursor()
p = p.replace(microsecond=0) if config['SQLITE_INIT_SCHEMA']:
_params.append(p) cur.executescript(open(config['DB_SCHEMA']).read())
params = _params if config['SQLITE_INIT_DATA'] and created:
if config['DB_ENGINE'] == 'mysql': cur.executescript(open(config['db_data']).read())
import mysql.connector db.commit()
if 'db' not in g or not g.db.is_connected(): db.close()
g.db = mysql.connector.connect(user=config['MYSQL_USER'], password=config['MYSQL_PASSWD'], host=config['MYSQL_HOST'], database=config['MYSQL_DB'])
if not hasattr(request, 'db'): def get_dbcursor():
request.db = g.db.cursor(dictionary=True)
request.db.execute(operation.replace('?', '%s'), params)
elif config['DB_ENGINE'] == 'sqlite':
if 'db' not in g: if 'db' not in g:
g.db = sqlite3.connect(config['SQLITE_DB'], detect_types=sqlite3.PARSE_DECLTYPES) g.db = sqlite3.connect(config['SQLITE_DB'], detect_types=sqlite3.PARSE_DECLTYPES)
g.db.row_factory = dict_factory
g.db.isolation_level = None g.db.isolation_level = None
if not hasattr(request, 'db'): if not hasattr(request, 'db'):
request.db = g.db.cursor() request.db = g.db.cursor()
request.db.execute(operation, params) return request.db
else:
return [] def fix_query(operation, params):
try: params = [(p.replace(microsecond=0) if isinstance(p, datetime) else p) for p in params]
rows = request.db.fetchall() return operation, params
except:
rows = [] elif config['DB_ENGINE'] == 'mysql':
if not rows and request.db.lastrowid != None: import mysql.connector
return request.db.lastrowid
return rows def get_dbcursor():
if 'db' not in g or not g.db.is_connected():
g.db = mysql.connector.connect(user=config['MYSQL_USER'], password=config['MYSQL_PASSWD'], host=config['MYSQL_HOST'], database=config['MYSQL_DB'])
if not hasattr(request, 'db'):
request.db = g.db.cursor()
return request.db
def fix_query(operation, params):
operation = operation.replace('?', '%s')
params = [(p.replace(microsecond=0) if isinstance(p, datetime) else p) for p in params]
return operation, params
def query(operation, *params, delim="sep"):
operation, params = fix_query(operation, params)
cur = get_dbcursor()
cur.execute(operation, params)
rows = cur.fetchall()
res = []
for row in rows:
res.append({})
ptr = res[-1]
for col, desc in zip(row, cur.description):
name = desc[0].split('.')[-1]
if name == delim:
ptr = res[-1][col] = {}
continue
if type(col) == str:
col = col.replace('\\n', '\n').replace('\\r', '\r')
ptr[name] = col
return res
def modify(operation, *params):
operation, params = fix_query(operation, params)
cur = get_dbcursor()
cur.execute(operation, params)
return cur.lastrowid
@app.teardown_request @app.teardown_request
def commit_db(*args): def commit_db(*args):
...@@ -94,15 +106,11 @@ def searchquery(text, columns, match, tables, suffix, *suffixparams): ...@@ -94,15 +106,11 @@ def searchquery(text, columns, match, tables, suffix, *suffixparams):
return query(expr, *params, *suffixparams) return query(expr, *params, *suffixparams)
LDAP_USERRE = re.compile(r'[^a-z0-9]') LDAP_USERRE = re.compile(r'[^a-z0-9]')
notldap = { if 'LDAP_HOST' in config:
'videoag':('videoag', ['users','videoag'], {'uid': 'videoag', 'givenName': 'Video', 'sn': 'Geier'}), import ldap3
'gustav':('passwort', ['users'], {'uid': 'gustav', 'givenName': 'Gustav', 'sn': 'Geier'})
}
def ldapauth(user, password): def ldapauth(user, password):
user = LDAP_USERRE.sub(r'', user.lower()) user = LDAP_USERRE.sub(r'', user.lower())
if 'LDAP_HOST' in config:
import ldap3
try: try:
conn = ldap3.Connection(config['LDAP_HOST'], 'uid=%s,ou=users,dc=fsmpi,dc=rwth-aachen,dc=de'%user, password, auto_bind=True) conn = ldap3.Connection(config['LDAP_HOST'], 'uid=%s,ou=users,dc=fsmpi,dc=rwth-aachen,dc=de'%user, password, auto_bind=True)
if conn.search("ou=groups,dc=fsmpi,dc=rwth-aachen,dc=de", "(&(cn=*)(memberUid=%s))"%user, attributes=['cn']): if conn.search("ou=groups,dc=fsmpi,dc=rwth-aachen,dc=de", "(&(cn=*)(memberUid=%s))"%user, attributes=['cn']):
...@@ -111,14 +119,9 @@ def ldapauth(user, password): ...@@ -111,14 +119,9 @@ def ldapauth(user, password):
return user, groups return user, groups
except ldap3.core.exceptions.LDAPBindError: except ldap3.core.exceptions.LDAPBindError:
pass pass
elif config.get('DEBUG') and user in notldap and password == notldap[user][0]:
return user, notldap[user][1]
return None, []
def ldapget(user): def ldapget(user):
user = LDAP_USERRE.sub(r'', user.lower()) user = LDAP_USERRE.sub(r'', user.lower())
if 'LDAP_HOST' in config:
import ldap3
conn = ldap3.Connection('ldaps://rumo.fsmpi.rwth-aachen.de', auto_bind=True) conn = ldap3.Connection('ldaps://rumo.fsmpi.rwth-aachen.de', auto_bind=True)
conn.search("ou=users,dc=fsmpi,dc=rwth-aachen,dc=de", "(uid=%s)"%user, conn.search("ou=users,dc=fsmpi,dc=rwth-aachen,dc=de", "(uid=%s)"%user,
attributes=ldap3.ALL_ATTRIBUTES) attributes=ldap3.ALL_ATTRIBUTES)
...@@ -126,6 +129,19 @@ def ldapget(user): ...@@ -126,6 +129,19 @@ def ldapget(user):
return {} return {}
e = conn.entries[0] e = conn.entries[0]
return {'uid': user, 'givenName': e.givenName.value, 'sn':e.sn.value} return {'uid': user, 'givenName': e.givenName.value, 'sn':e.sn.value}
else: else:
return notldap[user][2] notldap = {
'videoag':('videoag', ['users','videoag'], {'uid': 'videoag', 'givenName': 'Video', 'sn': 'Geier'}),
'gustav':('passwort', ['users'], {'uid': 'gustav', 'givenName': 'Gustav', 'sn': 'Geier'})
}
def ldapauth(user, password):
user = LDAP_USERRE.sub(r'', user.lower())
if config.get('DEBUG') and user in notldap and password == notldap[user][0]:
return user, notldap[user][1]
return None, []
def ldapget(user):
user = LDAP_USERRE.sub(r'', user.lower())
return notldap[user][2]
...@@ -20,25 +20,22 @@ def feed(handle=None): ...@@ -20,25 +20,22 @@ def feed(handle=None):
course['atomid'] = gen_atomid('Video AG, courses['+str(course['id'])+']: '+course['handle']) course['atomid'] = gen_atomid('Video AG, courses['+str(course['id'])+']: '+course['handle'])
id = course['id'] id = course['id']
entries = query(''' entries = query('''
SELECT lectures.*, videos.file_size, videos.path, videos.id AS video_id, videos.hash, SELECT lectures.*, "video" AS sep, videos.*, formats.description AS format_description, formats.prio, "course" AS sep, courses.*
videos.time_created AS video_created, videos.time_updated AS video_updated,
courses.title AS course_title, courses.handle AS course_handle, courses.semester, courses.organizer AS course_organizer, courses.short as course_short,
formats.description AS format_description, formats.prio
FROM lectures FROM lectures
JOIN courses ON (courses.id = lectures.course_id) JOIN courses ON (courses.id = lectures.course_id)
JOIN videos ON (lectures.id = videos.lecture_id) JOIN videos ON (lectures.id = videos.lecture_id)
JOIN formats ON (formats.id = videos.video_format) JOIN formats ON (formats.id = videos.video_format)
WHERE ((? IS NULL AND courses.listed) OR course_id = ?) AND courses.visible AND lectures.visible AND videos.visible WHERE ((? IS NULL AND courses.listed) OR course_id = ?) AND courses.visible AND lectures.visible AND videos.visible
ORDER BY video_created DESC, prio ASC ORDER BY videos.time_created DESC, prio ASC
LIMIT 100''', LIMIT 100''',
course['id'], course['id']) course['id'], course['id'])
updated = max(course['time_updated'], course['time_created'], key=fixdate) updated = max(course['time_updated'], course['time_created'], key=fixdate)
for entry in entries: for entry in entries:
entry['updated'] = max(entry['video_created'], entry['video_updated'], entry['time_created'], entry['time_updated'], key=fixdate) entry['updated'] = max(entry['video']['time_created'], entry['video']['time_updated'], entry['time_created'], entry['time_updated'], key=fixdate)
if len(entry['hash']) != 32: if len(entry['video']['hash']) != 32:
entry['atomid'] = gen_atomid('Video AG, videos['+str(entry['video_id'])+']') entry['atomid'] = gen_atomid('Video AG, videos['+str(entry['video_id'])+']')
else: else:
entry['atomid'] = 'urn:md5:'+(entry['hash'].upper()) entry['atomid'] = 'urn:md5:'+(entry['video']['hash'].upper())
updated = max(updated, entry['updated'], key=fixdate) updated = max(updated, entry['updated'], key=fixdate)
course['updated'] = updated course['updated'] = updated
return Response(render_template('feed.atom', course=course, entries=entries), 200, {'Content-Type': 'application/atom+xml'}) return Response(render_template('feed.atom', course=course, entries=entries), 200, {'Content-Type': 'application/atom+xml'})
......
...@@ -17,7 +17,7 @@ def import_from(source=None, id=None): ...@@ -17,7 +17,7 @@ def import_from(source=None, id=None):
for i in campus: for i in campus:
if i.startswith('new'): if i.startswith('new'):
if campus[i]['url'] != '': if campus[i]['url'] != '':
query('INSERT INTO import_campus (url, type, course_id, last_checked, changed) VALUES (?, ?, ?, ?, 1)',campus[i]['url'],campus[i]['type'],id,datetime.now()) modify('INSERT INTO import_campus (url, type, course_id, last_checked, changed) VALUES (?, ?, ?, ?, 1)',campus[i]['url'],campus[i]['type'],id,datetime.now())
else: else:
if campus[i]['url'] != '': if campus[i]['url'] != '':
query('UPDATE import_campus SET url = ?, `type` = ? WHERE (course_id = ?) AND (id = ?)', campus[i]['url'],campus[i]['type'],id,int(i)) query('UPDATE import_campus SET url = ?, `type` = ? WHERE (course_id = ?) AND (id = ?)', campus[i]['url'],campus[i]['type'],id,int(i))
......
...@@ -34,7 +34,7 @@ if config['DEBUG']: ...@@ -34,7 +34,7 @@ if config['DEBUG']:
if not config.get('SECRET_KEY', None): if not config.get('SECRET_KEY', None):
config['SECRET_KEY'] = os.urandom(24) config['SECRET_KEY'] = os.urandom(24)
from db import query, searchquery, ldapauth, ldapget, convert_timestamp from db import query, modify, searchquery, ldapauth, ldapget
mod_endpoints = [] mod_endpoints = []
...@@ -133,7 +133,7 @@ def index(): ...@@ -133,7 +133,7 @@ def index():
start = date.today() - timedelta(days=1) start = date.today() - timedelta(days=1)
end = start + timedelta(days=7) end = start + timedelta(days=7)
upcomming = query(''' upcomming = query('''
SELECT lectures.*,courses.short, courses.title AS course_title SELECT lectures.*, "course" AS sep, courses.*
FROM lectures FROM lectures
JOIN courses ON (lectures.course_id = courses.id) JOIN courses ON (lectures.course_id = courses.id)
WHERE (time > ?) AND (time < ?) and lectures.visible and courses.visible and courses.listed WHERE (time > ?) AND (time < ?) and lectures.visible and courses.visible and courses.listed
...@@ -141,13 +141,13 @@ def index(): ...@@ -141,13 +141,13 @@ def index():
for i in upcomming: for i in upcomming:
i['date'] = i['time'].date() i['date'] = i['time'].date()
latestvideos=query(''' latestvideos=query('''
SELECT lectures.*, max(videos.time_updated) AS lastvidtime, courses.short, courses.downloadable, courses.title AS coursetitle SELECT lectures.*, "course" AS sep, courses.*
FROM lectures FROM lectures
LEFT JOIN videos ON (videos.lecture_id = lectures.id) LEFT JOIN videos ON (videos.lecture_id = lectures.id)
LEFT JOIN courses on (courses.id = lectures.course_id) LEFT JOIN courses on (courses.id = lectures.course_id)
WHERE (? OR (courses.visible AND courses.listed AND lectures.visible AND videos.visible)) WHERE (? OR (courses.visible AND courses.listed AND lectures.visible AND videos.visible))
GROUP BY videos.lecture_id GROUP BY videos.lecture_id
ORDER BY lastvidtime DESC ORDER BY MAX(videos.time_updated) DESC
LIMIT 6 ''',ismod()) LIMIT 6 ''',ismod())
featured = query('SELECT * FROM featured WHERE NOT deleted AND (? OR visible)', ismod()) featured = query('SELECT * FROM featured WHERE NOT deleted AND (? OR visible)', ismod())
return render_template('index.html', latestvideos=latestvideos, upcomming=upcomming, featured=featured) return render_template('index.html', latestvideos=latestvideos, upcomming=upcomming, featured=featured)
...@@ -238,7 +238,7 @@ def login(): ...@@ -238,7 +238,7 @@ def login():
session['user'] = ldapget(user) session['user'] = ldapget(user)
dbuser = query('SELECT * FROM users WHERE name = ?', user) dbuser = query('SELECT * FROM users WHERE name = ?', user)
if not dbuser: if not dbuser:
query('INSERT INTO users (name, realname, fsacc, level, calendar_key, rfc6238) VALUES (?, ?, ?, 1, "", "")', user, session['user']['givenName'], user) modify('INSERT INTO users (name, realname, fsacc, level, calendar_key, rfc6238) VALUES (?, ?, ?, 1, "", "")', user, session['user']['givenName'], user)
dbuser = query('SELECT * FROM users WHERE name = ?', user) dbuser = query('SELECT * FROM users WHERE name = ?', user)
session['user']['dbid'] = dbuser[0]['id'] session['user']['dbid'] = dbuser[0]['id']
return redirect(request.values.get('ref', url_for('index'))) return redirect(request.values.get('ref', url_for('index')))
...@@ -262,7 +262,7 @@ def edit(prefix="", ignore=[]): ...@@ -262,7 +262,7 @@ def edit(prefix="", ignore=[]):
'chapters': ('chapters', 'id', ['time', 'text', 'visible', 'deleted']), 'chapters': ('chapters', 'id', ['time', 'text', 'visible', 'deleted']),
'announcements': ('announcements', 'id', ['text', 'internal', 'level', 'visible', 'deleted']) 'announcements': ('announcements', 'id', ['text', 'internal', 'level', 'visible', 'deleted'])
} }
query('BEGIN') modify('BEGIN')
if request.is_json: if request.is_json:
changes = request.get_json().items() changes = request.get_json().items()
else: else:
...@@ -270,21 +270,19 @@ def edit(prefix="", ignore=[]): ...@@ -270,21 +270,19 @@ def edit(prefix="", ignore=[]):
for key, val in changes: for key, val in changes:
if key in ignore: if key in ignore:
continue continue
print('edit:', key, val)
key = prefix+key key = prefix+key
print (key,val)
table, id, column = key.split('.', 2) table, id, column = key.split('.', 2)
assert table in tabs assert table in tabs
assert column in tabs[table][2] assert column in tabs[table][2]
query('INSERT INTO changelog ("table",id_value,id_key,field,value_new,value_old,"when",who,executed) VALUES (?,?,?,?,?,(SELECT %s FROM %s WHERE %s = ?),?,?,1)'%(column,tabs[table][0],tabs[table][1]),table,id,tabs[table][1],column,val,id,datetime.now(),session['user']['givenName']) modify('INSERT INTO changelog ("table",id_value,id_key,field,value_new,value_old,"when",who,executed) VALUES (?,?,?,?,?,(SELECT %s FROM %s WHERE %s = ?),?,?,1)'%(column,tabs[table][0],tabs[table][1]),table,id,tabs[table][1],column,val,id,datetime.now(),session['user']['givenName'])
query('UPDATE %s SET %s = ?, time_updated = ? WHERE %s = ?'%(tabs[table][0], column, tabs[table][1]), val, datetime.now(), id) modify('UPDATE %s SET %s = ?, time_updated = ? WHERE %s = ?'%(tabs[table][0], column, tabs[table][1]), val, datetime.now(), id)
query('COMMIT') modify('COMMIT')
return "OK", 200 return "OK", 200
@app.route('/newcourse', methods=['GET', 'POST']) @app.route('/newcourse', methods=['GET', 'POST'])
@mod_required @mod_required
def new_course(): def new_course():
id = query(''' id = modify('''
INSERT INTO courses_data INSERT INTO courses_data
(visible, title, short, handle, organizer, subject, created_by, time_created, (visible, title, short, handle, organizer, subject, created_by, time_created,
time_updated, semester, settings, description, internal, responsible, feed_url) time_updated, semester, settings, description, internal, responsible, feed_url)
...@@ -299,7 +297,7 @@ def new_course(): ...@@ -299,7 +297,7 @@ def new_course():
@app.route('/newlecture/<courseid>', methods=['GET', 'POST']) @app.route('/newlecture/<courseid>', methods=['GET', 'POST'])
@mod_required @mod_required
def new_lecture(courseid): def new_lecture(courseid):
id = query(''' id = modify('''
INSERT INTO lectures_data INSERT INTO lectures_data
(course_id, visible, drehplan, title, comment, internal, speaker, place, (course_id, visible, drehplan, title, comment, internal, speaker, place,
time, time_created, time_updated, jumplist, titlefile) time, time_created, time_updated, jumplist, titlefile)
...@@ -347,7 +345,7 @@ def auth(): # For use with nginx auth_request ...@@ -347,7 +345,7 @@ def auth(): # For use with nginx auth_request
if not types[0] or allowed or ismod() or \ if not types[0] or allowed or ismod() or \
(auth and check_mod(*ldapauth(auth.username, auth.password))): (auth and check_mod(*ldapauth(auth.username, auth.password))):
return 'OK', 200 return 'OK', 200
query('INSERT INTO log VALUES (?, "", ?, "video", ?, ?)', ip, datetime.now(), videos[0]['id'], url) modify('INSERT INTO log VALUES (?, "", ?, "video", ?, ?)', ip, datetime.now(), videos[0]['id'], url)
elif 'password' in types: elif 'password' in types:
return Response("Login required", 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) return Response("Login required", 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})
return "Not allowed", 403 return "Not allowed", 403
...@@ -378,7 +376,7 @@ def suggest_chapter(lectureid): ...@@ -378,7 +376,7 @@ def suggest_chapter(lectureid):
submitter = None submitter = None
if not ismod(): if not ismod():
submitter = request.environ['REMOTE_ADDR'] submitter = request.environ['REMOTE_ADDR']
id = query('INSERT INTO chapters (lecture_id, time, text, time_created, time_updated, created_by, submitted_by) VALUES (?, ?, ?, ?, ?, ?, ?)', id = modify('INSERT INTO chapters (lecture_id, time, text, time_created, time_updated, created_by, submitted_by) VALUES (?, ?, ?, ?, ?, ?, ?)',
lectureid, time, text, datetime.now(), datetime.now(), session.get('user', {'dbid':None})['dbid'], submitter) lectureid, time, text, datetime.now(), datetime.now(), session.get('user', {'dbid':None})['dbid'], submitter)
if 'ref' in request.values: if 'ref' in request.values:
return redirect(request.values['ref']) return redirect(request.values['ref'])
...@@ -387,7 +385,7 @@ def suggest_chapter(lectureid): ...@@ -387,7 +385,7 @@ def suggest_chapter(lectureid):
@app.route('/newpsa', methods=['POST', 'GET']) @app.route('/newpsa', methods=['POST', 'GET'])
@mod_required @mod_required
def new_announcement(): def new_announcement():
id = query('INSERT INTO announcements (text, internal, time_created, time_updated, created_by) VALUES ("Neue Ankündigung", "", ?, ?, ?)', id = modify('INSERT INTO announcements (text, internal, time_created, time_updated, created_by) VALUES ("Neue Ankündigung", "", ?, ?, ?)',
datetime.now(), datetime.now(), session.get('user', {'dbid':None})['dbid']) datetime.now(), datetime.now(), session.get('user', {'dbid':None})['dbid'])
if 'ref' in request.values: if 'ref' in request.values:
return redirect(request.values['ref']) return redirect(request.values['ref'])
...@@ -396,7 +394,7 @@ def new_announcement(): ...@@ -396,7 +394,7 @@ def new_announcement():
@app.route('/newfeatured', methods=['POST', 'GET']) @app.route('/newfeatured', methods=['POST', 'GET'])
@mod_required @mod_required
def new_featured(): def new_featured():
id = query('INSERT INTO featured (time_created, time_updated, created_by) VALUES (?, ?, ?)', id = modify('INSERT INTO featured (time_created, time_updated, created_by) VALUES (?, ?, ?)',
datetime.now(), datetime.now(), session.get('user', {'dbid':None})['dbid']) datetime.now(), datetime.now(), session.get('user', {'dbid':None})['dbid'])
if 'ref' in request.values: if 'ref' in request.values:
return redirect(request.values['ref']) return redirect(request.values['ref'])
......
{% macro summary(entry) %} {% macro summary(entry) %}
{% if not course.handle %} {% if not course.handle %}
Veranstaltung: <a href="{{ url_for('course', handle=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 %} {% if entry.course.organizer %}
Veranstalter: {{ entry.course_organizer }}<br> Veranstalter: {{ entry.course.organizer }}<br>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if entry.speaker %} {% if entry.speaker %}
...@@ -42,10 +42,10 @@ Veranstalter: {{ course.organizer }}<br> ...@@ -42,10 +42,10 @@ Veranstalter: {{ course.organizer }}<br>
{% for entry in entries %} {% for entry in entries %}
<entry> <entry>
<title>{% if not course.handle %}{{ entry.course_short }} {% if entry.semester %}({{ entry.semester|semester }}){% endif %}, {% endif %}{{ entry.time|date }}: {{ entry.title }}</title> <title>{% if not course.handle %}{{ entry.course.short }} {% if entry.course.semester %}({{ entry.course.semester|semester }}){% endif %}, {% endif %}{{ entry.time|date }}: {{ entry.title }}</title>
{% if not course.handle and entry.course_organizer %} {% if not course.handle and entry.course.organizer %}
<author> <author>
<name>{{ entry.course_organizer }}</name> <name>{{ entry.course.organizer }}</name>
</author> </author>
{% endif %} {% endif %}
{% if entry.speaker %} {% if entry.speaker %}
...@@ -54,7 +54,7 @@ Veranstalter: {{ course.organizer }}<br> ...@@ -54,7 +54,7 @@ Veranstalter: {{ course.organizer }}<br>
</author> </author>
{% endif %} {% endif %}
<link rel="alternate" href="{{ url_for('lecture', 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 }}"/> <link rel="enclosure" href="{{ url_for('files', filename=entry.video.path, _external=True)}}" length="{{ entry.video.file_size }}"/>
<id>{{ entry.atomid }}</id> <id>{{ entry.atomid }}</id>
<updated>{{ entry.updated|rfc3339 }}</updated> <updated>{{ entry.updated|rfc3339 }}</updated>
<summary type="html">{{ summary(entry)|e }}</summary> <summary type="html">{{ summary(entry)|e }}</summary>
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
<strong>{{ g.grouper|date }}</strong> <strong>{{ g.grouper|date }}</strong>
{% for i in g.list %} {% for i in g.list %}
<li class="list-group-item list-group-item-condensed"> <li class="list-group-item list-group-item-condensed">
{{i.time|time}} {{i.place}} <a href="{{url_for('course', id=i.course_id)}}">{{i.course_title}}</a>: <a href="{{url_for('course', id=i.course_id)}}#lecture-{{i.id}}">{{i.title}}</a> {{i.time|time}} {{i.place}} <a href="{{url_for('course', id=i.course_id)}}">{{i.course.title}}</a>: <a href="{{url_for('course', id=i.course_id)}}#lecture-{{i.id}}">{{i.title}}</a>
</li> </li>
{% endfor %} {% endfor %}
......
{% macro preview(lecture) %} {% macro preview(lecture) %}
<li class="list-group-item"> <li class="list-group-item">
<a class="hidden-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}" style="color: #000"> <a class="hidden-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture.course.title }}" style="color: #000">
<div class="row"> <div class="row">
<img class="col-xs-4" style="max-height: 100px; width: auto;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; "> <img class="col-xs-4" style="max-height: 100px; width: auto;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; ">
<div class="col-xs-4"> <div class="col-xs-4">
<span><strong>{{ lecture['short'] }}</strong></span><br> <span><strong>{{ lecture.course.short }}</strong></span><br>
<span>{{ lecture['time'] }}</span> <span>{{ lecture['time'] }}</span>
{% if lecture['speaker'] %} {% if lecture['speaker'] %}
<div class="small">Gehalten von {{ lecture['speaker'] }} </div> <div class="small">Gehalten von {{ lecture['speaker'] }} </div>
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
</div> </div>
</div> </div>
</a> </a>
<a class="visible-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}" style="color: #000"> <a class="visible-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture.course.title }}" style="color: #000">
<ul class="list-unstyled"> <ul class="list-unstyled">
<li> <li>
<img style="width: 100%;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; "> <img style="width: 100%;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; ">
</li> </li>
<li> <li>
<strong>{{ lecture['short'] }}</strong> {{ lecture['time'] }} <strong>{{ lecture.course.short }}</strong> {{ lecture['time'] }}
</li> </li>
{% if lecture['speaker'] %} {% if lecture['speaker'] %}
<li> <li>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment