mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 09:15:41 +00:00
91 lines
3.2 KiB
Python
91 lines
3.2 KiB
Python
from flask import request
|
|
from flask_login import current_user, login_required
|
|
from .. import create_app, db, socketio
|
|
from ..models import User
|
|
import json
|
|
import jsonpatch
|
|
import os
|
|
|
|
'''
|
|
' A list containing session ids of disconnected Socket.IO sessions. It is used
|
|
' to signal associated background tasks to stop.
|
|
'''
|
|
disconnected = []
|
|
|
|
|
|
@socketio.on('connect')
|
|
@login_required
|
|
def connect():
|
|
'''
|
|
' The Socket.IO module creates a session id (sid) on each request. The
|
|
' initiating client 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.
|
|
'''
|
|
socketio.start_background_task(background_task,
|
|
current_user.id,
|
|
request.sid)
|
|
|
|
|
|
@socketio.on('disconnect')
|
|
@login_required
|
|
def disconnect():
|
|
'''
|
|
' On disconnect the session id (sid) of the connection gets placed in the
|
|
' disconnected list (see above).
|
|
'''
|
|
disconnected.append(request.sid)
|
|
|
|
|
|
def background_task(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'
|
|
'''
|
|
'''
|
|
' Create an app instance to get access to an app_context with which db
|
|
' operations are fulfilled.
|
|
'''
|
|
app = create_app(os.getenv('FLASK_CONFIG') or 'default', main=False)
|
|
|
|
with app.app_context():
|
|
user = db.session.query(User).filter_by(id=user_id).first()
|
|
''' Get current values from the database. '''
|
|
corpora = user.corpora_as_dict()
|
|
jobs = user.jobs_as_dict()
|
|
''' Send initial values. '''
|
|
socketio.emit('init-corpora',
|
|
json.dumps(corpora),
|
|
room=session_id)
|
|
socketio.emit('init-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-corpora',
|
|
corpus_patch.to_string(),
|
|
room=session_id)
|
|
if jobs_patch:
|
|
socketio.emit('update-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)
|