diff --git a/edit.py b/edit.py index e12116f1c02d39c9c67d8d03c962eebf17c7e170..f9eafb7ea944f7d0dcb5e0a34578b5559661c70f 100644 --- a/edit.py +++ b/edit.py @@ -119,6 +119,18 @@ def getfielddescription(path): desc = '<br>'+desc return desc +edit_handlers = {} +def edit_handler(*tables, field=None): + def wrapper(func): + for table in tables: + if table not in edit_handlers: + edit_handlers[table] = {} + if field not in edit_handlers[table]: + edit_handlers[table][field] = [] + edit_handlers[table][field].append(func) + return func + return wrapper + @app.route('/internal/edit', methods=['GET', 'POST']) @mod_required @csrf_protect @@ -141,6 +153,10 @@ def edit(prefix='', ignore=[]): VALUES (?,?,?,?,?,(SELECT `%s` FROM %s WHERE %s = ?),?,?,1)'%(path['column'], path['tableinfo']['table'], path['tableinfo']['idcolumn']), path['table'], path['id'], path['tableinfo']['idcolumn'], path['column'], val, path['id'], datetime.now(), session['user']['dbid']) modify('UPDATE %s SET `%s` = ?, time_updated = ? WHERE `%s` = ?'%(path['tableinfo']['table'], path['column'], path['tableinfo']['idcolumn']), val, datetime.now(),path['id']) + for func in edit_handlers.get(path['table'], {}).get(None, []): + func(path['table'], path['column'], val, path['id']) + for func in edit_handlers.get(path['table'], {}).get(path['column'], []): + func(path['table'], path['column'], val, path['id']) if 'ref' in request.values: return redirect(request.values['ref']) return "OK", 200 diff --git a/jobs.py b/jobs.py index 432935beed319e7c99558bd410d49f3b4c4764f4..0718d7d5f6cb4dd87557f813d29a3a8e8dd53eb0 100644 --- a/jobs.py +++ b/jobs.py @@ -67,7 +67,7 @@ def jobs_api_token_required(func): else: token = None - if not token == config['JOBS_API_KEY']: + if not token == config.get('JOBS_API_KEY', [None]): return 'Permission denied', 403 else: return func(*args, **kwargs) @@ -99,6 +99,25 @@ def jobs_worker_ping(hostname): query('REPLACE INTO worker (hostname, last_ping) values (?, ?)', hostname, datetime.now()) return 'OK',200 +job_handlers = {} +def job_handler(*types, state='finished'): + def wrapper(func): + for jobtype in types: + if jobtype not in job_handlers: + job_handlers[jobtype] = {} + if jobtype not in job_handlers[jobtype]: + job_handlers[jobtype][state] = [] + job_handlers[jobtype][state].append(func) + return func + return wrapper + +def schedule_job(jobtype, data=None, priority=0): + if not data: + data = {} + modify('INSERT INTO jobs (type, priority, data, time_created) VALUES (?, ?, ?, ?)', + jobtype, priority, json.dumps(data, default=date_json_handler), datetime.now()) + + @app.route('/internal/jobs/api/job/<int:id>/ping', methods=['GET', 'POST']) @jobs_api_token_required def jobs_ping(id): @@ -109,7 +128,13 @@ def jobs_ping(id): query('UPDATE jobs SET time_finished = ?, status = ?, state = "finished" where id = ?', datetime.now(), status, id) else: query('UPDATE jobs SET worker = ?, last_ping = ?, status = ?, state = ? where id = ?', hostname, datetime.now(), status, state, id) - return 'OK',200 + job = query('SELECT * FROM jobs WHERE id = ?', id)[0] + for func in job_handlers.get(job['type'], {}).get(state, []): + try: + func(id, job['type'], json.loads(job['data']), state, json.loads(job['status'])) + except Exception: + traceback.print_exc() + return 'OK', 200 @app.route('/internal/jobs/api/worker/<hostname>/schedule', methods=['POST']) @jobs_api_token_required diff --git a/server.py b/server.py index 0d6884800832851607080f4dafdd777e0a8fe1e3..e3f0acc17b3371b6040be5c8273cc9a742579b17 100644 --- a/server.py +++ b/server.py @@ -461,7 +461,7 @@ def dbstatus(): clusters[cluster].append(host) return render_template('dbstatus.html', clusters=clusters, statuses=status, vars=variables), 200 -import edit +from edit import edit_handler import feeds import importer import stats @@ -469,8 +469,7 @@ import sorter if 'ICAL_URL' in config: import meetings import l2pauth -if 'JOBS_API_KEY' in config: - import jobs +from jobs import job_handler, schedule_job import timetable import chapters import icalexport