Skip to content
Snippets Groups Projects
events.py 2.98 KiB
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 =  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:
            # print(session_id + ' running')
            # socketio.emit('message', 'heartbeat', room=session_id)
            ''' 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 a reference for the next iteration. '''
            corpora = new_corpora
            jobs = new_jobs
            socketio.sleep(3)
    disconnected.remove(session_id)
    # print(session_id + ' stopped')