from datetime import datetime from . import db, socketio from .models import Corpus, CorpusFile, Job, JobInput, JobResult ############################################################################### # SQLAlchemy event handlers # ############################################################################### @db.event.listens_for(Corpus, 'after_delete') @db.event.listens_for(CorpusFile, 'after_delete') @db.event.listens_for(Job, 'after_delete') @db.event.listens_for(JobInput, 'after_delete') @db.event.listens_for(JobResult, 'after_delete') def ressource_after_delete(mapper, connection, ressource): if isinstance(ressource, Corpus): user_id = ressource.creator.id path = '/corpora/{}'.format(ressource.id) elif isinstance(ressource, CorpusFile): user_id = ressource.corpus.creator.id path = '/corpora/{}/files/{}'.format(ressource.corpus.id, ressource.id) elif isinstance(ressource, Job): user_id = ressource.creator.id path = '/jobs/{}'.format(ressource.id) elif isinstance(ressource, JobInput): user_id = ressource.job.creator.id path = '/jobs/{}/inputs/{}'.format(ressource.job.id, ressource.id) elif isinstance(ressource, JobResult): user_id = ressource.job.creator.id path = '/jobs/{}/results/{}'.format(ressource.job.id, ressource.id) event = 'user_{}_patch'.format(user_id) jsonpatch = [{'op': 'remove', 'path': path}] room = 'user_{}'.format(user_id) socketio.emit(event, jsonpatch, room=room) @db.event.listens_for(Corpus, 'after_insert') @db.event.listens_for(CorpusFile, 'after_insert') @db.event.listens_for(Job, 'after_insert') @db.event.listens_for(JobInput, 'after_insert') @db.event.listens_for(JobResult, 'after_insert') def ressource_after_insert_handler(mapper, connection, ressource): if isinstance(ressource, Corpus): user_id = ressource.creator.id path = '/corpora/{}'.format(ressource.id) elif isinstance(ressource, CorpusFile): user_id = ressource.corpus.creator.id path = '/corpora/{}/files/{}'.format(ressource.corpus.id, ressource.id) elif isinstance(ressource, Job): user_id = ressource.creator.id path = '/jobs/{}'.format(ressource.id) elif isinstance(ressource, JobInput): user_id = ressource.job.creator.id path = '/jobs/{}/inputs/{}'.format(ressource.job.id, ressource.id) elif isinstance(ressource, JobResult): user_id = ressource.job.creator.id path = '/jobs/{}/results/{}'.format(ressource.job.id, ressource.id) event = 'user_{}_patch'.format(user_id) jsonpatch = [ { 'op': 'add', 'path': path, 'value': ressource.to_dict(include_relationships=False) } ] room = 'user_{}'.format(user_id) socketio.emit(event, jsonpatch, room=room) @db.event.listens_for(Corpus, 'after_update') @db.event.listens_for(CorpusFile, 'after_update') @db.event.listens_for(Job, 'after_update') @db.event.listens_for(JobInput, 'after_update') @db.event.listens_for(JobResult, 'after_update') def ressource_after_update_handler(mapper, connection, ressource): if isinstance(ressource, Corpus): user_id = ressource.creator.id base_path = '/corpora/{}'.format(ressource.id) elif isinstance(ressource, CorpusFile): user_id = ressource.corpus.creator.id base_path = '/corpora/{}/files/{}'.format(ressource.corpus.id, ressource.id) elif isinstance(ressource, Job): user_id = ressource.creator.id base_path = '/jobs/{}'.format(ressource.id) elif isinstance(ressource, JobInput): user_id = ressource.job.creator.id base_path = '/jobs/{}/inputs/{}'.format(ressource.job.id, ressource.id) elif isinstance(ressource, JobResult): user_id = ressource.job.creator.id base_path = '/jobs/{}/results/{}'.format(ressource.job.id, ressource.id) jsonpatch = [] for attr in db.inspect(ressource).attrs: # We don't want to emit changes about relationship fields if attr.key in ['files', 'inputs', 'results']: continue history = attr.load_history() if not history.has_changes(): continue new_value = history.added[0] # DateTime attributes must be converted to a timestamp if isinstance(new_value, datetime): new_value = new_value.timestamp() jsonpatch.append( { 'op': 'replace', 'path': '{}/{}'.format(base_path, attr.key), 'value': new_value } ) if jsonpatch: event = 'user_{}_patch'.format(user_id) room = 'user_{}'.format(user_id) socketio.emit(event, jsonpatch, room=room)