mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 01:05:42 +00:00
Merge branch 'development' of gitlab.ub.uni-bielefeld.de:sfb1288inf/nopaque into development
share toggle update in contributions
This commit is contained in:
commit
9c8271aec5
@ -6,7 +6,6 @@ from app.decorators import admin_required
|
|||||||
from app.models import Role, User, UserSettingJobStatusMailNotificationLevel
|
from app.models import Role, User, UserSettingJobStatusMailNotificationLevel
|
||||||
from app.settings.forms import (
|
from app.settings.forms import (
|
||||||
EditGeneralSettingsForm,
|
EditGeneralSettingsForm,
|
||||||
EditInterfaceSettingsForm,
|
|
||||||
EditNotificationSettingsForm
|
EditNotificationSettingsForm
|
||||||
)
|
)
|
||||||
from . import bp
|
from . import bp
|
||||||
@ -55,9 +54,6 @@ def edit_user(user_id):
|
|||||||
user,
|
user,
|
||||||
prefix='edit-general-settings-form'
|
prefix='edit-general-settings-form'
|
||||||
)
|
)
|
||||||
edit_interface_settings_form = EditInterfaceSettingsForm(
|
|
||||||
prefix='edit-interface-settings-form'
|
|
||||||
)
|
|
||||||
edit_notification_settings_form = EditNotificationSettingsForm(
|
edit_notification_settings_form = EditNotificationSettingsForm(
|
||||||
prefix='edit-notification-settings-form'
|
prefix='edit-notification-settings-form'
|
||||||
)
|
)
|
||||||
@ -76,12 +72,6 @@ def edit_user(user_id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash('Your changes have been saved')
|
flash('Your changes have been saved')
|
||||||
return redirect(url_for('.edit_user', user_id=user.id))
|
return redirect(url_for('.edit_user', user_id=user.id))
|
||||||
if (edit_interface_settings_form.submit.data
|
|
||||||
and edit_interface_settings_form.validate()):
|
|
||||||
user.setting_dark_mode = edit_interface_settings_form.dark_mode.data
|
|
||||||
db.session.commit()
|
|
||||||
flash('Your changes have been saved')
|
|
||||||
return redirect(url_for('.edit_user', user_id=user.id))
|
|
||||||
if (edit_notification_settings_form.submit.data
|
if (edit_notification_settings_form.submit.data
|
||||||
and edit_notification_settings_form.validate()):
|
and edit_notification_settings_form.validate()):
|
||||||
user.setting_job_status_mail_notification_level = \
|
user.setting_job_status_mail_notification_level = \
|
||||||
@ -93,13 +83,11 @@ def edit_user(user_id):
|
|||||||
return redirect(url_for('.edit_user', user_id=user.id))
|
return redirect(url_for('.edit_user', user_id=user.id))
|
||||||
admin_edit_user_form.prefill(user)
|
admin_edit_user_form.prefill(user)
|
||||||
edit_general_settings_form.prefill(user)
|
edit_general_settings_form.prefill(user)
|
||||||
edit_interface_settings_form.prefill(user)
|
|
||||||
edit_notification_settings_form.prefill(user)
|
edit_notification_settings_form.prefill(user)
|
||||||
return render_template(
|
return render_template(
|
||||||
'admin/edit_user.html.j2',
|
'admin/edit_user.html.j2',
|
||||||
admin_edit_user_form=admin_edit_user_form,
|
admin_edit_user_form=admin_edit_user_form,
|
||||||
edit_general_settings_form=edit_general_settings_form,
|
edit_general_settings_form=edit_general_settings_form,
|
||||||
edit_interface_settings_form=edit_interface_settings_form,
|
|
||||||
edit_notification_settings_form=edit_notification_settings_form,
|
edit_notification_settings_form=edit_notification_settings_form,
|
||||||
title='Edit user',
|
title='Edit user',
|
||||||
user=user
|
user=user
|
||||||
|
@ -150,7 +150,6 @@ class UserSchema(ma.SQLAlchemySchema):
|
|||||||
last_seen = ma.auto_field(dump_only=True)
|
last_seen = ma.auto_field(dump_only=True)
|
||||||
password = ma.String(load_only=True)
|
password = ma.String(load_only=True)
|
||||||
last_seen = ma.auto_field(dump_only=True)
|
last_seen = ma.auto_field(dump_only=True)
|
||||||
setting_dark_mode = ma.auto_field()
|
|
||||||
setting_job_status_mail_notification_level = ma.String(
|
setting_job_status_mail_notification_level = ma.String(
|
||||||
validate=validate.OneOf(list(UserSettingJobStatusMailNotificationLevel.__members__.keys()))
|
validate=validate.OneOf(list(UserSettingJobStatusMailNotificationLevel.__members__.keys()))
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,7 @@ from wtforms.validators import InputRequired, Length
|
|||||||
from app.services import SERVICES
|
from app.services import SERVICES
|
||||||
|
|
||||||
|
|
||||||
class CreateContributionBaseForm(FlaskForm):
|
class ContributionBaseForm(FlaskForm):
|
||||||
title = StringField(
|
title = StringField(
|
||||||
'Title',
|
'Title',
|
||||||
validators=[InputRequired(), Length(max=64)]
|
validators=[InputRequired(), Length(max=64)]
|
||||||
@ -48,7 +48,7 @@ class CreateContributionBaseForm(FlaskForm):
|
|||||||
submit = SubmitField()
|
submit = SubmitField()
|
||||||
|
|
||||||
|
|
||||||
class CreateTesseractOCRPipelineModelForm(CreateContributionBaseForm):
|
class CreateTesseractOCRPipelineModelForm(ContributionBaseForm):
|
||||||
tesseract_model_file = FileField(
|
tesseract_model_file = FileField(
|
||||||
'File',
|
'File',
|
||||||
validators=[FileRequired()]
|
validators=[FileRequired()]
|
||||||
@ -72,7 +72,7 @@ class CreateTesseractOCRPipelineModelForm(CreateContributionBaseForm):
|
|||||||
self.compatible_service_versions.default = ''
|
self.compatible_service_versions.default = ''
|
||||||
|
|
||||||
|
|
||||||
class CreateSpaCyNLPPipelineModelForm(CreateContributionBaseForm):
|
class CreateSpaCyNLPPipelineModelForm(ContributionBaseForm):
|
||||||
spacy_model_file = FileField(
|
spacy_model_file = FileField(
|
||||||
'File',
|
'File',
|
||||||
validators=[FileRequired()]
|
validators=[FileRequired()]
|
||||||
@ -100,17 +100,8 @@ class CreateSpaCyNLPPipelineModelForm(CreateContributionBaseForm):
|
|||||||
self.compatible_service_versions.default = ''
|
self.compatible_service_versions.default = ''
|
||||||
|
|
||||||
|
|
||||||
class EditContributionBaseForm(CreateContributionBaseForm):
|
class EditContributionBaseForm(ContributionBaseForm):
|
||||||
def prefill(self, model_file):
|
pass
|
||||||
''' Pre-fill the form with data of an exististing corpus file '''
|
|
||||||
self.title.data = model_file.title
|
|
||||||
self.description.data = model_file.description
|
|
||||||
self.publisher.data = model_file.publisher
|
|
||||||
self.publishing_year.data = model_file.publishing_year
|
|
||||||
self.publisher_url.data = model_file.publisher_url
|
|
||||||
self.publishing_url.data = model_file.publishing_url
|
|
||||||
self.version.data = model_file.version
|
|
||||||
self.shared.data = model_file.shared
|
|
||||||
|
|
||||||
|
|
||||||
class EditTesseractOCRPipelineModelForm(EditContributionBaseForm):
|
class EditTesseractOCRPipelineModelForm(EditContributionBaseForm):
|
||||||
@ -122,7 +113,3 @@ class EditSpaCyNLPPipelineModelForm(EditContributionBaseForm):
|
|||||||
'Pipeline name',
|
'Pipeline name',
|
||||||
validators=[InputRequired(), Length(max=64)]
|
validators=[InputRequired(), Length(max=64)]
|
||||||
)
|
)
|
||||||
|
|
||||||
def prefill(self, model_file):
|
|
||||||
super().prefill(model_file)
|
|
||||||
self.pipeline_name.data = model_file.pipeline_name
|
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
from flask import abort, current_app, flash, Markup, render_template, url_for
|
from flask import (
|
||||||
|
abort,
|
||||||
|
current_app,
|
||||||
|
flash,
|
||||||
|
Markup,
|
||||||
|
redirect,
|
||||||
|
render_template,
|
||||||
|
url_for
|
||||||
|
)
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from app import db
|
from app import db
|
||||||
@ -43,33 +51,17 @@ def tesseract_ocr_pipeline_models():
|
|||||||
@bp.route('/tesseract-ocr-pipeline-models/<hashid:tesseract_ocr_pipeline_model_id>', methods=['GET', 'POST'])
|
@bp.route('/tesseract-ocr-pipeline-models/<hashid:tesseract_ocr_pipeline_model_id>', methods=['GET', 'POST'])
|
||||||
def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id):
|
def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id):
|
||||||
tesseract_ocr_pipeline_model = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
|
tesseract_ocr_pipeline_model = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
|
||||||
form = EditTesseractOCRPipelineModelForm(prefix='edit-tesseract-ocr-pipeline-model-form')
|
form = EditTesseractOCRPipelineModelForm(
|
||||||
if form.validate_on_submit():
|
obj=tesseract_ocr_pipeline_model,
|
||||||
if tesseract_ocr_pipeline_model.title != form.title.data:
|
prefix='edit-tesseract-ocr-pipeline-model-form'
|
||||||
tesseract_ocr_pipeline_model.title = form.title.data
|
|
||||||
if tesseract_ocr_pipeline_model.description != form.description.data:
|
|
||||||
tesseract_ocr_pipeline_model.description = form.description.data
|
|
||||||
if tesseract_ocr_pipeline_model.publisher != form.publisher.data:
|
|
||||||
tesseract_ocr_pipeline_model.publisher = form.publisher.data
|
|
||||||
if tesseract_ocr_pipeline_model.publishing_year != form.publishing_year.data:
|
|
||||||
tesseract_ocr_pipeline_model.publishing_year = form.publishing_year.data
|
|
||||||
if tesseract_ocr_pipeline_model.publisher_url != form.publisher_url.data:
|
|
||||||
tesseract_ocr_pipeline_model.publisher_url = form.publisher_url.data
|
|
||||||
if tesseract_ocr_pipeline_model.publishing_url != form.publishing_url.data:
|
|
||||||
tesseract_ocr_pipeline_model.publishing_url = form.publishing_url.data
|
|
||||||
if tesseract_ocr_pipeline_model.version != form.version.data:
|
|
||||||
tesseract_ocr_pipeline_model.version = form.version.data
|
|
||||||
if tesseract_ocr_pipeline_model.shared != form.shared.data:
|
|
||||||
tesseract_ocr_pipeline_model.shared = form.shared.data
|
|
||||||
db.session.commit()
|
|
||||||
tesseract_ocr_pipeline_model_url = url_for(
|
|
||||||
'.tesseract_ocr_pipeline_model',
|
|
||||||
tesseract_ocr_pipeline_model_id=tesseract_ocr_pipeline_model.id
|
|
||||||
)
|
)
|
||||||
message = Markup(f'Tesseract OCR Pipeline model "<a href="{tesseract_ocr_pipeline_model_url}">{tesseract_ocr_pipeline_model.title}</a>" updated')
|
if form.validate_on_submit():
|
||||||
|
form.populate_obj(tesseract_ocr_pipeline_model)
|
||||||
|
if db.session.is_modified(tesseract_ocr_pipeline_model):
|
||||||
|
message = Markup(f'Tesseract OCR Pipeline model "<a href="{tesseract_ocr_pipeline_model.url}">{tesseract_ocr_pipeline_model.title}</a>" updated')
|
||||||
flash(message)
|
flash(message)
|
||||||
return {}, 201, {'Location': tesseract_ocr_pipeline_model_url}
|
db.session.commit()
|
||||||
form.prefill(tesseract_ocr_pipeline_model)
|
return redirect(url_for('.tesseract_ocr_pipeline_models'))
|
||||||
return render_template(
|
return render_template(
|
||||||
'contributions/tesseract_ocr_pipeline_model.html.j2',
|
'contributions/tesseract_ocr_pipeline_model.html.j2',
|
||||||
form=form,
|
form=form,
|
||||||
@ -155,36 +147,17 @@ def spacy_nlp_pipeline_models():
|
|||||||
@bp.route('/spacy-nlp-pipeline-models/<hashid:spacy_nlp_pipeline_model_id>', methods=['GET', 'POST'])
|
@bp.route('/spacy-nlp-pipeline-models/<hashid:spacy_nlp_pipeline_model_id>', methods=['GET', 'POST'])
|
||||||
def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id):
|
def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id):
|
||||||
spacy_nlp_pipeline_model = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
|
spacy_nlp_pipeline_model = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
|
||||||
form = EditSpaCyNLPPipelineModelForm(prefix='edit-spacy-nlp-pipeline-model-form')
|
form = EditSpaCyNLPPipelineModelForm(
|
||||||
if form.validate_on_submit():
|
obj=spacy_nlp_pipeline_model,
|
||||||
if spacy_nlp_pipeline_model.title != form.title.data:
|
prefix='edit-spacy-nlp-pipeline-model-form'
|
||||||
spacy_nlp_pipeline_model.title = form.title.data
|
|
||||||
if spacy_nlp_pipeline_model.description != form.description.data:
|
|
||||||
spacy_nlp_pipeline_model.description = form.description.data
|
|
||||||
if spacy_nlp_pipeline_model.pipeline_name != form.pipeline_name.data:
|
|
||||||
spacy_nlp_pipeline_model.pipeline_name = form.pipeline_name.data
|
|
||||||
if spacy_nlp_pipeline_model.publisher != form.publisher.data:
|
|
||||||
spacy_nlp_pipeline_model.publisher = form.publisher.data
|
|
||||||
if spacy_nlp_pipeline_model.publishing_year != form.publishing_year.data:
|
|
||||||
spacy_nlp_pipeline_model.publishing_year = form.publishing_year.data
|
|
||||||
if spacy_nlp_pipeline_model.publisher_url != form.publisher_url.data:
|
|
||||||
spacy_nlp_pipeline_model.publisher_url = form.publisher_url.data
|
|
||||||
if spacy_nlp_pipeline_model.publishing_url != form.publishing_url.data:
|
|
||||||
spacy_nlp_pipeline_model.publishing_url = form.publishing_url.data
|
|
||||||
if spacy_nlp_pipeline_model.version != form.version.data:
|
|
||||||
spacy_nlp_pipeline_model.version = form.version.data
|
|
||||||
if spacy_nlp_pipeline_model.shared != form.shared.data:
|
|
||||||
spacy_nlp_pipeline_model.shared = form.shared.data
|
|
||||||
current_app.logger.warning(db.session.dirty)
|
|
||||||
db.session.commit()
|
|
||||||
spacy_nlp_pipeline_model_url = url_for(
|
|
||||||
'.spacy_nlp_pipeline_model',
|
|
||||||
spacy_nlp_pipeline_model_id=spacy_nlp_pipeline_model.id
|
|
||||||
)
|
)
|
||||||
message = Markup(f'SpaCy NLP Pipeline model "<a href="{spacy_nlp_pipeline_model_url}">{spacy_nlp_pipeline_model.title}</a>" updated')
|
if form.validate_on_submit():
|
||||||
|
form.populate_obj(spacy_nlp_pipeline_model)
|
||||||
|
if db.session.is_modified(spacy_nlp_pipeline_model):
|
||||||
|
message = Markup(f'SpaCy NLP Pipeline model "<a href="{spacy_nlp_pipeline_model.url}">{spacy_nlp_pipeline_model.title}</a>" updated')
|
||||||
flash(message)
|
flash(message)
|
||||||
return {}, 201, {'Location': url_for('.contributions')}
|
db.session.commit()
|
||||||
form.prefill(spacy_nlp_pipeline_model)
|
return redirect(url_for('.spacy_nlp_pipeline_models'))
|
||||||
return render_template(
|
return render_template(
|
||||||
'contributions/spacy_nlp_pipeline_model.html.j2',
|
'contributions/spacy_nlp_pipeline_model.html.j2',
|
||||||
form=form,
|
form=form,
|
||||||
|
@ -47,20 +47,7 @@ class CreateCorpusFileForm(CorpusFileBaseForm):
|
|||||||
|
|
||||||
|
|
||||||
class EditCorpusFileForm(CorpusFileBaseForm):
|
class EditCorpusFileForm(CorpusFileBaseForm):
|
||||||
def prefill(self, corpus_file):
|
pass
|
||||||
''' Pre-fill the form with data of an exististing corpus file '''
|
|
||||||
self.address.data = corpus_file.address
|
|
||||||
self.author.data = corpus_file.author
|
|
||||||
self.booktitle.data = corpus_file.booktitle
|
|
||||||
self.chapter.data = corpus_file.chapter
|
|
||||||
self.editor.data = corpus_file.editor
|
|
||||||
self.institution.data = corpus_file.institution
|
|
||||||
self.journal.data = corpus_file.journal
|
|
||||||
self.pages.data = corpus_file.pages
|
|
||||||
self.publisher.data = corpus_file.publisher
|
|
||||||
self.publishing_year.data = corpus_file.publishing_year
|
|
||||||
self.school.data = corpus_file.school
|
|
||||||
self.title.data = corpus_file.title
|
|
||||||
|
|
||||||
|
|
||||||
class ImportCorpusForm(FlaskForm):
|
class ImportCorpusForm(FlaskForm):
|
||||||
|
@ -176,52 +176,15 @@ def corpus_file(corpus_id, corpus_file_id):
|
|||||||
abort(404)
|
abort(404)
|
||||||
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
||||||
abort(403)
|
abort(403)
|
||||||
form = EditCorpusFileForm(prefix='edit-corpus-file-form')
|
form = EditCorpusFileForm(obj=corpus_file, prefix='edit-corpus-file-form')
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
has_changes = False
|
form.populate_obj(corpus_file)
|
||||||
if corpus_file.address != form.address.data:
|
if db.session.is_modified(corpus_file):
|
||||||
corpus_file.address = form.address.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.author != form.author.data:
|
|
||||||
corpus_file.author = form.author.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.booktitle != form.booktitle.data:
|
|
||||||
corpus_file.booktitle = form.booktitle.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.chapter != form.chapter.data:
|
|
||||||
corpus_file.chapter = form.chapter.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.editor != form.editor.data:
|
|
||||||
corpus_file.editor = form.editor.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.institution != form.institution.data:
|
|
||||||
corpus_file.institution = form.institution.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.journal != form.journal.data:
|
|
||||||
corpus_file.journal = form.journal.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.pages != form.pages.data:
|
|
||||||
corpus_file.pages = form.pages.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.publisher != form.publisher.data:
|
|
||||||
corpus_file.publisher = form.publisher.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.publishing_year != form.publishing_year.data:
|
|
||||||
corpus_file.publishing_year = form.publishing_year.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.school != form.school.data:
|
|
||||||
corpus_file.school = form.school.data
|
|
||||||
has_changes = True
|
|
||||||
if corpus_file.title != form.title.data:
|
|
||||||
corpus_file.title = form.title.data
|
|
||||||
has_changes = True
|
|
||||||
if has_changes:
|
|
||||||
corpus_file.corpus.status = CorpusStatus.UNPREPARED
|
corpus_file.corpus.status = CorpusStatus.UNPREPARED
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
message = Markup(f'Corpus file "<a href="{corpus_file.url}">{corpus_file.filename}</a>" updated')
|
message = Markup(f'Corpus file "<a href="{corpus_file.url}">{corpus_file.filename}</a>" updated')
|
||||||
flash(message, category='corpus')
|
flash(message, category='corpus')
|
||||||
return redirect(corpus_file.corpus.url)
|
return redirect(corpus_file.corpus.url)
|
||||||
form.prefill(corpus_file)
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'corpora/corpus_file.html.j2',
|
'corpora/corpus_file.html.j2',
|
||||||
corpus=corpus_file.corpus,
|
corpus=corpus_file.corpus,
|
||||||
|
@ -263,7 +263,6 @@ class User(HashidMixin, UserMixin, db.Model):
|
|||||||
password_hash = db.Column(db.String(128))
|
password_hash = db.Column(db.String(128))
|
||||||
confirmed = db.Column(db.Boolean, default=False)
|
confirmed = db.Column(db.Boolean, default=False)
|
||||||
member_since = db.Column(db.DateTime(), default=datetime.utcnow)
|
member_since = db.Column(db.DateTime(), default=datetime.utcnow)
|
||||||
setting_dark_mode = db.Column(db.Boolean, default=False)
|
|
||||||
setting_job_status_mail_notification_level = db.Column(
|
setting_job_status_mail_notification_level = db.Column(
|
||||||
IntEnumColumn(UserSettingJobStatusMailNotificationLevel),
|
IntEnumColumn(UserSettingJobStatusMailNotificationLevel),
|
||||||
default=UserSettingJobStatusMailNotificationLevel.END
|
default=UserSettingJobStatusMailNotificationLevel.END
|
||||||
@ -500,7 +499,6 @@ class User(HashidMixin, UserMixin, db.Model):
|
|||||||
'member_since': f'{self.member_since.isoformat()}Z',
|
'member_since': f'{self.member_since.isoformat()}Z',
|
||||||
'username': self.username,
|
'username': self.username,
|
||||||
'settings': {
|
'settings': {
|
||||||
'dark_mode': self.setting_dark_mode,
|
|
||||||
'job_status_mail_notification_level': \
|
'job_status_mail_notification_level': \
|
||||||
self.setting_job_status_mail_notification_level.name
|
self.setting_job_status_mail_notification_level.name
|
||||||
}
|
}
|
||||||
@ -552,6 +550,13 @@ class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model):
|
|||||||
str(self.id)
|
str(self.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
return url_for(
|
||||||
|
'contributions.tesseract_ocr_pipeline_model',
|
||||||
|
tesseract_ocr_pipeline_model_id=self.id
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def insert_defaults():
|
def insert_defaults():
|
||||||
nopaque_user = User.query.filter_by(username='nopaque').first()
|
nopaque_user = User.query.filter_by(username='nopaque').first()
|
||||||
@ -660,6 +665,13 @@ class SpaCyNLPPipelineModel(FileMixin, HashidMixin, db.Model):
|
|||||||
str(self.id)
|
str(self.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
return url_for(
|
||||||
|
'contributions.spacy_nlp_pipeline_model',
|
||||||
|
spacy_nlp_pipeline_model_id=self.id
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def insert_defaults():
|
def insert_defaults():
|
||||||
nopaque_user = User.query.filter_by(username='nopaque').first()
|
nopaque_user = User.query.filter_by(username='nopaque').first()
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
class QueryResult(FileMixin, HashidMixin, db.Model):
|
|
||||||
__tablename__ = 'query_results'
|
|
||||||
# Primary key
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
|
||||||
# Foreign keys
|
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
|
|
||||||
# Fields
|
|
||||||
description = db.Column(db.String(255))
|
|
||||||
query_metadata = db.Column(db.JSON())
|
|
||||||
title = db.Column(db.String(32))
|
|
||||||
# Backrefs: user: User
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
'''
|
|
||||||
String representation of the QueryResult. For human readability.
|
|
||||||
'''
|
|
||||||
return f'<QueryResult {self.title}>'
|
|
||||||
|
|
||||||
@property
|
|
||||||
def download_url(self):
|
|
||||||
return url_for(
|
|
||||||
'corpora.download_query_result', query_result_id=self.id)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def jsonpatch_path(self):
|
|
||||||
return f'{self.user.jsonpatch_path}/query_results/{self.hashid}'
|
|
||||||
|
|
||||||
@property
|
|
||||||
def path(self):
|
|
||||||
return os.path.join(
|
|
||||||
self.user.path, 'query_results', str(self.id), self.filename)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def url(self):
|
|
||||||
return url_for('corpora.query_result', query_result_id=self.id)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def user_hashid(self):
|
|
||||||
return self.user.hashid
|
|
||||||
|
|
||||||
def delete(self):
|
|
||||||
shutil.rmtree(self.path, ignore_errors=True)
|
|
||||||
db.session.delete(self)
|
|
||||||
|
|
||||||
def to_json(self, backrefs=False, relationships=False):
|
|
||||||
_json = {
|
|
||||||
'id': self.hashid,
|
|
||||||
'corpus_title': self.query_metadata['corpus_name'],
|
|
||||||
'description': self.description,
|
|
||||||
'filename': self.filename,
|
|
||||||
'query': self.query_metadata['query'],
|
|
||||||
'query_metadata': self.query_metadata,
|
|
||||||
'title': self.title,
|
|
||||||
**self.file_mixin_to_json(
|
|
||||||
backrefs=backrefs, relationships=relationships)
|
|
||||||
}
|
|
||||||
if backrefs:
|
|
||||||
_json['user'] = self.user.to_json(backrefs=True, relationships=False)
|
|
@ -72,10 +72,8 @@ class CreateTesseractOCRPipelineJobForm(CreateJobBaseForm):
|
|||||||
self.ocropus_nlbin_threshold.render_kw['disabled'] = True
|
self.ocropus_nlbin_threshold.render_kw['disabled'] = True
|
||||||
if 'methods' in service_info:
|
if 'methods' in service_info:
|
||||||
if 'binarization' in service_info['methods']:
|
if 'binarization' in service_info['methods']:
|
||||||
if 'disabled' in self.binarization.render_kw:
|
|
||||||
del self.binarization.render_kw['disabled']
|
del self.binarization.render_kw['disabled']
|
||||||
if 'ocropus_nlbin_threshold' in service_info['methods']:
|
if 'ocropus_nlbin_threshold' in service_info['methods']:
|
||||||
if 'disabled' in self.ocropus_nlbin_threshold.render_kw:
|
|
||||||
del self.ocropus_nlbin_threshold.render_kw['disabled']
|
del self.ocropus_nlbin_threshold.render_kw['disabled']
|
||||||
models = [
|
models = [
|
||||||
x for x in TesseractOCRPipelineModel.query.order_by(TesseractOCRPipelineModel.title).all()
|
x for x in TesseractOCRPipelineModel.query.order_by(TesseractOCRPipelineModel.title).all()
|
||||||
@ -118,7 +116,6 @@ class CreateTranskribusHTRPipelineJobForm(CreateJobBaseForm):
|
|||||||
self.binarization.render_kw['disabled'] = True
|
self.binarization.render_kw['disabled'] = True
|
||||||
if 'methods' in service_info:
|
if 'methods' in service_info:
|
||||||
if 'binarization' in service_info['methods']:
|
if 'binarization' in service_info['methods']:
|
||||||
if 'disabled' in self.binarization.render_kw:
|
|
||||||
del self.binarization.render_kw['disabled']
|
del self.binarization.render_kw['disabled']
|
||||||
self.model.choices = [('', 'Choose your option')]
|
self.model.choices = [('', 'Choose your option')]
|
||||||
self.model.choices += [(x['modelId'], x['name']) for x in transkribus_htr_pipeline_models]
|
self.model.choices += [(x['modelId'], x['name']) for x in transkribus_htr_pipeline_models]
|
||||||
@ -157,7 +154,6 @@ class CreateSpacyNLPPipelineJobForm(CreateJobBaseForm):
|
|||||||
self.encoding_detection.render_kw['disabled'] = True
|
self.encoding_detection.render_kw['disabled'] = True
|
||||||
if 'methods' in service_info:
|
if 'methods' in service_info:
|
||||||
if 'encoding_detection' in service_info['methods']:
|
if 'encoding_detection' in service_info['methods']:
|
||||||
if 'disabled' in self.encoding_detection.render_kw:
|
|
||||||
del self.encoding_detection.render_kw['disabled']
|
del self.encoding_detection.render_kw['disabled']
|
||||||
models = [
|
models = [
|
||||||
x for x in SpaCyNLPPipelineModel.query.order_by(SpaCyNLPPipelineModel.title).all()
|
x for x in SpaCyNLPPipelineModel.query.order_by(SpaCyNLPPipelineModel.title).all()
|
||||||
|
@ -71,10 +71,6 @@ class EditGeneralSettingsForm(FlaskForm):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.user = user
|
self.user = user
|
||||||
|
|
||||||
def prefill(self, user):
|
|
||||||
self.email.data = user.email
|
|
||||||
self.username.data = user.username
|
|
||||||
|
|
||||||
def validate_email(self, field):
|
def validate_email(self, field):
|
||||||
if (field.data != self.user.email
|
if (field.data != self.user.email
|
||||||
and User.query.filter_by(email=field.data).first()):
|
and User.query.filter_by(email=field.data).first()):
|
||||||
@ -86,13 +82,6 @@ class EditGeneralSettingsForm(FlaskForm):
|
|||||||
raise ValidationError('Username already in use')
|
raise ValidationError('Username already in use')
|
||||||
|
|
||||||
|
|
||||||
class EditInterfaceSettingsForm(FlaskForm):
|
|
||||||
dark_mode = BooleanField('Dark mode')
|
|
||||||
submit = SubmitField()
|
|
||||||
|
|
||||||
def prefill(self, user):
|
|
||||||
self.dark_mode.data = user.setting_dark_mode
|
|
||||||
|
|
||||||
class EditNotificationSettingsForm(FlaskForm):
|
class EditNotificationSettingsForm(FlaskForm):
|
||||||
job_status_mail_notification_level = SelectField(
|
job_status_mail_notification_level = SelectField(
|
||||||
'Job status mail notification level',
|
'Job status mail notification level',
|
||||||
|
@ -6,7 +6,6 @@ from . import bp
|
|||||||
from .forms import (
|
from .forms import (
|
||||||
ChangePasswordForm,
|
ChangePasswordForm,
|
||||||
EditGeneralSettingsForm,
|
EditGeneralSettingsForm,
|
||||||
EditInterfaceSettingsForm,
|
|
||||||
EditNotificationSettingsForm
|
EditNotificationSettingsForm
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,11 +19,9 @@ def settings():
|
|||||||
)
|
)
|
||||||
edit_general_settings_form = EditGeneralSettingsForm(
|
edit_general_settings_form = EditGeneralSettingsForm(
|
||||||
current_user,
|
current_user,
|
||||||
|
obj=current_user,
|
||||||
prefix='edit-general-settings-form'
|
prefix='edit-general-settings-form'
|
||||||
)
|
)
|
||||||
edit_interface_settings_form = EditInterfaceSettingsForm(
|
|
||||||
prefix='edit-interface-settings-form'
|
|
||||||
)
|
|
||||||
edit_notification_settings_form = EditNotificationSettingsForm(
|
edit_notification_settings_form = EditNotificationSettingsForm(
|
||||||
prefix='edit-notification-settings-form'
|
prefix='edit-notification-settings-form'
|
||||||
)
|
)
|
||||||
@ -41,13 +38,6 @@ def settings():
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash('Your changes have been saved')
|
flash('Your changes have been saved')
|
||||||
return redirect(url_for('.settings'))
|
return redirect(url_for('.settings'))
|
||||||
if (edit_interface_settings_form.submit.data
|
|
||||||
and edit_interface_settings_form.validate()):
|
|
||||||
current_user.setting_dark_mode = (
|
|
||||||
edit_interface_settings_form.dark_mode.data)
|
|
||||||
db.session.commit()
|
|
||||||
flash('Your changes have been saved')
|
|
||||||
return redirect(url_for('.settings'))
|
|
||||||
if (edit_notification_settings_form.submit.data
|
if (edit_notification_settings_form.submit.data
|
||||||
and edit_notification_settings_form.validate()):
|
and edit_notification_settings_form.validate()):
|
||||||
current_user.setting_job_status_mail_notification_level = (
|
current_user.setting_job_status_mail_notification_level = (
|
||||||
@ -58,14 +48,11 @@ def settings():
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash('Your changes have been saved')
|
flash('Your changes have been saved')
|
||||||
return redirect(url_for('.settings'))
|
return redirect(url_for('.settings'))
|
||||||
edit_general_settings_form.prefill(current_user)
|
|
||||||
edit_interface_settings_form.prefill(current_user)
|
|
||||||
edit_notification_settings_form.prefill(current_user)
|
edit_notification_settings_form.prefill(current_user)
|
||||||
return render_template(
|
return render_template(
|
||||||
'settings/settings.html.j2',
|
'settings/settings.html.j2',
|
||||||
change_password_form=change_password_form,
|
change_password_form=change_password_form,
|
||||||
edit_general_settings_form=edit_general_settings_form,
|
edit_general_settings_form=edit_general_settings_form,
|
||||||
edit_interface_settings_form=edit_interface_settings_form,
|
|
||||||
edit_notification_settings_form=edit_notification_settings_form,
|
edit_notification_settings_form=edit_notification_settings_form,
|
||||||
title='Settings'
|
title='Settings'
|
||||||
)
|
)
|
||||||
|
@ -27,38 +27,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
{{ edit_interface_settings_form.hidden_tag() }}
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<span class="card-title">Interface settings</span>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s1">
|
|
||||||
<p><i class="material-icons">brightness_3</i></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s8">
|
|
||||||
<p>{{ edit_interface_settings_form.dark_mode.label.text }}</p>
|
|
||||||
<p class="light">Enable dark mode to ease your eyes.</p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
{{ edit_interface_settings_form.dark_mode() }}
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-action">
|
|
||||||
<div class="right-align">
|
|
||||||
{{ wtf.render_field(edit_interface_settings_form.submit, material_icon='send') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{{ edit_notification_settings_form.hidden_tag() }}
|
{{ edit_notification_settings_form.hidden_tag() }}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
@ -5,12 +5,6 @@
|
|||||||
{% block head %}
|
{% block head %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<link href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}" rel="icon">
|
<link href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}" rel="icon">
|
||||||
{% if current_user.setting_dark_mode %}
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/darkreader/4.9.40/darkreader.min.js" integrity="sha512-0Jbi9gWSyU5SvNS16za0aILl6l+MgM8N+TGlZxy4qPQEzqKoU9egh4h56Kz0xp2R+ZFPQMfeDn26Gh6cqu2WAg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
||||||
<script>
|
|
||||||
DarkReader.enable();
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock head %}
|
{% endblock head %}
|
||||||
|
|
||||||
{% block metas %}
|
{% block metas %}
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<span class="card-title">Preprocessing</span>
|
<span class="card-title">Preprocessing</span>
|
||||||
</div>
|
</div>
|
||||||
|
{% if 'disabled' not in form.encoding_detection.render_kw or not form.encoding_detection.render_kw['disabled'] %}
|
||||||
<div class="col s9">
|
<div class="col s9">
|
||||||
<p>{{ form.encoding_detection.label.text }}</p>
|
<p>{{ form.encoding_detection.label.text }}</p>
|
||||||
<p class="light">If the input files are not created with the nopaque OCR service or you do not know if your text files are UTF-8 encoded, check this switch. We will try to automatically determine the right encoding for your texts to process them.</p>
|
<p class="light">If the input files are not created with the nopaque OCR service or you do not know if your text files are UTF-8 encoded, check this switch. We will try to automatically determine the right encoding for your texts to process them.</p>
|
||||||
@ -99,6 +100,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
<!--
|
<!--
|
||||||
Seperate each setting with the following
|
Seperate each setting with the following
|
||||||
<div class="col s12"><p> </p></div>
|
<div class="col s12"><p> </p></div>
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<span class="card-title">Preprocessing</span>
|
<span class="card-title">Preprocessing</span>
|
||||||
</div>
|
</div>
|
||||||
|
{% if 'disabled' not in form.binarization.render_kw or not form.binarization.render_kw['disabled'] %}
|
||||||
<div class="col s9">
|
<div class="col s9">
|
||||||
<p>{{ form.binarization.label.text }}</p>
|
<p>{{ form.binarization.label.text }}</p>
|
||||||
<p class="light">Based on a brightness threshold pixels are converted into either black or white. It is useful to reduce noise in images. (<b>longer duration</b>)</p>
|
<p class="light">Based on a brightness threshold pixels are converted into either black or white. It is useful to reduce noise in images. (<b>longer duration</b>)</p>
|
||||||
@ -84,56 +85,14 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s12"><p> </p></div>
|
{% if 'disabled' not in form.ocropus_nlbin_threshold.render_kw or not form.ocropus_nlbin_threshold.render_kw['disabled'] %}
|
||||||
<div class="col s9">
|
<div class="col s9 hide" id="create-job-form-ocropus_nlbin_threshold-container">
|
||||||
|
<br>
|
||||||
<p>Intensity (between 0 and 1)</p>
|
<p>Intensity (between 0 and 1)</p>
|
||||||
<p class="range-field">{{ form.ocropus_nlbin_threshold() }}</p>
|
<p class="range-field">{{ form.ocropus_nlbin_threshold() }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s12"><p> </p></div>
|
{% endif %}
|
||||||
<div class="col s12 divider"></div>
|
{% endif %}
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s9">
|
|
||||||
<p>Page range</p>
|
|
||||||
<p class="light"></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
<input disabled type="checkbox">
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s12 divider"></div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s9">
|
|
||||||
<p>Page rotation</p>
|
|
||||||
<p class="light"></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
<input disabled type="checkbox">
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s12 divider"></div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s9">
|
|
||||||
<p>Page split</p>
|
|
||||||
<p class="light"></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
<input disabled type="checkbox">
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--
|
<!--
|
||||||
Seperate each setting with the following
|
Seperate each setting with the following
|
||||||
<div class="col s12"><p> </p></div>
|
<div class="col s12"><p> </p></div>
|
||||||
@ -185,3 +144,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock modals %}
|
{% endblock modals %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script>
|
||||||
|
document.querySelector('#create-job-form-binarization').addEventListener('change', (event) => {
|
||||||
|
document.querySelector('#create-job-form-ocropus_nlbin_threshold-container').classList.toggle('hide');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock scripts %}
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<span class="card-title">Preprocessing</span>
|
<span class="card-title">Preprocessing</span>
|
||||||
</div>
|
</div>
|
||||||
|
{% if 'disabled' not in form.binarization.render_kw or not form.binarization.render_kw['disabled'] %}
|
||||||
<div class="col s9">
|
<div class="col s9">
|
||||||
<p>{{ form.binarization.label.text }}</p>
|
<p>{{ form.binarization.label.text }}</p>
|
||||||
<p class="light">Based on a brightness threshold pixels are converted into either black or white. It is useful to reduce noise in images. (<b>longer duration</b>)</p>
|
<p class="light">Based on a brightness threshold pixels are converted into either black or white. It is useful to reduce noise in images. (<b>longer duration</b>)</p>
|
||||||
@ -88,51 +89,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s12"><p> </p></div>
|
{% endif %}
|
||||||
<div class="col s12 divider"></div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s9">
|
|
||||||
<p>Page range</p>
|
|
||||||
<p class="light"></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
<input disabled type="checkbox">
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s12 divider"></div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s9">
|
|
||||||
<p>Page rotation</p>
|
|
||||||
<p class="light"></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
<input disabled type="checkbox">
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s12 divider"></div>
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s9">
|
|
||||||
<p>Page split</p>
|
|
||||||
<p class="light"></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
<input disabled type="checkbox">
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--
|
<!--
|
||||||
Seperate each setting with the following
|
Seperate each setting with the following
|
||||||
<div class="col s12"><p> </p></div>
|
<div class="col s12"><p> </p></div>
|
||||||
|
@ -27,38 +27,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
{{ edit_interface_settings_form.hidden_tag() }}
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<span class="card-title">Interface settings</span>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col s12"><p> </p></div>
|
|
||||||
<div class="col s1">
|
|
||||||
<p><i class="material-icons">brightness_3</i></p>
|
|
||||||
</div>
|
|
||||||
<div class="col s8">
|
|
||||||
<p>{{ edit_interface_settings_form.dark_mode.label.text }}</p>
|
|
||||||
<p class="light">Enable dark mode to ease your eyes.</p>
|
|
||||||
</div>
|
|
||||||
<div class="col s3 right-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label>
|
|
||||||
{{ edit_interface_settings_form.dark_mode() }}
|
|
||||||
<span class="lever"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-action">
|
|
||||||
<div class="right-align">
|
|
||||||
{{ wtf.render_field(edit_interface_settings_form.submit, material_icon='send') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{{ edit_notification_settings_form.hidden_tag() }}
|
{{ edit_notification_settings_form.hidden_tag() }}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
26
migrations/versions/89e9526089bf_.py
Normal file
26
migrations/versions/89e9526089bf_.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"""Remove setting_dark_mode column from users table
|
||||||
|
|
||||||
|
Revision ID: 89e9526089bf
|
||||||
|
Revises: 721829b5dd25
|
||||||
|
Create Date: 2022-11-17 09:47:27.724692
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '89e9526089bf'
|
||||||
|
down_revision = '721829b5dd25'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.drop_column('users', 'setting_dark_mode')
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.add_column('users',
|
||||||
|
sa.Column('setting_dark_mode', sa.Boolean(), nullable=True)
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user