nopaque/app/main/events.py
2019-08-29 11:37:00 +02:00

82 lines
3.1 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():
# print('{} connected'.format(current_user.username))
# send('You entered the room {}'.format(request.sid),
# room=request.sid)
socketio.start_background_task(background_task,
current_user.id,
request.sid)
@socketio.on('disconnect')
@login_required
def disconnect():
disconnected.append(request.sid)
#print('{} disconnected'.format(current_user.username))
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.
'''
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 = list(map(lambda x: x.to_dict(), user.corpora))
jobs = list(map(lambda x: x.to_dict(), user.jobs))
''' 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:
# print(session_id + ' running')
# socketio.emit('message', 'heartbeat', room=session_id)
''' Get current values from the database '''
new_corpora = list(map(lambda x: x.to_dict(), user.corpora))
new_jobs = list(map(lambda x: x.to_dict(), user.jobs))
''' 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 a reference for the next iteration. '''
corpora = new_corpora
jobs = new_jobs
socketio.sleep(3)
disconnected.remove(session_id)
# print(session_id + ' stopped')