From a7a6ebde8ef99f258171908204b923bee21e764f Mon Sep 17 00:00:00 2001 From: Julian Rother <julianr@fsmpi.rwth-aachen.de> Date: Wed, 12 Apr 2017 00:33:14 +0200 Subject: [PATCH] Changed url scheme, all non-stable paths are prefixed by /internal --- feeds.py | 4 ++-- importer.py | 4 ++-- jobs.py | 10 +++++----- l2pauth.py | 4 ++-- server.py | 42 +++++++++++++++++++++++++----------------- sorter.py | 4 ++-- static/moderator.js | 4 ++-- stats.py | 10 +++++----- templates/embed.html | 2 -- templates/feed.atom | 2 +- templates/lecture.html | 2 +- templates/macros.html | 8 ++++---- timetable.py | 2 +- 13 files changed, 52 insertions(+), 46 deletions(-) diff --git a/feeds.py b/feeds.py index 7b7767d..702c575 100644 --- a/feeds.py +++ b/feeds.py @@ -9,7 +9,7 @@ def fixdate(d): return d @app.route('/feed') -@app.route('/course/<handle>/feed') +@app.route('/<handle>/feed') @handle_errors(None, 'Diese Veranstaltung existiert nicht!', 400, IndexError) def feed(handle=None): id = None @@ -40,7 +40,7 @@ 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('/course/feed') +@app.route('/courses/feed') 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') diff --git a/importer.py b/importer.py index ded1e96..b3d3bd3 100644 --- a/importer.py +++ b/importer.py @@ -1,6 +1,6 @@ from server import * -@app.route('/import/<int:id>', methods=['GET', 'POST']) +@app.route('/internal/import/<int:id>', methods=['GET', 'POST']) @mod_required def list_import_sources(id): courses = query('SELECT * FROM courses WHERE id = ?', id)[0] @@ -25,7 +25,7 @@ def list_import_sources(id): return render_template('import_campus.html', course=courses, import_campus=import_campus, events=[]) -@app.route('/import/<int:id>/now', methods=['GET', 'POST']) +@app.route('/internal/import/<int:id>/now', methods=['GET', 'POST']) @mod_required def import_from(id): diff --git a/jobs.py b/jobs.py index 909aab3..440f958 100644 --- a/jobs.py +++ b/jobs.py @@ -3,7 +3,7 @@ import traceback import json import random -@app.route('/jobs/overview') +@app.route('/internal/jobs/overview') @register_navbar('Jobs', iconlib='fa', icon='suitcase') @mod_required def jobs_overview(): @@ -47,13 +47,13 @@ def jobs_catch_broken(): except: pass -@app.route('/jobs/api/worker/<hostname>/ping', methods=['GET', 'POST']) +@app.route('/internal/jobs/api/worker/<hostname>/ping', methods=['GET', 'POST']) @jobs_api_token_required def jobs_worker_ping(hostname): query('INSERT OR REPLACE INTO worker (hostname, last_ping) values (?, ?)', hostname, datetime.now()) return 'OK',200 -@app.route('/jobs/api/job/<int:id>/ping', methods=['GET', 'POST']) +@app.route('/internal/jobs/api/job/<int:id>/ping', methods=['GET', 'POST']) @jobs_api_token_required def jobs_ping(id): hostname = request.values['host'] @@ -62,7 +62,7 @@ def jobs_ping(id): query('UPDATE jobs SET worker = ?, last_ping = ?, status = ?, state = ? where id = ?', hostname, datetime.now(), status, state, id) return 'OK',200 -@app.route('/jobs/api/job/<int:id>/finished', methods=['GET', 'POST']) +@app.route('/internal/jobs/api/job/<int:id>/finished', methods=['GET', 'POST']) @jobs_api_token_required def jobs_finished(id): if 'status' in request.values: @@ -72,7 +72,7 @@ def jobs_finished(id): query('UPDATE jobs SET time_finished = ?, status = ?, state = "finished" where id = ?', datetime.now(), status, id) return 'OK',200 -@app.route('/jobs/api/worker/<hostname>/schedule', methods=['POST']) +@app.route('/internal/jobs/api/worker/<hostname>/schedule', methods=['POST']) @jobs_api_token_required def jobs_schedule(hostname): hostdata = request.get_json() diff --git a/l2pauth.py b/l2pauth.py index d658ee4..3c971e7 100644 --- a/l2pauth.py +++ b/l2pauth.py @@ -14,7 +14,7 @@ def oauthget(endpoint, **args): r = requests.request('POST', OAUTH_BASE+endpoint, data=args) return r.json() -@app.route('/l2pauth') +@app.route('/internal/l2pauth') def start_l2pauth(): if 'L2P_APIKEY' not in config: return render_template("500.html"), 500 @@ -23,7 +23,7 @@ def start_l2pauth(): session['oauthscope'] = 'l2p' return redirect(code['verification_url']+'?q=verify&d='+code['user_code']) -@app.route('/rwthauth') +@app.route('/internal/rwthauth') def start_rwthauth(): if 'L2P_APIKEY' not in config: return render_template("500.html"), 500 diff --git a/server.py b/server.py index 55aa88c..fcdf465 100644 --- a/server.py +++ b/server.py @@ -299,7 +299,10 @@ def index(): return redirect(url_for('course', handle=request.args['course']),code=302) if 'view' in request.args: if (request.args['view'] == 'player') and ('lectureid' in request.args) : - return redirect(url_for('lecture', id=request.args['lectureid']),code=302) + courses = query('SELECT courses.handle FROM courses JOIN lectures ON courses.id = lectures.course_id WHERE lectures.id = ?', request.args['lectureid']) + if not courses: + return "Not found", 404 + return redirect(url_for('lecture', course=courses[0]['handle'], id=request.args['lectureid']),code=302) start = date.today() - timedelta(days=1) end = start + timedelta(days=7) @@ -335,7 +338,7 @@ def index(): item['courses'] = query('SELECT * FROM courses WHERE (visible AND listed) AND `%s` = ? ORDER BY `%s`'%(item['param'], item['param']), item['param2']) return render_template('index.html', latestvideos=livestreams+latestvideos, upcomming=upcomming, featured=featured) -@app.route('/course') +@app.route('/courses') @register_navbar('Videos', icon='film') def courses(): courses = query('SELECT * FROM courses WHERE (? OR (visible AND listed)) ORDER BY title', ismod()) @@ -355,8 +358,8 @@ def genlive(streams): stream['file_size'] = 0 return streams -@app.route('/course/<handle>') -@app.route('/course/<int:id>') +@app.route('/<handle>') +@app.route('/<int:id>') @handle_errors('courses', 'Diese Veranstaltung existiert nicht!', 404, IndexError) def course(id=None, handle=None): if id: @@ -396,10 +399,12 @@ def course(id=None, handle=None): def faq(): return render_template('faq.html') -@app.route('/play/<int:id>') -@app.route('/embed/<int:id>', endpoint='embed') +@app.route('/<course>/<int:id>') +@app.route('/<int:courseid>/<int:id>') +@app.route('/<course>/<int:id>/embed', endpoint='embed') +@app.route('/<int:courseid>/<int:id>/embed', endpoint='embed') @handle_errors('course', 'Diese Vorlesung existiert nicht!', 404, IndexError) -def lecture(id): +def lecture(id, course=None, courseid=None): lecture = query('SELECT * FROM lectures WHERE id = ? AND (? OR visible)', id, ismod())[0] videos = query(''' SELECT videos.*, (videos.downloadable AND courses.downloadable) as downloadable, formats.description AS format_description, formats.player_prio, formats.prio, formats.mimetype @@ -463,7 +468,7 @@ def search(): def check_mod(user, groups): return user and 'users' in groups -@app.route('/login', methods=['GET', 'POST']) +@app.route('/internal/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': return render_template('login.html') @@ -480,7 +485,7 @@ def login(): session['_csrf_token'] = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(128)) return redirect(request.values.get('ref', url_for('index'))) -@app.route('/logout', methods=['GET', 'POST']) +@app.route('/internal/logout', methods=['GET', 'POST']) def logout(): session.pop('user') return redirect(request.values.get('ref', url_for('index'))) @@ -509,7 +514,7 @@ tabs = { ['time_created', 'time_updated']) } -@app.route('/edit', methods=['GET', 'POST']) +@app.route('/internal/edit', methods=['GET', 'POST']) @mod_required @csrf_protect def edit(prefix='', ignore=[]): @@ -536,7 +541,7 @@ def edit(prefix='', ignore=[]): return redirect(request.values['ref']) return "OK", 200 -@app.route('/new/<table>', methods=['GET', 'POST']) +@app.route('/internal/new/<table>', methods=['GET', 'POST']) @mod_required @csrf_protect def create(table): @@ -564,7 +569,7 @@ def create(table): return redirect(request.values['ref']) return str(id), 200 -@app.route('/auth') +@app.route('/internal/auth') def auth(): # For use with nginx auth_request if 'X-Original-Uri' not in request.headers: return 'Internal Server Error', 500 @@ -625,7 +630,7 @@ 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('/changelog') +@app.route('/internal/changelog') @register_navbar('Changelog', icon='book') @mod_required def changelog(): @@ -638,7 +643,7 @@ def changelog(): def files(filename): return redirect(config['VIDEOPREFIX']+'/'+filename) -@app.route('/newchapter/<int:lectureid>', methods=['POST', 'GET']) +@app.route('/internal/newchapter/<int:lectureid>', methods=['POST', 'GET']) def suggest_chapter(lectureid): time = request.values['time'] text = request.values['text'] @@ -659,7 +664,7 @@ def suggest_chapter(lectureid): return redirect(request.values['ref']) return 'OK', 200 -@app.route('/chapters/<int:lectureid>') +@app.route('/internal/chapters/<int:lectureid>') def chapters(lectureid): chapters = query("SELECT * FROM chapters WHERE lecture_id = ? AND NOT deleted AND (visible OR ?) ORDER BY time DESC", lectureid, ismod()) if not chapters: @@ -682,7 +687,7 @@ def sitemap(): for i in query('select * from courses where visible and listed'): pages.append([url_for('course',handle=i['handle'])]) for j in query('select * from lectures where (course_id = ? and visible)',i['id']): - pages.append([url_for('lecture',id=j['id'])]) + pages.append([url_for('lecture',course=i['handle'],id=j['id'])]) return Response(render_template('sitemap.xml', pages=pages), 200, {'Content-Type': 'application/atom+xml'} ) @@ -692,7 +697,10 @@ def sitemap(): @app.route('/site/<string:phpfile>') def legacy(phpfile=None): if phpfile=='embed.php' and ('lecture' in request.args): - return redirect(url_for('embed', id=request.args['lecture']),code=302) + courses = query('SELECT courses.handle FROM courses JOIN lectures ON courses.id = lectures.course_id WHERE lectures.id = ?', request.args['lecture']) + if not courses: + return render_endpoint('index', 'Diese Seite existiert nicht!'), 404 + return redirect(url_for('embed', course=courses[0]['handle'], id=request.args['lecture']),code=302) if phpfile=='feed.php' and ('all' in request.args): return redirect(url_for('feed'),code=302) if phpfile=='feed.php' and ('newcourses' in request.args): diff --git a/sorter.py b/sorter.py index 72c338e..1e0f80b 100644 --- a/sorter.py +++ b/sorter.py @@ -1,7 +1,7 @@ from server import * import traceback -@app.route('/sort/log') +@app.route('/internal/sort/log') @register_navbar('Sortierlog', icon='sort-by-attributes-alt') @mod_required def sort_log(): @@ -53,7 +53,7 @@ def schedule_thumbnail(lectureid): data = '{"lectureid": "'+str(lectureid)+'", "path": "'+path+'"}' query('INSERT INTO jobs (type, data, time_created) VALUES ("thumbnail", ?, ?)', data, datetime.now()); -@app.route('/sort/now') +@app.route('/internal/sort/now') @mod_required @sched_func(600) def sort_now(): diff --git a/static/moderator.js b/static/moderator.js index 858b5f5..ca809f1 100644 --- a/static/moderator.js +++ b/static/moderator.js @@ -13,7 +13,7 @@ var moderator = { dict['_csrf_token'] = moderator.api.csrf_token; $.ajax({ method: "POST", - url: "/edit", + url: "/internal/edit", dataType: "text", contentType: "application/json", data: JSON.stringify(dict), @@ -29,7 +29,7 @@ var moderator = { value['_csrf_token'] = moderator.api.csrf_token; $.ajax({ method: "POST", - url: "/new/"+type, + url: "/internal/new/"+type, dataType: "text", contentType: "application/json", data: JSON.stringify(value), diff --git a/stats.py b/stats.py index b0be43c..8ef3166 100644 --- a/stats.py +++ b/stats.py @@ -3,7 +3,7 @@ import json from jobs import date_json_handler from hashlib import md5 -@app.route('/stats') +@app.route('/internal/stats') @register_navbar('Statistiken', icon='stats') @mod_required def stats(): @@ -22,8 +22,8 @@ statsqueries['live_views'] = "SELECT hlslog.segment AS x, COUNT(DISTINCT hlslog. def plotly_date_handler(obj): return obj.strftime("%Y-%m-%d %H:%M:%S") -@app.route('/stats/generic/<req>') -@app.route('/stats/generic/<req>/<param>') +@app.route('/internal/stats/generic/<req>') +@app.route('/internal/stats/generic/<req>/<param>') @mod_required def stats_generic(req, param=None): if req not in statsqueries: @@ -37,8 +37,8 @@ def stats_generic(req, param=None): res[key].append(val) return Response(json.dumps([res], default=plotly_date_handler), mimetype='application/json') -@app.route('/stats/viewsperday/<req>') -@app.route('/stats/viewsperday/<req>/<param>') +@app.route('/internal/stats/viewsperday/<req>') +@app.route('/internal/stats/viewsperday/<req>/<param>') @mod_required def stats_viewsperday(req, param=""): update_expr = 'INSERT INTO logcache (req, param, trace, date, value) SELECT "%s", ?, trace, date, y FROM (%s) AS cachetmp WHERE date < ?' diff --git a/templates/embed.html b/templates/embed.html index 2c5a2ee..0871ece 100644 --- a/templates/embed.html +++ b/templates/embed.html @@ -1,6 +1,4 @@ {% from 'macros.html' import player %} -{% from 'macros.html' import video_download_btn %} -{% from 'macros.html' import video_embed_btn %} {% set page_border = 0 -%} {% extends "base.html" %} diff --git a/templates/feed.atom b/templates/feed.atom index 0144dd0..e24ad94 100644 --- a/templates/feed.atom +++ b/templates/feed.atom @@ -53,7 +53,7 @@ Veranstalter: {{ course.organizer }}<br> <name>{{ entry.speaker }}</name> </author> {% endif %} - <link rel="alternate" href="{{ url_for('lecture', id=entry.id, _external=True) }}"/> + <link rel="alternate" href="{{ url_for('lecture', course=entry.course.handle, id=entry.id, _external=True) }}"/> <link rel="enclosure" href="{{ url_for('files', filename=entry.video.path, _external=True)}}" length="{{ entry.video.file_size }}"/> <id>{{ entry.atomid }}</id> <updated>{{ entry.updated|rfc3339 }}</updated> diff --git a/templates/lecture.html b/templates/lecture.html index 96ca158..71c4b12 100644 --- a/templates/lecture.html +++ b/templates/lecture.html @@ -27,7 +27,7 @@ <a href="{{url_for('course', handle=course.handle)}}#lecture-{{lecture.id}}" class="btn btn-default" >Zur Veranstaltungsseite</a> <ul class="list-inline pull-right"> <li><button class="btn btn-default" id="hintnewchapter">Kapitelmarker vorschlagen</button></li> - <li>{{ video_embed_btn(lecture.id) }}</li> + <li>{{ video_embed_btn(lecture.id, course=course.handle) }}</li> <li class="dropdown">{{ video_download_btn(videos) }}</li> </ul> </div> diff --git a/templates/macros.html b/templates/macros.html index 07313d7..9395650 100644 --- a/templates/macros.html +++ b/templates/macros.html @@ -1,6 +1,6 @@ {% macro preview(lecture) %} <li class="list-group-item"> - <a href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture.course.title }}" style="color: #000"> + <a href="{{url_for('lecture', course=lecture.course.handle, id=lecture['id'])}}" title="{{ lecture.course.title }}" style="color: #000"> <div class="hidden-xs"> <div class="row"> <img class="col-xs-4" style="max-height: 120px; height: auto; width:170px" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; "> @@ -144,12 +144,12 @@ $(function() { {% endif %} {% endmacro %} -{%macro video_embed_btn(lectureid) %} +{%macro video_embed_btn(lectureid, course=None) %} <a class="btn btn-default" id="embedcodebtn" data-container="body" data-toggle="popover" data-placement="bottom"> <span>Einbetten</span> </a> <script> -{% set embedcode = '<iframe width="700" height="394" src="'+url_for('embed', id=lectureid, _external=True)+'" frameborder="0" allowfullscreen="true"></iframe>' %} +{% set embedcode = '<iframe width="700" height="394" src="'+url_for('embed', course=course, id=lectureid, _external=True)+'" frameborder="0" allowfullscreen="true"></iframe>' %} $('#embedcodebtn').popover( { html:true, @@ -165,7 +165,7 @@ $('#embedcodebtn').popover( <div class="row"> <div style="background-image: url('{% if not lecture.titlefile %}{{url_for('static',filename='no-thumbnail.png')}}{% else %}{{ config.VIDEOPREFIX }}/{{lecture.titlefile}}'){% endif %}" class="col-sm-2 col-xs-12 thumbnailimg"> {% if not videos|length is equalto 0 %} - <a href="{{url_for('lecture', id=lecture.id)}}"> + <a href="{{url_for('lecture', course=lecture.course.handle, id=lecture.id)}}"> <span class="glyphicon glyphicon-play-circle playpreviewbtn"></span> </a> {% endif %} diff --git a/timetable.py b/timetable.py index a8e18be..2ccb548 100644 --- a/timetable.py +++ b/timetable.py @@ -1,6 +1,6 @@ from server import * -@app.route('/timetable') +@app.route('/internal/timetable') @register_navbar('Drehplan', icon='calendar') @mod_required def timetable(): -- GitLab