mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 01:05:42 +00:00
Add admin view on foreign jobs.
This commit is contained in:
parent
0ea87de072
commit
1ebfee5cb3
@ -1,9 +1,11 @@
|
|||||||
from flask import current_app, request
|
from flask import current_app, request
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
|
from ..decorators import admin_required
|
||||||
from .. import db, socketio
|
from .. import db, socketio
|
||||||
from ..models import User
|
from ..models import User
|
||||||
import json
|
import json
|
||||||
import jsonpatch
|
import jsonpatch
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -28,6 +30,26 @@ def connect():
|
|||||||
request.sid)
|
request.sid)
|
||||||
|
|
||||||
|
|
||||||
|
@socketio.on('connect_admin')
|
||||||
|
@login_required
|
||||||
|
@admin_required
|
||||||
|
def connect_admin(selected_user_id):
|
||||||
|
'''
|
||||||
|
' The Socket.IO module creates a session id (sid) on each request. The
|
||||||
|
' initiating admin is automatically placed in a room with that sid, which
|
||||||
|
' will be used for further information exchange generated by a background
|
||||||
|
' task associated with the sid. Admin will be placed in that room on emiting
|
||||||
|
' "conncect_admin".
|
||||||
|
'''
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.warning('Admin emitted "connect_admin".')
|
||||||
|
logger.warning('Selected user id is: {}'.format(selected_user_id))
|
||||||
|
socketio.start_background_task(background_task_foreign,
|
||||||
|
current_app._get_current_object(),
|
||||||
|
selected_user_id,
|
||||||
|
request.sid)
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('disconnect')
|
@socketio.on('disconnect')
|
||||||
@login_required
|
@login_required
|
||||||
def disconnect():
|
def disconnect():
|
||||||
@ -51,9 +73,13 @@ def background_task(app, user_id, session_id):
|
|||||||
'''
|
'''
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
user = db.session.query(User).filter_by(id=user_id).first()
|
user = db.session.query(User).filter_by(id=user_id).first()
|
||||||
|
logging.getLogger(__name__)
|
||||||
|
logging.warning('User object is: {}'.format(user))
|
||||||
''' Get current values from the database. '''
|
''' Get current values from the database. '''
|
||||||
corpora = user.corpora_as_dict()
|
corpora = user.corpora_as_dict()
|
||||||
|
logging.warning('Corpora are: {}'.format(corpora))
|
||||||
jobs = user.jobs_as_dict()
|
jobs = user.jobs_as_dict()
|
||||||
|
logging.warning('Jobs are: {}'.format(jobs))
|
||||||
''' Send initial values. '''
|
''' Send initial values. '''
|
||||||
socketio.emit('init-corpora',
|
socketio.emit('init-corpora',
|
||||||
json.dumps(corpora),
|
json.dumps(corpora),
|
||||||
@ -83,3 +109,54 @@ def background_task(app, user_id, session_id):
|
|||||||
jobs = new_jobs
|
jobs = new_jobs
|
||||||
socketio.sleep(3)
|
socketio.sleep(3)
|
||||||
disconnected.remove(session_id)
|
disconnected.remove(session_id)
|
||||||
|
|
||||||
|
|
||||||
|
def background_task_foreign(app, user_id, session_id):
|
||||||
|
'''
|
||||||
|
' Sends initial corpus and job lists to the client. Afterwards it checks
|
||||||
|
' every 3 seconds if changes to the initial values appeared. If changes are
|
||||||
|
' detected, a RFC 6902 compliant JSON patch gets send.
|
||||||
|
'
|
||||||
|
' NOTE: The initial values are send as a init-* events.
|
||||||
|
' The JSON patches are send as update-* events.
|
||||||
|
'
|
||||||
|
' > where '*' is either 'corpora' or 'jobs'
|
||||||
|
'''
|
||||||
|
with app.app_context():
|
||||||
|
user = db.session.query(User).filter_by(id=user_id).first()
|
||||||
|
logging.getLogger(__name__)
|
||||||
|
logging.warning('User object is: {}'.format(user))
|
||||||
|
''' Get current values from the database. '''
|
||||||
|
corpora = user.corpora_as_dict()
|
||||||
|
logging.warning('Corpora are: {}'.format(corpora))
|
||||||
|
jobs = user.jobs_as_dict()
|
||||||
|
logging.warning('Jobs are: {}'.format(jobs))
|
||||||
|
''' Send initial values. '''
|
||||||
|
socketio.emit('init-foreign-corpora',
|
||||||
|
json.dumps(corpora),
|
||||||
|
room=session_id)
|
||||||
|
socketio.emit('init-foreign-jobs',
|
||||||
|
json.dumps(jobs),
|
||||||
|
room=session_id)
|
||||||
|
''' TODO: Implement maximum runtime for this loop. '''
|
||||||
|
while session_id not in disconnected:
|
||||||
|
''' Get current values from the database '''
|
||||||
|
new_corpora = user.corpora_as_dict()
|
||||||
|
new_jobs = user.jobs_as_dict()
|
||||||
|
''' Compute JSON patches. '''
|
||||||
|
corpus_patch = jsonpatch.JsonPatch.from_diff(corpora, new_corpora)
|
||||||
|
jobs_patch = jsonpatch.JsonPatch.from_diff(jobs, new_jobs)
|
||||||
|
''' In case there are patches, send them to the user. '''
|
||||||
|
if corpus_patch:
|
||||||
|
socketio.emit('update-foreign-corpora',
|
||||||
|
corpus_patch.to_string(),
|
||||||
|
room=session_id)
|
||||||
|
if jobs_patch:
|
||||||
|
socketio.emit('update-foreign-jobs',
|
||||||
|
jobs_patch.to_string(),
|
||||||
|
room=session_id)
|
||||||
|
''' Set new values as references for the next iteration. '''
|
||||||
|
corpora = new_corpora
|
||||||
|
jobs = new_jobs
|
||||||
|
socketio.sleep(3)
|
||||||
|
disconnected.remove(session_id)
|
||||||
|
@ -21,50 +21,41 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var selected_user_id = {{selected_user.id|tojson|safe}}
|
||||||
|
socket.emit('connect_admin', selected_user_id);
|
||||||
|
</script>
|
||||||
<div class="col s12 m6">
|
<div class="col s12 m6">
|
||||||
<div class="card large">
|
<div id="job-list">
|
||||||
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<span class="card-title">User Jobs</span>
|
<div class="row">
|
||||||
<div id="users">
|
<div class="col s12">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<i class="material-icons prefix">search</i>
|
<i class="material-icons prefix">search</i>
|
||||||
<input id="search-corpus" class="search" type="text"></input>
|
<input id="search-job" class="search" type="text"></input>
|
||||||
<label for="search-corpus">Search jobs</label>
|
<label for="search-job">Search job</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="collection list">
|
|
||||||
{% for job in selected_user.jobs.all() %}
|
|
||||||
{% if job.service == 'nlp' %}
|
|
||||||
{% set service_color = 'blue' %}
|
|
||||||
{% set service_icon = 'format_textdirection_l_to_r' %}
|
|
||||||
{% elif job.service =='ocr' %}
|
|
||||||
{% set service_color = 'green' %}
|
|
||||||
{% set service_icon = 'find_in_page' %}
|
|
||||||
{% else %}
|
|
||||||
{% set service_color = 'red' %}
|
|
||||||
{% set service_icon = 'help' %}
|
|
||||||
{% endif %}
|
|
||||||
{% if job.status == 'pending' %}
|
|
||||||
{% set badge_color = 'amber' %}
|
|
||||||
{% elif job.status =='running' %}
|
|
||||||
{% set badge_color = 'indigo' %}
|
|
||||||
{% elif job.status =='complete' %}
|
|
||||||
{% set badge_color = 'teal' %}
|
|
||||||
{% else %}
|
|
||||||
{% set badge_color = 'red' %}
|
|
||||||
{% endif %}
|
|
||||||
<a href="{{ url_for('main.job', job_id=job.id) }}" class="collection-item avatar">
|
|
||||||
<i class="material-icons circle {{ service_color }}">{{ service_icon }}</i>
|
|
||||||
<span class="new badge {{ badge_color }}" data-badge-caption="">{{ job.status }}</span>
|
|
||||||
<span class="title">{{ job.title }}</span>
|
|
||||||
<p>{{ job.description }}</p>
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col s12">
|
||||||
<ul class="pagination"></ul>
|
<ul class="pagination"></ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="collection list"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
var jobList = new JobList("job-list", {
|
||||||
|
item: '<div><span class="title"></span><span class="description"></span></div>',
|
||||||
|
page: 4,
|
||||||
|
pagination: true,
|
||||||
|
valueNames: ["description", "title", {data: ["id"]}]
|
||||||
|
});
|
||||||
|
jobList.on("filterComplete", List.updatePagination);
|
||||||
|
jobList.on("searchComplete", List.updatePagination);
|
||||||
|
</script>
|
||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<div class="card large">
|
<div class="card large">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
var jobsSubscribers = [];
|
var jobsSubscribers = [];
|
||||||
var socket = io();
|
var socket = io();
|
||||||
|
|
||||||
|
|
||||||
socket.on('init-corpora', function(msg) {
|
socket.on('init-corpora', function(msg) {
|
||||||
var subscriber;
|
var subscriber;
|
||||||
|
|
||||||
@ -64,6 +65,46 @@
|
|||||||
console.log(msg);
|
console.log(msg);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
var foreignCorpora;
|
||||||
|
var foreignCorporaSubscribers = [];
|
||||||
|
var foreignJobs;
|
||||||
|
var foreignJobsSubscribers = [];
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('init-foreign-corpora', function(msg) {
|
||||||
|
var subscriber;
|
||||||
|
|
||||||
|
foreignCorpora = JSON.parse(msg);
|
||||||
|
for (subscriber of foreignCorporaSubscribers) {subscriber._init();}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('init-foreign-jobs', function(msg) {
|
||||||
|
var subscriber;
|
||||||
|
|
||||||
|
foreignJobs = JSON.parse(msg);
|
||||||
|
for (subscriber of foreignJobsSubscribers) {subscriber._init();}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('update-foreign-corpora', function(msg) {
|
||||||
|
var patch, patchedCorpora, subscriber;
|
||||||
|
|
||||||
|
patch = JSON.parse(msg);
|
||||||
|
foreignCorpora = jsonpatch.apply_patch(foreignCorpora, patch);
|
||||||
|
for (subscriber of foreignCorporaSubscribers) {subscriber._update(patch);}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('update-foreign-jobs', function(msg) {
|
||||||
|
var patch, patchedJobs, subscriber;
|
||||||
|
|
||||||
|
patch = JSON.parse(msg);
|
||||||
|
foreignJobs = jsonpatch.apply_patch(foreignJobs, patch);
|
||||||
|
for (subscriber of foreignJobsSubscribers) {subscriber._update(patch);}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
Loading…
Reference in New Issue
Block a user