diff --git a/config.py.example b/config.py.example index 27254fd575acc9c1fa6df3b8cd010a416665f876..53d80f9c653466db9f9c7732449abac8a5647123 100644 --- a/config.py.example +++ b/config.py.example @@ -19,3 +19,4 @@ SQLITE_INIT_SCHEMA = True SQLITE_INIT_DATA = False #LDAP_HOST = 'ldaps://rumo.fsmpi.rwth-aachen.de' +#ICAL_URL = 'https://user:password@mail.fsmpi.rwth-aachen.de/SOGo/....ics' diff --git a/db_schema.sql b/db_schema.sql index f5e1fbf63a42173719aaa78d6c9d1106dd73e580..b0c5c1fb89e7483d133aad71ebe40184dc3209a9 100644 --- a/db_schema.sql +++ b/db_schema.sql @@ -84,19 +84,19 @@ CREATE TABLE IF NOT EXISTS `lectures_data` ( `visible` INTEGER NOT NULL DEFAULT '1', `timed_release` datetime DEFAULT NULL, `use_timed_release` INTEGER NOT NULL DEFAULT '0', - `drehplan` varchar(10) NOT NULL, + `drehplan` varchar(10) NOT NULL DEFAULT '', `deleted` INTEGER NOT NULL DEFAULT '0', - `title` text NOT NULL, - `comment` text NOT NULL, - `internal` text NOT NULL, - `speaker` text NOT NULL, - `place` text NOT NULL, + `title` text NOT NULL DEFAULT '', + `comment` text NOT NULL DEFAULT '', + `internal` text NOT NULL DEFAULT '', + `speaker` text NOT NULL DEFAULT '', + `place` text NOT NULL DEFAULT '', `time` datetime NOT NULL, `duration` INTEGER NOT NULL DEFAULT '90', `time_created` datetime NOT NULL, `time_updated` datetime NOT NULL, - `jumplist` text NOT NULL, - `titlefile` varchar(255) NOT NULL + `jumplist` text NOT NULL DEFAULT '', + `titlefile` varchar(255) NOT NULL DEFAULT '' ); CREATE TABLE IF NOT EXISTS `places` ( `place` varchar(20) NOT NULL PRIMARY KEY, diff --git a/meetings.py b/meetings.py index 57b3e505b6720a7836918ad2371f01a928e13af9..0eb0195fcb04fceca2140f7de6f6665102e3bd97 100644 --- a/meetings.py +++ b/meetings.py @@ -21,6 +21,7 @@ def get_next_meeting(): event = sorted(meetings, key=lambda e: e['DTSTART'].dt)[0] return str(event['UID']), event['DTSTART'].dt.replace(tzinfo=None) +@sched_func(60*60) def update_meeting(): try: uid, start = get_next_meeting() diff --git a/server.py b/server.py index dde9977c0cd31f880bf177c9086f4897a01e1342..fb2271c6ccf87d16799263143e8c889e3872afc5 100644 --- a/server.py +++ b/server.py @@ -7,6 +7,8 @@ import os import sys import hashlib import random +import sched +import time app = Flask(__name__) @@ -16,15 +18,25 @@ app.add_template_global(random.randint, name='randint') app.add_template_global(datetime, name='datetime') app.add_template_global(timedelta, name='timedelta') -def timer_func(): - with app.test_request_context(): - pass # do something - timer = threading.Timer(60*60, timer_func) - timer.start() +scheduler = sched.scheduler() +def run_scheduler(): + time.sleep(1) # UWSGI does weird things on startup + while True: + scheduler.run() -timer = threading.Timer(0, timer_func) -timer.daemon = True -timer.start() +def sched_func(delay, priority=0, firstdelay=None, args=[], kargs={}): + if firstdelay == None: + firstdelay = random.randint(1, 120) + def wrapper(func): + def sched_wrapper(): + with app.test_request_context(): + func(*args, *kargs) + scheduler.enter(delay, priority, sched_wrapper) + scheduler.enter(firstdelay, priority, sched_wrapper) + return func + return wrapper + +threading.Thread(target=run_scheduler, daemon=True).start() config = app.config config.from_pyfile('config.py.example', silent=True) @@ -257,13 +269,22 @@ def logout(): tabs = { 'courses': ('courses_data', 'id', ['visible', 'listed', 'title', 'short', 'handle', 'organizer', 'subject', 'semester', 'downloadable', - 'internal', 'responsible','deleted']), + 'internal', 'responsible','deleted'], + ['created_by', 'time_created', 'time_updated']), 'lectures': ('lectures_data', 'id', ['visible', 'title', 'comment', - 'internal', 'speaker', 'place', 'time', 'duration', 'jumplist','deleted']), - 'videos': ('videos_data', 'id', ['visible','deleted']), - 'chapters': ('chapters', 'id', ['time', 'text', 'visible', 'deleted']), - 'announcements': ('announcements', 'id', ['text', 'level', 'visible', 'deleted', 'time_publish', 'time_expire']), - 'featured': ('featured', 'id', ['title', 'text', 'internal', 'visible', 'deleted']) + 'internal', 'speaker', 'place', 'time', 'duration', 'jumplist','deleted'], + ['course_id', 'time_created', 'time_updated']), + 'videos': ('videos_data', 'id', ['visible','deleted'], + ['created_by', 'time_created', 'time_updated']), + 'chapters': ('chapters', 'id', ['time', 'text', 'visible', 'deleted'], + ['created_by', 'time_created', 'time_updated']), + 'announcements': ('announcements', 'id', ['text', 'level', 'visible', + 'deleted', 'time_publish', 'time_expire'], + ['created_by', 'time_created', 'time_updated']), + 'featured': ('featured', 'id', ['title', 'text', 'internal', 'visible', 'deleted'], + ['created_by', 'time_created', 'time_updated']), + 'auth': ('auth', 'auth_id', ['auth_type', 'auth_user', 'auth_passwd'], + ['course_id', 'lecture_id', 'video_id']) } @app.route('/edit', methods=['GET', 'POST']) @@ -275,11 +296,9 @@ def edit(prefix='', ignore=[]): if not prefix and 'prefix' in request.args: prefix = request.args['prefix'] modify('BEGIN') + changes = request.values.items() if request.is_json: changes = request.get_json().items() - else: - changes = request.args.items() - created = {} for key, val in changes: if key in ignore: continue @@ -299,23 +318,25 @@ def edit(prefix='', ignore=[]): @mod_required def create(table): assert table in tabs - id = modify('INSERT INTO %s (created_by, time_created, time_updated) VALUES (?, ?, ?)'%tabs[table][0], - session['user']['dbid'], datetime.now(), datetime.now()) - edit(prefix=table+'.'+str(id)+'.') - if 'ref' in request.values: - return redirect(request.values['ref']) - return str(id), 200 - -@app.route('/newlecture/<courseid>', methods=['GET', 'POST']) -@mod_required -def new_lecture(courseid): - id = modify(''' - INSERT INTO lectures_data - (course_id, visible, drehplan, title, comment, internal, speaker, place, - time, time_created, time_updated, jumplist, titlefile) - VALUES (?, 0, "", "Noch kein Titel", "", "", "", "", ?, ?, ?, "", "") - ''', courseid, datetime.now(), datetime.now(), datetime.now()) - edit(prefix='lectures.'+str(id)+'.', ignore=['ref']) + defaults = {'created_by': session['user']['dbid'], 'time_created': datetime.now(), 'time_updated': datetime.now()} + columns = [] + values = [] + for column, val in defaults.items(): + if column in tabs[table][3]: + columns.append(column) + values.append(val) + args = request.values + if request.is_json: + args = request.get_json() + for column, val in args.items(): + if column == 'ref': + continue + assert column in tabs[table][2]+tabs[table][3] + assert column not in defaults + columns.append(column) + values.append(val) + id = modify('INSERT INTO %s (%s) VALUES (%s)'%(tabs[table][0], + ','.join(columns), ','.join(['?']*len(values))), *values) if 'ref' in request.values: return redirect(request.values['ref']) return str(id), 200 @@ -432,3 +453,5 @@ import feeds import importer import schedule import sorter +if 'ICAL_URL' in config: + import meetings diff --git a/templates/course.html b/templates/course.html index 48c70f6fff3c0cd544dc26f55ca45e64d335b590..7d421e6b7852d714c96459f554f0bd1a59822002 100644 --- a/templates/course.html +++ b/templates/course.html @@ -38,7 +38,7 @@ </div> <div class="panel panel-default"> <div class="panel-heading"> - <h1 class="panel-title">Videos{% if ismod() %} <a class="btn btn-default" style="margin-right: 5px;" href="{{ url_for('new_lecture', courseid=course.id, ref=request.url) }}">Neuer Termin</a><a class="btn btn-default" style="margin-right: 5px;" href="{{url_for('import_from', id=course['id'])}}">Campus Import</a>{% endif %} <a class="fa fa-rss-square pull-right" aria-hidden="true" href="{{url_for('feed', handle=course.handle)}}"></a> </h1> + <h1 class="panel-title">Videos{% if ismod() %} <a class="btn btn-default" style="margin-right: 5px;" href="{{ url_for('create', table='lectures', time=datetime.now(), title='Noch kein Titel', course_id=course.id, ref=request.url) }}">Neuer Termin</a><a class="btn btn-default" style="margin-right: 5px;" href="{{url_for('import_from', id=course['id'])}}">Campus Import</a>{% endif %} <a class="fa fa-rss-square pull-right" aria-hidden="true" href="{{url_for('feed', handle=course.handle)}}"></a> </h1> </div> <ul class="list-group lectureslist"> {% for l in lectures %} diff --git a/templates/import_campus.html b/templates/import_campus.html index 3240907f378a18c060308c0c9222f19ccd715e67..3a5819f6ec729836a183d4d439597b60f3d0854a 100644 --- a/templates/import_campus.html +++ b/templates/import_campus.html @@ -90,7 +90,7 @@ {{ valuedeletebtn(['lectures',i.id,'deleted']) }} {% endif%} {% if (i.type == 'import') %} - <button class="btn btn-default newlecture" onclick="moderatorinterface.gethttp('{{ url_for('new_lecture', courseid=course.id, time=i.time, title=i.title, place=i.place) }}')">anlegen</a> + <button class="btn btn-default newlecture" onclick="moderatorinterface.gethttp('{{ url_for('create', table='lecture', course_id=course.id, time=i.time, title=i.title, place=i.place) }}')">anlegen</a> {% endif%} </span> </span>