Remove last edited date from FileMixin

This commit is contained in:
Patrick Jentsch 2022-11-24 12:24:29 +01:00
parent 28b1461ef9
commit aff85f2145
15 changed files with 133 additions and 127 deletions

View File

@ -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

View File

@ -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,

View File

@ -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():

View File

@ -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)

View File

@ -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):

View File

@ -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 = [

View File

@ -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

View File

@ -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,

View File

@ -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")
);
}
}

View File

@ -48,13 +48,6 @@
</div>
</div>
<div class="col s12 m6">
<div class="input-field">
<input class="corpus-last-edited-date validate" disabled id="corpus-last-edited-date" type="text">
<label for="corpus-last-edited-date">Last edited</label>
</div>
</div>
<div class="col s12 m6">
<div class="input-field">
<input class="corpus-token-ratio validate" disabled id="corpus-token-ratio" type="text">

View File

@ -15,7 +15,7 @@ def user(user_id):
backrefs = request.args.get('backrefs', 'false').lower() == 'true'
relationships = (
request.args.get('relationships', 'false').lower() == 'true')
return user.to_json(backrefs=backrefs, relationships=relationships), 200
return user.to_json_serializeable(backrefs=backrefs, relationships=relationships), 200
@bp.route('/<hashid:user_id>', methods=['DELETE'])

View File

@ -21,6 +21,7 @@ def upgrade():
def downgrade():
op.add_column('transkribus_htr_models',
op.add_column(
'transkribus_htr_models',
sa.Column('transkribus_name', sa.String(length=64), autoincrement=False, nullable=True)
)

View File

@ -0,0 +1,51 @@
"""Remove last_edited_date column from all tables
Revision ID: 31b9c0259e6b
Revises: 89e9526089bf
Create Date: 2022-11-24 09:53:21.025531
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '31b9c0259e6b'
down_revision = '89e9526089bf'
branch_labels = None
depends_on = None
def upgrade():
op.drop_column('corpora', 'last_edited_date')
op.drop_column('corpus_files', 'last_edited_date')
op.drop_column('job_inputs', 'last_edited_date')
op.drop_column('job_results', 'last_edited_date')
op.drop_column('spacy_nlp_pipeline_models', 'last_edited_date')
op.drop_column('tesseract_ocr_pipeline_models', 'last_edited_date')
def downgrade():
op.add_column(
'tesseract_ocr_pipeline_models',
sa.Column('last_edited_date', sa.DateTime(), nullable=True)
)
op.add_column(
'spacy_nlp_pipeline_models',
sa.Column('last_edited_date', sa.DateTime(), nullable=True)
)
op.add_column(
'job_results',
sa.Column('last_edited_date', sa.DateTime(), nullable=True)
)
op.add_column(
'job_inputs',
sa.Column('last_edited_date', sa.DateTime(), nullable=True)
)
op.add_column(
'corpus_files',
sa.Column('last_edited_date', sa.DateTime(), nullable=True)
)
op.add_column(
'corpora',
sa.Column('last_edited_date', sa.DateTime(), nullable=True)
)

View File

@ -5,7 +5,6 @@ Revises: 260b57d5f4e7
Create Date: 2022-10-11 14:32:13.227364
"""
from genericpath import isdir
from alembic import op
import os
from app.models import User

View File

@ -21,6 +21,7 @@ def upgrade():
def downgrade():
op.add_column('users',
op.add_column(
'users',
sa.Column('setting_dark_mode', sa.Boolean(), nullable=True)
)