diff --git a/feeds.py b/feeds.py index 702c57553986b66cb46bcd64a5f8e07ea9cbbde5..a4b6f5b0606645049c6402081dba8cb029aa833f 100644 --- a/feeds.py +++ b/feeds.py @@ -40,6 +40,28 @@ def feed(handle=None): course['updated'] = updated return Response(render_template('feed.atom', course=course, entries=entries), 200, {'Content-Type': 'application/atom+xml'}) +@app.route('/<handle>/rssfeed') +def rss_feed(handle): + course = query('SELECT * FROM courses WHERE handle = ? AND visible', handle)[0] + formats = query('''SELECT formats.* FROM formats + JOIN videos ON videos.video_format = formats.id + JOIN lectures ON lectures.id = videos.lecture_id + WHERE lectures.course_id = ? + GROUP BY formats.id + ORDER BY formats.player_prio DESC''', course['id']) + fmt = query('SELECT * FROM formats WHERE id = ?', request.values.get('format_id', formats[0]['id']))[0] + items = query('''SELECT lectures.*, "video" AS sep, videos.* + FROM lectures + JOIN courses ON courses.id = lectures.course_id + JOIN videos ON lectures.id = videos.lecture_id + WHERE courses.id = ? AND videos.video_format = ?AND courses.visible AND lectures.visible AND videos.visible + ORDER BY videos.time_created DESC + LIMIT 100''', course['id'], fmt['id']) + chapters = query('SELECT chapters.* FROM chapters JOIN lectures ON lectures.id = chapters.lecture_id WHERE lectures.course_id = ? AND NOT chapters.deleted AND chapters.visible ORDER BY time ASC', course['id']) + for item in items: + item['updated'] = max(item['video']['time_created'], item['video']['time_updated'], item['time_created'], item['time_updated'], key=fixdate) + return Response(render_template('feed.rss', course=course, format=fmt, formats=formats, items=items, chapters=chapters), 200, {'Content-Type': 'application/rss+xml; charset=UTF-8'}) + @app.route('/courses/feed') def courses_feed(): courses = query('SELECT * FROM courses WHERE visible AND listed ORDER BY time_created DESC LIMIT 100') diff --git a/template_helper.py b/template_helper.py index 20271d73e732a5a9b9dcc9328caf038a36cd6ec8..1fee370a167d70f362375d9221fb0de9f1639e2d 100644 --- a/template_helper.py +++ b/template_helper.py @@ -1,5 +1,7 @@ from server import * import subprocess +from time import mktime +from email.utils import formatdate app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True @@ -154,6 +156,10 @@ def human_time(d): def rfc3339(d): return d.strftime('%Y-%m-%dT%H:%M:%S+02:00') +@app.template_filter() +def rfc822(d): + return formatdate(mktime(d.timetuple())) + @app.template_global() def get_announcements(minlevel=0): offset = timedelta() diff --git a/templates/feed.rss b/templates/feed.rss new file mode 100644 index 0000000000000000000000000000000000000000..3f8897ec53376b103ac3af481075ad9bdde19583 --- /dev/null +++ b/templates/feed.rss @@ -0,0 +1,38 @@ +{% macro title(fmt) %} +{{ course.title }} ({{ fmt.description }}) — Video AG, FSMPI +{%- endmacro %} +<?xml version="1.0" encoding="UTF-8"?> +<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:psc="http://podlove.org/simple-chapters" version="2.0"> +<channel> +<title>{{ title(format) }}</title> +<link>{{ url_for('course', handle=course.handle, _external=True) }}</link> +<description><![CDATA[{{ course.description }}]]></description> +<generator>Website der Video AG (+https://git.fsmpi.rwth-aachen.de/videoaginfra/website)</generator> +<image> + <url>{{ url_for('static', filename='logo.png', _external=True) }}</url> + <title>{{ title(format) }}</title> + <link>{{ url_for('course', handle=course.handle, _external=True) }}</link> +</image> +<atom:link rel="self" type="application/rss+xml" title="{{ title(format) }}" href="{{ url_for('rss_feed', handle=course.handle, format_id=format.id, _external=True) }}"/> +{% for fmt in formats %} +{% if fmt.id != format.id %} +<atom:link rel="alternate" type="application/rss+xml" title="{{ title(fmt) }}" href="{{ url_for('rss_feed', handle=course.handle, format_id=fmt.id, _external=True) }}"/> +{% endif %} +{% endfor %} +{% for item in items %} +<item> + <title>{{ item.title }}</title> + <link>{{ url_for('lecture', id=item.id, course=course.handle, _external=True) }}</link> + <pubDate>{{ item.updated|rfc822 }}</pubDate> + <guid>video.fsmpi.rwth-aachen.de:{{ item.video.id }}</guid> + <description><![CDATA[{{ item.comment|e }}]]></description> + <psc:chapters xmlns:psc="http://podlove.org/simple-chapters" version="1.2"> + {% for chapter in chapters|selectattr('lecture_id','equalto',item.id) %} + <psc:chapter start="{{ chapter.time }}" title="{{ chapter.text }}"/> + {% endfor %} + </psc:chapters> + <enclosure url="{{ url_for('files', filename=item.video.path, _external=True) }}" length="{{ item.video.file_size }}" type="{{ format.mimetype }}"/> +</item> +{% endfor %} +</channel> +</rss>