From d699fd09e59023eec7d09bc064e332a396aaca99 Mon Sep 17 00:00:00 2001 From: Patrick Jentsch <p.jentsch@uni-bielefeld.de> Date: Tue, 21 Feb 2023 13:59:11 +0100 Subject: [PATCH] Add live data updates for corpus follower lists --- app/models.py | 45 +++++++++++++++---- .../js/ResourceLists/CorpusFollowerList.js | 33 +++++++++++++- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/app/models.py b/app/models.py index 5e2bdcdf..4e40793b 100644 --- a/app/models.py +++ b/app/models.py @@ -653,7 +653,7 @@ class User(HashidMixin, UserMixin, db.Model): self.role.to_json_serializeable(backrefs=True) if relationships: json_serializeable['corpus_follower_associations'] = { - x.hashid: x.to_json_serializeable() + x.hashid: x.to_json_serializeable(relationships=True) for x in self.corpus_follower_associations } json_serializeable['corpora'] = { @@ -672,10 +672,6 @@ class User(HashidMixin, UserMixin, db.Model): x.hashid: x.to_json_serializeable(relationships=True) for x in self.spacy_nlp_pipeline_models } - json_serializeable['followed_corpora'] = { - x.hashid: x.to_json_serializeable(relationships=True) - for x in self.followed_corpora - } if filter_by_privacy_settings: if not self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL): @@ -1430,7 +1426,7 @@ class Corpus(HashidMixin, db.Model): self.user.to_json_serializeable(backrefs=True) if relationships: json_serializeable['corpus_follower_associations'] = { - x.hashid: x.to_json_serializeable() + x.hashid: x.to_json_serializeable(relationships=True) for x in self.corpus_follower_associations } json_serializeable['files'] = { @@ -1454,12 +1450,27 @@ class Corpus(HashidMixin, db.Model): @db.event.listens_for(TesseractOCRPipelineModel, 'after_delete') def ressource_after_delete(mapper, connection, ressource): jsonpatch = [{'op': 'remove', 'path': ressource.jsonpatch_path}] - room = f'users.{ressource.user_hashid}' - socketio.emit('users.patch', jsonpatch, room=room) room = f'/users/{ressource.user_hashid}' socketio.emit('PATCH', jsonpatch, room=room) +@db.event.listens_for(CorpusFollowerAssociation, 'after_delete') +def corpus_follower_association_after_delete_handler(mapper, connection, ressource): + corpus_owner_hashid = ressource.corpus.user.hashid + corpus_hashid = hashids.encode(ressource.corpus_id) + follower_hashid = hashids.encode(ressource.follower_id) + # Send a PATCH to the corpus owner + jsonpatch_path = f'/users/{corpus_owner_hashid}/corpora/{corpus_hashid}/corpus_follower_associations/{ressource.hashid}' + jsonpatch = [{'op': 'remove', 'path': jsonpatch_path}] + room = f'/users/{corpus_owner_hashid}' + socketio.emit('PATCH', jsonpatch, room=room) + # Send a PATCH to the follower + jsonpatch_path = f'/users/{follower_hashid}/corpus_follower_associations/{ressource.hashid}' + jsonpatch = [{'op': 'remove', 'path': jsonpatch_path}] + room = f'/users/{follower_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') @@ -1478,6 +1489,24 @@ def ressource_after_insert_handler(mapper, connection, ressource): socketio.emit('PATCH', jsonpatch, room=room) +# @db.event.listens_for(CorpusFollowerAssociation, 'after_insert') +# def corpus_follower_association_after_insert_handler(mapper, connection, ressource): +# corpus_owner_hashid = ressource.corpus.user.hashid +# corpus_hashid = hashids.encode(ressource.corpus_id) +# follower_hashid = hashids.encode(ressource.follower_id) +# value = ressource.to_json_serializeable() +# # Send a PATCH to the corpus owner +# jsonpatch_path = f'/users/{corpus_owner_hashid}/corpora/{corpus_hashid}/corpus_follower_associations/{ressource.hashid}' +# jsonpatch = [{'op': 'add', 'path': jsonpatch_path, 'value': value}] +# room = f'/users/{corpus_owner_hashid}' +# socketio.emit('PATCH', jsonpatch, room=room) +# # Send a PATCH to the follower +# jsonpatch_path = f'/users/{follower_hashid}/corpus_follower_associations/{ressource.hashid}' +# jsonpatch = [{'op': 'add', 'path': jsonpatch_path, 'value': value}] +# room = f'/users/{follower_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') diff --git a/app/static/js/ResourceLists/CorpusFollowerList.js b/app/static/js/ResourceLists/CorpusFollowerList.js index d83e4a39..616f3793 100644 --- a/app/static/js/ResourceLists/CorpusFollowerList.js +++ b/app/static/js/ResourceLists/CorpusFollowerList.js @@ -169,5 +169,36 @@ class CorpusFollowerList extends ResourceList { } } - onPatch(patch) {} + onPatch(patch) { + let re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/corpus_follower_associations/([A-Za-z0-9]*)`); + let filteredPatch = patch.filter(operation => re.test(operation.path)); + for (let operation of filteredPatch) { + switch(operation.op) { + case 'add': { + // let re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/corpus_follower_associations/([A-Za-z0-9]*)$`); + // if (re.test(operation.path)) {this.add(operation.value);} + break; + } + case 'remove': { + let re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/corpus_follower_associations/([A-Za-z0-9]*)$`); + if (re.test(operation.path)) { + let [match, jobId] = operation.path.match(re); + this.remove(jobId); + } + break; + } + case 'replace': { + // let re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/corpus_follower_associations/([A-Za-z0-9]*)/(service|status|description|title)$`); + // if (re.test(operation.path)) { + // let [match, jobId, valueName] = operation.path.match(re); + // this.replace(jobId, valueName, operation.value); + // } + break; + } + default: { + break; + } + } + } + } } -- GitLab