diff --git a/app/admin/forms.py b/app/admin/forms.py index d73d3892..7b468161 100644 --- a/app/admin/forms.py +++ b/app/admin/forms.py @@ -11,8 +11,3 @@ class AdminEditUserForm(FlaskForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.role.choices = [(x.hashid, x.name) for x in Role.query.all()] - - def prefill(self, user): - ''' Pre-fill the form with data of an exististing user ''' - self.confirmed.data = user.confirmed - self.role.data = user.role.hashid diff --git a/app/admin/routes.py b/app/admin/routes.py index 8f4370fd..c4480e18 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -30,7 +30,7 @@ def index(): @bp.route('/users') def users(): - json_users = [x.to_json(backrefs=True) for x in User.query.all()] + json_users = [x.to_json_serializeable(backrefs=True) for x in User.query.all()] return render_template( 'admin/users.html.j2', json_users=json_users, @@ -48,15 +48,16 @@ def user(user_id): def edit_user(user_id): user = User.query.get_or_404(user_id) admin_edit_user_form = AdminEditUserForm( - obj=user, + data={'confirmed': user.confirmed, 'role': user.role.hashid}, prefix='admin-edit-user-form' ) edit_general_settings_form = EditGeneralSettingsForm( user, - obj=user, + data=user.to_json_serializeable(), prefix='edit-general-settings-form' ) edit_notification_settings_form = EditNotificationSettingsForm( + data=user.to_json_serializeable(), prefix='edit-notification-settings-form' ) if (admin_edit_user_form.submit.data @@ -83,7 +84,6 @@ def edit_user(user_id): db.session.commit() flash('Your changes have been saved') return redirect(url_for('.edit_user', user_id=user.id)) - edit_notification_settings_form.prefill(user) return render_template( 'admin/edit_user.html.j2', admin_edit_user_form=admin_edit_user_form, diff --git a/app/contributions/routes.py b/app/contributions/routes.py index 6852979f..40b21203 100644 --- a/app/contributions/routes.py +++ b/app/contributions/routes.py @@ -51,7 +51,7 @@ def tesseract_ocr_pipeline_models(): def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id): tesseract_ocr_pipeline_model = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id) form = EditTesseractOCRPipelineModelForm( - obj=tesseract_ocr_pipeline_model, + data=tesseract_ocr_pipeline_model.to_json_serializeable(), prefix='edit-tesseract-ocr-pipeline-model-form' ) if form.validate_on_submit(): @@ -148,7 +148,7 @@ def spacy_nlp_pipeline_models(): def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id): spacy_nlp_pipeline_model = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id) form = EditSpaCyNLPPipelineModelForm( - obj=spacy_nlp_pipeline_model, + data=spacy_nlp_pipeline_model.to_json_serializeable(), prefix='edit-spacy-nlp-pipeline-model-form' ) if form.validate_on_submit(): diff --git a/app/converters/sandpaper.py b/app/converters/sandpaper.py index 5b258ea2..2ea61d98 100644 --- a/app/converters/sandpaper.py +++ b/app/converters/sandpaper.py @@ -54,7 +54,6 @@ def convert_corpus(json_corpus, user, corpus_dir): user=user, creation_date=datetime.fromtimestamp(json_corpus['creation_date']), description=json_corpus['description'], - last_edited_date=datetime.fromtimestamp(json_corpus['last_edited_date']), title=json_corpus['title'] ) db.session.add(corpus) diff --git a/app/corpora/routes.py b/app/corpora/routes.py index 8bf7b1fb..2e9047c3 100644 --- a/app/corpora/routes.py +++ b/app/corpora/routes.py @@ -48,16 +48,6 @@ def corpus(corpus_id): corpus = Corpus.query.get_or_404(corpus_id) if not (corpus.user == current_user or current_user.is_administrator()): abort(403) - # cool = False - # if corpus.is_public: - # cool = True - # elif current_user.is_authenticated: - # if corpus.user == current_user or current_user.is_administrator: - # cool = True - # else: - # abort(403) - # else: - # return current_app.login_manager.unauthorized() return render_template( 'corpora/corpus.html.j2', corpus=corpus, @@ -176,7 +166,10 @@ def corpus_file(corpus_id, corpus_file_id): abort(404) if not (corpus_file.corpus.user == current_user or current_user.is_administrator()): abort(403) - form = EditCorpusFileForm(obj=corpus_file, prefix='edit-corpus-file-form') + form = EditCorpusFileForm( + data=corpus_file.to_json_serializeable(), + prefix='edit-corpus-file-form' + ) if form.validate_on_submit(): form.populate_obj(corpus_file) if db.session.is_modified(corpus_file): diff --git a/app/models.py b/app/models.py index cbe25379..c607dc5f 100644 --- a/app/models.py +++ b/app/models.py @@ -74,17 +74,12 @@ class FileMixin: ''' creation_date = db.Column(db.DateTime, default=datetime.utcnow) filename = db.Column(db.String(255)) - last_edited_date = db.Column(db.DateTime) mimetype = db.Column(db.String(255)) - def file_mixin_to_json(self, backrefs=False, relationships=False): + def file_mixin_to_json_serializeable(self, backrefs=False, relationships=False): return { 'creation_date': f'{self.creation_date.isoformat()}Z', 'filename': self.filename, - 'last_edited_date': ( - None if self.last_edited_date is None - else f'{self.last_edited_date.isoformat()}Z' - ), 'mimetype': self.mimetype } @@ -186,19 +181,19 @@ class Role(HashidMixin, db.Model): def reset_permissions(self): self.permissions = 0 - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'default': self.default, 'name': self.name, 'permissions': self.permissions } if relationships: - _json['users'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['users'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.users } - return _json + return json_serializeable @staticmethod def insert_defaults(): @@ -486,8 +481,8 @@ class User(HashidMixin, UserMixin, db.Model): return False return check_password_hash(self.password_hash, password) - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'confirmed': self.confirmed, 'email': self.email, @@ -497,31 +492,30 @@ class User(HashidMixin, UserMixin, db.Model): ), 'member_since': f'{self.member_since.isoformat()}Z', 'username': self.username, - 'settings': { - 'job_status_mail_notification_level': \ + 'job_status_mail_notification_level': \ self.setting_job_status_mail_notification_level.name - } } if backrefs: - _json['role'] = self.role.to_json(backrefs=True) + json_serializeable['role'] = \ + self.role.to_json_serializeable(backrefs=True) if relationships: - _json['corpora'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['corpora'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.corpora } - _json['jobs'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['jobs'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.jobs } - _json['tesseract_ocr_pipeline_models'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['tesseract_ocr_pipeline_models'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.tesseract_ocr_pipeline_models } - _json['spacy_nlp_pipeline_models'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['spacy_nlp_pipeline_models'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.spacy_nlp_pipeline_models } - return _json + return json_serializeable class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model): __tablename__ = 'tesseract_ocr_pipeline_models' @@ -626,8 +620,8 @@ class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model): current_app.logger.error(e) db.session.delete(self) - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'compatible_service_versions': self.compatible_service_versions, 'description': self.description, @@ -638,11 +632,12 @@ class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model): 'shared': self.shared, 'title': self.title, 'version': self.version, - **self.file_mixin_to_json() + **self.file_mixin_to_json_serializeable() } if backrefs: - _json['user'] = self.user.to_json(backrefs=True) - return _json + json_serializeable['user'] = \ + self.user.to_json_serializeable(backrefs=True) + return json_serializeable class SpaCyNLPPipelineModel(FileMixin, HashidMixin, db.Model): @@ -751,8 +746,8 @@ class SpaCyNLPPipelineModel(FileMixin, HashidMixin, db.Model): current_app.logger.error(e) db.session.delete(self) - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'compatible_service_versions': self.compatible_service_versions, 'description': self.description, @@ -764,11 +759,11 @@ class SpaCyNLPPipelineModel(FileMixin, HashidMixin, db.Model): 'shared': self.shared, 'title': self.title, 'version': self.version, - **self.file_mixin_to_json() + **self.file_mixin_to_json_serializeable() } if backrefs: - _json['user'] = self.user.to_json(backrefs=True) - return _json + json_serializeable['user'] = self.user.to_json_serializeable(backrefs=True) + return json_serializeable class JobInput(FileMixin, HashidMixin, db.Model): @@ -814,14 +809,15 @@ class JobInput(FileMixin, HashidMixin, db.Model): def user_id(self): return self.job.user_id - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, - **self.file_mixin_to_json() + **self.file_mixin_to_json_serializeable() } if backrefs: - _json['job'] = self.job.to_json(backrefs=True) - return _json + json_serializeable['job'] = \ + self.job.to_json_serializeable(backrefs=True) + return json_serializeable class JobResult(FileMixin, HashidMixin, db.Model): @@ -869,18 +865,19 @@ class JobResult(FileMixin, HashidMixin, db.Model): def user_id(self): return self.job.user_id - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'description': self.description, - **self.file_mixin_to_json( + **self.file_mixin_to_json_serializeable( backrefs=backrefs, relationships=relationships ) } if backrefs: - _json['job'] = self.job.to_json(backrefs=True) - return _json + json_serializeable['job'] = \ + self.job.to_json_serializeable(backrefs=True) + return json_serializeable class Job(HashidMixin, db.Model): @@ -988,8 +985,8 @@ class Job(HashidMixin, db.Model): self.end_date = None self.status = JobStatus.SUBMITTED - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'creation_date': f'{self.creation_date.isoformat()}Z', 'description': self.description, @@ -1005,17 +1002,18 @@ class Job(HashidMixin, db.Model): 'url': self.url } if backrefs: - _json['user'] = self.user.to_json(backrefs=True) + json_serializeable['user'] = \ + self.user.to_json_serializeable(backrefs=True) if relationships: - _json['inputs'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['inputs'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.inputs } - _json['results'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['results'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.results } - return _json + return json_serializeable class CorpusFile(FileMixin, HashidMixin, db.Model): @@ -1079,8 +1077,8 @@ class CorpusFile(FileMixin, HashidMixin, db.Model): db.session.delete(self) self.corpus.status = CorpusStatus.UNPREPARED - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'url': self.url, 'address': self.address, @@ -1095,14 +1093,15 @@ class CorpusFile(FileMixin, HashidMixin, db.Model): 'publishing_year': self.publishing_year, 'school': self.school, 'title': self.title, - **self.file_mixin_to_json( + **self.file_mixin_to_json_serializeable( backrefs=backrefs, relationships=relationships ) } if backrefs: - _json['corpus'] = self.corpus.to_json(backrefs=True) - return _json + json_serializeable['corpus'] = \ + self.corpus.to_json_serializeable(backrefs=True) + return json_serializeable class Corpus(HashidMixin, db.Model): ''' @@ -1116,7 +1115,6 @@ class Corpus(HashidMixin, db.Model): # Fields creation_date = db.Column(db.DateTime(), default=datetime.utcnow) description = db.Column(db.String(255)) - last_edited_date = db.Column(db.DateTime()) status = db.Column( IntEnumColumn(CorpusStatus), default=CorpusStatus.UNPREPARED @@ -1210,15 +1208,14 @@ class Corpus(HashidMixin, db.Model): os.path.join(self.path, 'cwb', 'corpus.vrt'), encoding='utf-8' ) - self.last_edited_date = datetime.utcnow() self.status = CorpusStatus.SUBMITTED def delete(self): shutil.rmtree(self.path, ignore_errors=True) db.session.delete(self) - def to_json(self, backrefs=False, relationships=False): - _json = { + def to_json_serializeable(self, backrefs=False, relationships=False): + json_serializeable = { 'id': self.hashid, 'creation_date': f'{self.creation_date.isoformat()}Z', 'description': self.description, @@ -1226,21 +1223,17 @@ class Corpus(HashidMixin, db.Model): 'num_analysis_sessions': self.num_analysis_sessions, 'num_tokens': self.num_tokens, 'status': self.status.name, - 'last_edited_date': ( - None if self.last_edited_date is None - else f'{self.last_edited_date.isoformat()}Z' - ), 'title': self.title, 'is_public': self.is_public } if backrefs: - _json['user'] = self.user.to_json(backrefs=True) + json_serializeable['user'] = self.user.to_json_serializeable(backrefs=True) if relationships: - _json['files'] = { - x.hashid: x.to_json(relationships=True) + json_serializeable['files'] = { + x.hashid: x.to_json_serializeable(relationships=True) for x in self.files } - return _json + return json_serializeable # endregion models @@ -1248,8 +1241,6 @@ class Corpus(HashidMixin, db.Model): # event_handlers # ############################################################################## # region event_handlers - - @db.event.listens_for(Corpus, 'after_delete') @db.event.listens_for(CorpusFile, 'after_delete') @db.event.listens_for(Job, 'after_delete') @@ -1269,7 +1260,7 @@ def ressource_after_delete(mapper, connection, ressource): @db.event.listens_for(JobInput, 'after_insert') @db.event.listens_for(JobResult, 'after_insert') def ressource_after_insert_handler(mapper, connection, ressource): - value = ressource.to_json() + value = ressource.to_json_serializeable() for attr in mapper.relationships: value[attr.key] = {} jsonpatch = [ diff --git a/app/settings/forms.py b/app/settings/forms.py index 00904e00..4e7eacf2 100644 --- a/app/settings/forms.py +++ b/app/settings/forms.py @@ -96,7 +96,3 @@ class EditNotificationSettingsForm(FlaskForm): (x.name, x.name.capitalize()) for x in UserSettingJobStatusMailNotificationLevel ] - - def prefill(self, user): - self.job_status_mail_notification_level.data = \ - user.setting_job_status_mail_notification_level.name diff --git a/app/settings/routes.py b/app/settings/routes.py index 0604eb06..26b7fdda 100644 --- a/app/settings/routes.py +++ b/app/settings/routes.py @@ -19,10 +19,11 @@ def settings(): ) edit_general_settings_form = EditGeneralSettingsForm( current_user, - obj=current_user, + data=current_user.to_json_serializeable(), prefix='edit-general-settings-form' ) edit_notification_settings_form = EditNotificationSettingsForm( + data=current_user.to_json_serializeable(), prefix='edit-notification-settings-form' ) @@ -48,7 +49,6 @@ def settings(): db.session.commit() flash('Your changes have been saved') return redirect(url_for('.settings')) - edit_notification_settings_form.prefill(current_user) return render_template( 'settings/settings.html.j2', change_password_form=change_password_form, diff --git a/app/static/js/RessourceDisplays/CorpusDisplay.js b/app/static/js/RessourceDisplays/CorpusDisplay.js index 9bdc4800..d1c94464 100644 --- a/app/static/js/RessourceDisplays/CorpusDisplay.js +++ b/app/static/js/RessourceDisplays/CorpusDisplay.js @@ -18,7 +18,6 @@ class CorpusDisplay extends RessourceDisplay { let corpus = user.corpora[this.corpusId]; this.setCreationDate(corpus.creation_date); this.setDescription(corpus.description); - this.setLastEditedDate(corpus.last_edited_date); this.setStatus(corpus.status); this.setTitle(corpus.title); this.setNumTokens(corpus.num_tokens); @@ -37,11 +36,6 @@ class CorpusDisplay extends RessourceDisplay { break; } case 'replace': { - let re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/last_edited_date$`); - if (re.test(operation.path)) { - this.setLastEditedDate(operation.value); - break; - } re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/num_tokens`); if (re.test(operation.path)) { this.setNumTokens(operation.value); @@ -113,11 +107,4 @@ class CorpusDisplay extends RessourceDisplay { new Date(creationDate).toLocaleString("en-US") ); } - - setLastEditedDate(lastEditedDate) { - this.setElements( - this.displayElement.querySelectorAll('.corpus-end-date'), - new Date(lastEditedDate).toLocaleString("en-US") - ); - } } diff --git a/app/templates/corpora/corpus.html.j2 b/app/templates/corpora/corpus.html.j2 index d64b7084..16af7d31 100644 --- a/app/templates/corpora/corpus.html.j2 +++ b/app/templates/corpora/corpus.html.j2 @@ -48,13 +48,6 @@ -