Commit 989a7eae authored by Andreas Valder's avatar Andreas Valder
Browse files

added basics for a jobs api

parent 9d545a54
......@@ -230,6 +230,24 @@ CREATE TABLE IF NOT EXISTS `sorterrorlog_data` (
`time_created` datetime NOT NULL
);
CREATE TABLE IF NOT EXISTS `worker` (
`hostname` text NOT NULL PRIMARY KEY,
`last_ping` datetime NOT NULL
);
CREATE TABLE IF NOT EXISTS `jobs` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`type` text NOT NULL,
`priority` INTEGER NOT NULL DEFAULT 0,
`state` text NOT NULL DEFAULT 'ready',
`time_finished` datetime DEFAULT '',
`time_created` datetime NOT NULL,
`last_ping` datetime NOT NULL DEFAULT '',
`worker` text DEFAULT NULL,
`data` text NOT NULL DEFAULT '{}',
`status` text NOT NULL DEFAULT '{}'
);
CREATE VIEW IF NOT EXISTS `courses` AS select * from `courses_data` where (not(`courses_data`.`deleted`));
CREATE VIEW IF NOT EXISTS `lectures` AS select `lectures_data`.* from `lectures_data` join `courses_data` on (`courses_data`.`id` = `course_id`) where (not(`lectures_data`.`deleted` or `courses_data`.`deleted`));
CREATE VIEW IF NOT EXISTS `videos` AS select `videos_data`.* from `videos_data` join `lectures_data` on (`lectures_data`.`id` = `lecture_id`) join `courses_data` on (`courses_data`.`id` = `course_id`) where (not(`videos_data`.`deleted` or `lectures_data`.`deleted` or `courses_data`.`deleted`));
......
from server import *
import traceback
import json
@app.route('/jobs/overview')
@register_navbar('Jobs', iconlib='fa', icon='suitcase')
@mod_required
def jobs_overview():
# todo
return render_template('base.html')
worker = query('SELECT * FROM worker ORDER BY last_ping DESC')
jobs = query('SELECT * FROM jobs')
return render_template('jobs_overview.html',worker=worker,jobs=jobs)
@app.route('/jobs/api', methods=['GET', 'POST'])
@mod_required
def jobs_api():
# todo
return render_template('base.html')
def jobs_api_token_required(func):
@wraps(func)
def decorator(*args, **kwargs):
if 'apikey' in request.values:
token = request.values['apikey']
elif request.get_json() and ('apikey' in request.get_json()):
token = request.get_json()['apikey']
else:
token = None
if not token == config['JOBS_API_KEY']:
return 'Permission denied', 403
else:
return func(*args, **kwargs)
return decorator
def date_json_handler(obj):
return obj.isoformat() if hasattr(obj, 'isoformat') else obj
@app.route('/jobs/api/ping', methods=['GET', 'POST'])
@jobs_api_token_required
def jobs_ping():
hostname = request.values['host']
query('INSERT OR REPLACE INTO worker (hostname, last_ping) values (?, ?)',hostname,datetime.now())
return 'OK',200
@app.route('/jobs/api/schedule', methods=['POST'])
@jobs_api_token_required
def jobs_schedule():
hostdata = request.get_json()
print(hostdata)
if not hostdata:
return 'no data', 500
jobtypes = hostdata['jobtypes'] if 'jobtypes' in hostdata else []
for i in query('SELECT * FROM jobs WHERE state = "ready" ORDER BY priority DESC'):
if i['type'] in hostdata['jobtypes'].split(','):
job=i
break
return Response(json.dumps(job, default=date_json_handler), mimetype='application/json')
......@@ -10,7 +10,6 @@ import random
import sched
import traceback
import string
import traceback
app = Flask(__name__)
......
......@@ -33,7 +33,25 @@ def insert_video(lectureid,dbfilepath,filepath,fileformatid):
(?,0,?,?,"","","",?,?,?,?,"",?)''',
lectureid, dbfilepath, fileformatid, datetime.now(), datetime.now(), datetime.now(), -1, os.stat(filepath).st_size)
query('INSERT INTO sortlog (lecture_id,video_id,path,`when`) VALUES (?,?,?,?)', lectureid, video_id, dbfilepath, datetime.now())
schedule_thumbnail(lectureid)
def schedule_thumbnail(lectureid):
exists = query('SELECT * FROM jobs WHERE data LIKE ?','%"lectureid": "'+str(lectureid)+'"%' )
if exists:
return
path = query('SELECT path FROM videos WHERE lecture_id')
videos = query('''
SELECT videos.path
FROM videos
JOIN formats ON (videos.video_format = formats.id)
WHERE videos.lecture_id = ?
ORDER BY formats.prio DESC''', lectureid )
if videos:
path = videos[0]['path']
else:
return
data = '{"lectureid": "'+str(lectureid)+'", "path": "'+path+'"}'
query('INSERT INTO jobs (type, data, time_created) VALUES ("thumbnail", ?, ?)', data, datetime.now());
@app.route('/sort/now')
@mod_required
......
{% extends "base.html" %}
{% block content %}
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="panel-title">
Worker
</h1>
</div>
<div class="panel-collapse collapse in">
<div class="panel-body">
<table class="table">
<tr>
<th>Hostname</th>
<th>letzter Ping</th>
</tr>
{% for i in worker %}
{% set td = (datetime.now()-(i.last_ping) ) %}
{% if td < timedelta(seconds=10) %}
<tr class="success">
{% elif td < timedelta(seconds=30) %}
<tr class="warning">
{% else %}
<tr class="danger">
{% endif %}
<td>{{i.hostname}}</td>
<td>{{i.last_ping}}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="panel-title">
Jobs
</h1>
</div>
<div class="panel-collapse collapse in">
<div class="panel-body">
<table class="table">
<tr>
<th>ID</th>
<th>Type</th>
<th>Priority</th>
<th>Worker</th>
<th>letzter Ping</th>
<th>State</th>
<th>Eingereiht am</th>
<th>Fertig geworden am</th>
<th>Daten</th>
</tr>
{% for i in jobs %}
{% if i.last_ping %}
{% set td = (datetime.now()-(i.last_ping) ) %}
{% else %}
{% set td = -1 %}
{% endif %}
{% if td == -1 %}
<tr>
{% elif td < timedelta(seconds=20) %}
<tr class="success">
{% elif td < timedelta(seconds=60) %}
<tr class="warning">
{% else %}
<tr class="danger">
{% endif %}
<td>{{i.id}}</td>
<td>{{i.type}}</td>
<td>{{i.priority}}</td>
<td>{{i.worker}}</td>
<td>{{i.last_ping}}</td>
<td>{{i.state}}</td>
<td>{{i.time_created}}</td>
<td>{{i.time_finished}}</td>
<td>{{i.data}}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
</div>
{% endblock %}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment