diff --git a/jobs.py b/jobs.py
index 0341017121fc03553c82b89e9d115c64819f5248..435da737eb1fdcadc9462d01c7cb977d66bcdcd6 100644
--- a/jobs.py
+++ b/jobs.py
@@ -2,6 +2,7 @@ from server import *
 import traceback
 import json
 import random
+from sorter import schedule_thumbnail
 
 @app.route('/internal/jobs/overview')
 @register_navbar('Jobs', iconlib='fa',  icon='suitcase')
@@ -34,6 +35,28 @@ def jobs_overview():
 	jobs = query('SELECT * FROM jobs WHERE (type like ?) AND (worker like ? OR (worker IS NULL AND ? = "%")) AND (state like ?) ORDER BY `time_created` DESC LIMIT ? OFFSET ?', filter['type'], filter['worker'], filter['worker'], filter['state'], pagesize, page*pagesize)
 	return render_template('jobs_overview.html',worker=worker,jobs=jobs, filter_values=filter_values, filter=filter, page=page, pagesize=pagesize, pagecount=pagecount)
 
+@app.route('/internal/jobs/action/<action>', methods=['GET', 'POST'])
+@app.route('/internal/jobs/action/<action>/<jobid>', methods=['GET', 'POST'])
+@mod_required
+@csrf_protect
+def jobs_action(action, jobid=None):
+	if action == 'clear_failed':
+		query('UPDATE jobs SET state="deleted" WHERE state = "failed" AND (id = ? OR ? IS NULL)', jobid, jobid)
+	if action == 'retry_failed':
+		query('UPDATE jobs SET state="ready" WHERE state = "failed" AND (id = ? OR ? IS NULL)', jobid, jobid)
+	if action == 'copy':
+		if jobid:
+			query("INSERT INTO jobs SELECT NULL, type, priority, 'ready', '', '' , ?, '', NULL, data, '{}' FROM jobs where ID=?;", datetime.now(), jobid)
+	if action == 'delete':
+		if jobid:
+			query('UPDATE jobs SET state="deleted" WHERE id = ?', jobid)
+	if action == 'add':
+		jobtype = request.values.get('type', None)
+		if jobtype == 'thumbnail':
+			lectureid = int(request.values.get('lecture_id', -1))
+			schedule_thumbnail(lectureid)
+	return redirect(request.values.get('ref', url_for('jobs_overview')))
+
 def jobs_api_token_required(func):
 	@wraps(func)
 	def decorator(*args, **kwargs):
diff --git a/server.py b/server.py
index e5f4441849c6a64b368388b69d15a3b1cdf13e83..f535a6caa94d012244b4d8412d59ced03b4f71d9 100644
--- a/server.py
+++ b/server.py
@@ -528,7 +528,7 @@ def login():
 		modify('INSERT INTO users (name, realname, fsacc, level, calendar_key, rfc6238) VALUES (?, ?, ?, 1, "", "")', user, session['user']['givenName'], user)
 		dbuser = query('SELECT * FROM users WHERE name = ?', user)
 	session['user']['dbid'] = dbuser[0]['id']
-	session['_csrf_token'] = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(128))
+	session['_csrf_token'] = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(64))
 	session.permanent = True
 	return redirect(request.values.get('ref', url_for('index')))
 
diff --git a/sorter.py b/sorter.py
index 1e0f80be35c3046dace946cb0703c91b1716850e..720c6d34550f7170af56c1747f1caf9aa3bd7418 100644
--- a/sorter.py
+++ b/sorter.py
@@ -36,9 +36,6 @@ def insert_video(lectureid,dbfilepath,filepath,fileformatid):
 	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
diff --git a/templates/jobs_overview.html b/templates/jobs_overview.html
index 161aa6cb79f6f1a480f2e366148fc129115037b1..9cdd5e1cae86e11ab5313d5cf091dc2b0d98dd9a 100644
--- a/templates/jobs_overview.html
+++ b/templates/jobs_overview.html
@@ -1,4 +1,39 @@
 {% extends "base.html" %}
+
+{% block modals %}
+	{{ super() }}
+
+	<div class="modal fade" id="modal_addjob" role="dialog">
+		<div class="modal-dialog">
+			<div class="modal-content">
+				<div class="modal-header">
+					<button type="button" class="close" data-dismiss="modal">&times;</button>
+					Neue(n) Job(s) erzeugen
+				</div>
+				<div class="modal-body">
+					<ul class="nav nav-tabs" role="tablist">
+						<li role="presentation" class="active"><a href="#add_thtumbnail" aria-controls="thumbnail" role="tab" data-toggle="tab">Thumbnaile</a></li>
+					</ul>
+
+					<div class="tab-content" style="margin-top: 10px;">
+						<div role="tabpanel" class="tab-pane active" id="add_thumbnail">
+							<form class="form-inline" action="{{url_for('jobs_action', action='add', ref=request.url)}}" method="post">
+								<div class="form-group">
+									<input type="hidden" name="type" value="thumbnail">
+									<input type="text" class="form-control" id="thumbnail_lectureid" placeholder="Lecture ID" name="lecture_id">
+									<button type="submit" class="btn btn-primary">Hinzufügen</button>
+								</div>
+							</form>
+						</div>
+					</div>
+				</div>
+				<div class="modal-footer">
+				</div>
+			</div>
+		</div>
+	</div>
+{% endblock %}
+
 {% block content %}
 <div class="panel-group">
 	<div class="panel panel-default">
@@ -34,9 +69,12 @@
 	</div>
 	<div class="panel panel-default">
 		<div class="panel-heading">
-				<h1 class="panel-title">
-					Jobs
-				</h1>
+			<h1 class="panel-title">
+				Jobs
+				<a class="btn btn-default" href="javascript:$('#modal_addjob').modal()" >Job(s) erzeugen</a>
+				<a class="btn btn-default" href="{{url_for('jobs_action', action='clear_failed', ref=request.url)}}" >Alle fehlgeschlagenen Jobs löschen</a>
+				<a class="btn btn-default" href="{{url_for('jobs_action', action='retry_failed', ref=request.url)}}" >Alle fehlgeschlagenen Jobs neustarten</a>
+			</h1>
 		</div>
 		<div class="panel-collapse collapse in">
 			<div class="panel-body">
@@ -109,6 +147,7 @@
 							<th>Gescheduled am</th>
 							<th>Daten</th>
 							<th>Status</th>
+							<th></th>
 						</tr>
 						{% for i in jobs %}
 							{% if i.last_ping %}
@@ -137,6 +176,33 @@
 								<td>{{i.time_scheduled}}</td>
 								<td>{{i.data}}</td>
 								<td>{{i.status}}</td>
+								<td>
+									<ul class="list-inline" style="white-space: nowrap;">
+									{% if i.state == "failed" %}
+										<li>
+											<a class="btn btn-default" href="{{url_for('jobs_action', action='clear_failed', jobid=i.id, ref=request.url)}}" title="Löschen" style="background-color: red;">
+												<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
+											</a>
+										</li>
+										<li>
+											<a class="btn btn-default" href="{{url_for('jobs_action', action='retry_failed', jobid=i.id, ref=request.url)}}" title="Neustarten">
+												<span class="fa fa-refresh" aria-hidden="true"></span>
+											</a>
+										</li>
+									{% else %}
+										<li>
+											<a class="btn btn-default" href="{{url_for('jobs_action', action='delete', jobid=i.id, ref=request.url)}}" title="Löschen" style="background-color: red;">
+												<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
+											</a>
+										</li>
+										<li>
+											<a class="btn btn-default" href="{{url_for('jobs_action', action='copy', jobid=i.id, ref=request.url)}}" title="Kopie neu einreihen">
+												<span class="fa fa-refresh" aria-hidden="true"></span>
+											</a>
+										</li>
+									{% endif %}
+									</ul>
+								</td>
 							</tr>
 						{% endfor %}
 					</table>