from enum import Enum from flask_login import AnonymousUserMixin from app import db, login, mail, socketio from app.email import create_message from .avatar import * from .corpus_file import * from .corpus_follower_association import * from .corpus_follower_role import * from .corpus import * from .job_input import * from .job_result import * from .job import * from .role import * from .spacy_nlp_pipeline_model import * from .tesseract_ocr_pipeline_model import * from .token import * from .user import * @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') @db.event.listens_for(SpaCyNLPPipelineModel, 'after_delete') @db.event.listens_for(TesseractOCRPipelineModel, 'after_delete') def resource_after_delete(mapper, connection, resource): print('[START] resource_after_delete') jsonpatch = [ { 'op': 'remove', 'path': resource.jsonpatch_path } ] room = f'/users/{resource.user_hashid}' print('[EMIT] PATCH', jsonpatch) socketio.emit('PATCH', jsonpatch, room=room) print('[END] resource_after_delete') @db.event.listens_for(CorpusFollowerAssociation, 'after_delete') def cfa_after_delete_handler(mapper, connection, cfa): jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}' jsonpatch = [ { 'op': 'remove', 'path': jsonpatch_path } ] room = f'/users/{cfa.corpus.user.hashid}' socketio.emit('PATCH', 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') @db.event.listens_for(SpaCyNLPPipelineModel, 'after_insert') @db.event.listens_for(TesseractOCRPipelineModel, 'after_insert') def resource_after_insert_handler(mapper, connection, resource): jsonpatch_value = resource.to_json_serializeable() for attr in mapper.relationships: jsonpatch_value[attr.key] = {} jsonpatch = [ { 'op': 'add', 'path': resource.jsonpatch_path, 'value': jsonpatch_value } ] room = f'/users/{resource.user_hashid}' socketio.emit('PATCH', jsonpatch, room=room) @db.event.listens_for(CorpusFollowerAssociation, 'after_insert') def cfa_after_insert_handler(mapper, connection, cfa): jsonpatch_value = cfa.to_json_serializeable() jsonpatch_path = f'/users/{cfa.corpus.user.hashid}/corpora/{cfa.corpus.hashid}/corpus_follower_associations/{cfa.hashid}' jsonpatch = [ { 'op': 'add', 'path': jsonpatch_path, 'value': jsonpatch_value } ] room = f'/users/{cfa.corpus.user.hashid}' socketio.emit('PATCH', 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') @db.event.listens_for(SpaCyNLPPipelineModel, 'after_update') @db.event.listens_for(TesseractOCRPipelineModel, 'after_update') def resource_after_update_handler(mapper, connection, resource): jsonpatch = [] for attr in db.inspect(resource).attrs: if attr.key in mapper.relationships: continue if not attr.load_history().has_changes(): continue jsonpatch_path = f'{resource.jsonpatch_path}/{attr.key}' if isinstance(attr.value, datetime): jsonpatch_value = f'{attr.value.isoformat()}Z' elif isinstance(attr.value, Enum): jsonpatch_value = attr.value.name else: jsonpatch_value = attr.value jsonpatch.append( { 'op': 'replace', 'path': jsonpatch_path, 'value': jsonpatch_value } ) if jsonpatch: room = f'/users/{resource.user_hashid}' socketio.emit('PATCH', jsonpatch, room=room) @db.event.listens_for(Job, 'after_update') def job_after_update_handler(mapper, connection, job): for attr in db.inspect(job).attrs: if attr.key != 'status': continue if not attr.load_history().has_changes(): return if job.user.setting_job_status_mail_notification_level == UserSettingJobStatusMailNotificationLevel.NONE: return if job.user.setting_job_status_mail_notification_level == UserSettingJobStatusMailNotificationLevel.END: if job.status not in [JobStatus.COMPLETED, JobStatus.FAILED]: return msg = create_message( job.user.email, f'Status update for your Job "{job.title}"', 'tasks/email/notification', job=job ) mail.send(msg) class AnonymousUser(AnonymousUserMixin): def can(self, permissions): return False @property def is_administrator(self): return False login.anonymous_user = AnonymousUser @login.user_loader def load_user(user_id): return User.query.get(int(user_id))