From cff4b2c5880556fe0c531530d967dd23527d76cf Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Fri, 31 Mar 2023 09:14:21 +0200 Subject: [PATCH] Fix problems with new forms --- app/admin/forms.py | 8 +++-- app/auth/forms.py | 30 +++++++++++++++---- app/contributions/forms.py | 6 ++-- .../spacy_nlp_pipeline_models/forms.py | 8 +++-- .../spacy_nlp_pipeline_models/routes.py | 4 +-- .../tesseract_ocr_pipeline_models/forms.py | 8 +++-- .../tesseract_ocr_pipeline_models/routes.py | 4 +-- app/corpora/files/forms.py | 14 +++++++-- app/corpora/forms.py | 21 +++++++++---- app/forms.py | 26 ---------------- app/services/forms.py | 12 ++++++-- app/services/routes.py | 8 ++--- app/settings/forms.py | 29 +++++++++++++----- .../services/corpus_analysis.html.j2 | 29 +----------------- app/wtforms/__init__.py | 0 app/wtforms/validators.py | 14 +++++++++ 16 files changed, 126 insertions(+), 95 deletions(-) delete mode 100644 app/forms.py create mode 100644 app/wtforms/__init__.py create mode 100644 app/wtforms/validators.py diff --git a/app/admin/forms.py b/app/admin/forms.py index f24ce8f3..ea684624 100644 --- a/app/admin/forms.py +++ b/app/admin/forms.py @@ -1,14 +1,16 @@ -from wtforms import BooleanField, SelectField, SubmitField -from app.forms import NopaqueForm +from flask_wtf import FlaskForm +from wtforms import SelectField, SubmitField from app.models import Role -class UpdateUserForm(NopaqueForm): +class UpdateUserForm(FlaskForm): role = SelectField('Role') submit = SubmitField() def __init__(self, user, *args, **kwargs): if 'data' not in kwargs: kwargs['data'] = {'role': user.role.hashid} + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-user-form' super().__init__(*args, **kwargs) self.role.choices = [(x.hashid, x.name) for x in Role.query.all()] diff --git a/app/auth/forms.py b/app/auth/forms.py index 43db510a..d8ca5770 100644 --- a/app/auth/forms.py +++ b/app/auth/forms.py @@ -1,3 +1,4 @@ +from flask_wtf import FlaskForm from wtforms import ( BooleanField, PasswordField, @@ -6,11 +7,10 @@ from wtforms import ( ValidationError ) from wtforms.validators import InputRequired, Email, EqualTo, Length, Regexp -from app.forms import NopaqueForm from app.models import User -class RegistrationForm(NopaqueForm): +class RegistrationForm(FlaskForm): email = StringField( 'Email', validators=[InputRequired(), Email(), Length(max=254)] @@ -45,6 +45,11 @@ class RegistrationForm(NopaqueForm): ) submit = SubmitField() + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'registration-form' + super().__init__(*args, **kwargs) + def validate_email(self, field): if User.query.filter_by(email=field.data.lower()).first(): raise ValidationError('Email already registered') @@ -54,19 +59,29 @@ class RegistrationForm(NopaqueForm): raise ValidationError('Username already in use') -class LoginForm(NopaqueForm): +class LoginForm(FlaskForm): user = StringField('Email or username', validators=[InputRequired()]) password = PasswordField('Password', validators=[InputRequired()]) remember_me = BooleanField('Keep me logged in') submit = SubmitField() + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'login-form' + super().__init__(*args, **kwargs) -class ResetPasswordRequestForm(NopaqueForm): + +class ResetPasswordRequestForm(FlaskForm): email = StringField('Email', validators=[InputRequired(), Email()]) submit = SubmitField() + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'reset-password-request-form' + super().__init__(*args, **kwargs) -class ResetPasswordForm(NopaqueForm): + +class ResetPasswordForm(FlaskForm): password = PasswordField( 'New password', validators=[ @@ -82,3 +97,8 @@ class ResetPasswordForm(NopaqueForm): ] ) submit = SubmitField() + + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'reset-password-form' + super().__init__(*args, **kwargs) diff --git a/app/contributions/forms.py b/app/contributions/forms.py index 46777ff0..598fb7cc 100644 --- a/app/contributions/forms.py +++ b/app/contributions/forms.py @@ -1,3 +1,4 @@ +from flask_wtf import FlaskForm from wtforms import ( StringField, SubmitField, @@ -5,10 +6,9 @@ from wtforms import ( IntegerField ) from wtforms.validators import InputRequired, Length -from app.forms import NopaqueForm -class ContributionBaseForm(NopaqueForm): +class ContributionBaseForm(FlaskForm): title = StringField( 'Title', validators=[InputRequired(), Length(max=64)] @@ -43,5 +43,5 @@ class ContributionBaseForm(NopaqueForm): submit = SubmitField() -class EditContributionBaseForm(ContributionBaseForm): +class UpdateContributionBaseForm(ContributionBaseForm): pass diff --git a/app/contributions/spacy_nlp_pipeline_models/forms.py b/app/contributions/spacy_nlp_pipeline_models/forms.py index 2670c1d1..dc3ca781 100644 --- a/app/contributions/spacy_nlp_pipeline_models/forms.py +++ b/app/contributions/spacy_nlp_pipeline_models/forms.py @@ -2,7 +2,7 @@ from flask_wtf.file import FileField, FileRequired from wtforms import StringField, ValidationError from wtforms.validators import InputRequired, Length from app.services import SERVICES -from ..forms import ContributionBaseForm, EditContributionBaseForm +from ..forms import ContributionBaseForm, UpdateContributionBaseForm class CreateSpaCyNLPPipelineModelForm(ContributionBaseForm): @@ -20,6 +20,8 @@ class CreateSpaCyNLPPipelineModelForm(ContributionBaseForm): raise ValidationError('.tar.gz files only!') def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-spacy-nlp-pipeline-model-form' super().__init__(*args, **kwargs) service_manifest = SERVICES['spacy-nlp-pipeline'] self.compatible_service_versions.choices = [('', 'Choose your option')] @@ -29,12 +31,14 @@ class CreateSpaCyNLPPipelineModelForm(ContributionBaseForm): self.compatible_service_versions.default = '' -class EditSpaCyNLPPipelineModelForm(EditContributionBaseForm): +class UpdateSpaCyNLPPipelineModelForm(UpdateContributionBaseForm): pipeline_name = StringField( 'Pipeline name', validators=[InputRequired(), Length(max=64)] ) def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'edit-spacy-nlp-pipeline-model-form' super().__init__(*args, **kwargs) service_manifest = SERVICES['spacy-nlp-pipeline'] self.compatible_service_versions.choices = [('', 'Choose your option')] diff --git a/app/contributions/spacy_nlp_pipeline_models/routes.py b/app/contributions/spacy_nlp_pipeline_models/routes.py index eab8ac49..f53d55f1 100644 --- a/app/contributions/spacy_nlp_pipeline_models/routes.py +++ b/app/contributions/spacy_nlp_pipeline_models/routes.py @@ -6,7 +6,7 @@ from app.models import SpaCyNLPPipelineModel from . import bp from .forms import ( CreateSpaCyNLPPipelineModelForm, - EditSpaCyNLPPipelineModelForm + UpdateSpaCyNLPPipelineModelForm ) from .utils import ( spacy_nlp_pipeline_model_dlc as spacy_nlp_pipeline_model_dlc @@ -63,7 +63,7 @@ def create_spacy_nlp_pipeline_model(): @login_required def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id): snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id) - form = EditSpaCyNLPPipelineModelForm(data=snpm.to_json_serializeable()) + form = UpdateSpaCyNLPPipelineModelForm(data=snpm.to_json_serializeable()) if form.validate_on_submit(): form.populate_obj(snpm) if db.session.is_modified(snpm): diff --git a/app/contributions/tesseract_ocr_pipeline_models/forms.py b/app/contributions/tesseract_ocr_pipeline_models/forms.py index 51f0d76c..9a5979dd 100644 --- a/app/contributions/tesseract_ocr_pipeline_models/forms.py +++ b/app/contributions/tesseract_ocr_pipeline_models/forms.py @@ -1,7 +1,7 @@ from flask_wtf.file import FileField, FileRequired from wtforms import ValidationError from app.services import SERVICES -from ..forms import ContributionBaseForm, EditContributionBaseForm +from ..forms import ContributionBaseForm, UpdateContributionBaseForm class CreateTesseractOCRPipelineModelForm(ContributionBaseForm): @@ -15,6 +15,8 @@ class CreateTesseractOCRPipelineModelForm(ContributionBaseForm): raise ValidationError('traineddata files only!') def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-tesseract-ocr-pipeline-model-form' service_manifest = SERVICES['tesseract-ocr-pipeline'] super().__init__(*args, **kwargs) self.compatible_service_versions.choices = [('', 'Choose your option')] @@ -24,8 +26,10 @@ class CreateTesseractOCRPipelineModelForm(ContributionBaseForm): self.compatible_service_versions.default = '' -class EditTesseractOCRPipelineModelForm(EditContributionBaseForm): +class UpdateTesseractOCRPipelineModelForm(UpdateContributionBaseForm): def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'edit-tesseract-ocr-pipeline-model-form' service_manifest = SERVICES['tesseract-ocr-pipeline'] super().__init__(*args, **kwargs) self.compatible_service_versions.choices = [('', 'Choose your option')] diff --git a/app/contributions/tesseract_ocr_pipeline_models/routes.py b/app/contributions/tesseract_ocr_pipeline_models/routes.py index 51adf402..e0261e80 100644 --- a/app/contributions/tesseract_ocr_pipeline_models/routes.py +++ b/app/contributions/tesseract_ocr_pipeline_models/routes.py @@ -6,7 +6,7 @@ from app.models import TesseractOCRPipelineModel from . import bp from .forms import ( CreateTesseractOCRPipelineModelForm, - EditTesseractOCRPipelineModelForm + UpdateTesseractOCRPipelineModelForm ) from .utils import ( tesseract_ocr_pipeline_model_dlc as tesseract_ocr_pipeline_model_dlc @@ -62,7 +62,7 @@ def create_tesseract_ocr_pipeline_model(): @login_required def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id): topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id) - form = EditTesseractOCRPipelineModelForm(data=topm.to_json_serializeable()) + form = UpdateTesseractOCRPipelineModelForm(data=topm.to_json_serializeable()) if form.validate_on_submit(): form.populate_obj(topm) if db.session.is_modified(topm): diff --git a/app/corpora/files/forms.py b/app/corpora/files/forms.py index c819fba2..e6918a83 100644 --- a/app/corpora/files/forms.py +++ b/app/corpora/files/forms.py @@ -1,3 +1,4 @@ +from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileRequired from wtforms import ( StringField, @@ -6,10 +7,9 @@ from wtforms import ( IntegerField ) from wtforms.validators import InputRequired, Length -from app.forms import NopaqueForm -class CorpusFileBaseForm(NopaqueForm): +class CorpusFileBaseForm(FlaskForm): author = StringField( 'Author', validators=[InputRequired(), Length(max=255)] @@ -41,6 +41,14 @@ class CreateCorpusFileForm(CorpusFileBaseForm): if not field.data.filename.lower().endswith('.vrt'): raise ValidationError('VRT files only!') + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-corpus-file-form' + super().__init__(*args, **kwargs) + class UpdateCorpusFileForm(CorpusFileBaseForm): - pass + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-corpus-file-form' + super().__init__(*args, **kwargs) diff --git a/app/corpora/forms.py b/app/corpora/forms.py index e923ca1b..fa8ccd05 100644 --- a/app/corpora/forms.py +++ b/app/corpora/forms.py @@ -1,9 +1,9 @@ +from flask_wtf import FlaskForm from wtforms import StringField, SubmitField, TextAreaField from wtforms.validators import InputRequired, Length -from app.forms import NopaqueForm -class CorpusBaseForm(NopaqueForm): +class CorpusBaseForm(FlaskForm): description = TextAreaField( 'Description', validators=[InputRequired(), Length(max=255)] @@ -13,12 +13,21 @@ class CorpusBaseForm(NopaqueForm): class CreateCorpusForm(CorpusBaseForm): - pass + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-corpus-form' + super().__init__(*args, **kwargs) class UpdateCorpusForm(CorpusBaseForm): - pass + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-corpus-form' + super().__init__(*args, **kwargs) -class ImportCorpusForm(NopaqueForm): - pass +class ImportCorpusForm(FlaskForm): + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'import-corpus-form' + super().__init__(*args, **kwargs) diff --git a/app/forms.py b/app/forms.py deleted file mode 100644 index 6ac58347..00000000 --- a/app/forms.py +++ /dev/null @@ -1,26 +0,0 @@ -from flask_wtf import FlaskForm -from wtforms.validators import ValidationError -import re - - -form_prefix_pattern = re.compile(r'(?= max_size_b: - raise ValidationError( - f'File size must be less or equal than {max_size_mb} MB' - ) - field.data.seek(0) - return file_length_check - - -class NopaqueForm(FlaskForm): - def __init__(self, *args, **kwargs): - if 'prefix' not in kwargs: - kwargs['prefix'] = \ - form_prefix_pattern.sub('-', self.__class__.__name__).lower() - super().__init__(*args, **kwargs) - diff --git a/app/services/forms.py b/app/services/forms.py index d53132f8..01b1cdd8 100644 --- a/app/services/forms.py +++ b/app/services/forms.py @@ -1,3 +1,4 @@ +from flask_wtf import FlaskForm from flask_login import current_user from flask_wtf.file import FileField, FileRequired from wtforms import ( @@ -10,12 +11,11 @@ from wtforms import ( ValidationError ) from wtforms.validators import InputRequired, Length -from app.forms import NopaqueForm from app.models import SpaCyNLPPipelineModel, TesseractOCRPipelineModel from . import SERVICES -class CreateJobBaseForm(NopaqueForm): +class CreateJobBaseForm(FlaskForm): description = StringField( 'Description', validators=[InputRequired(), Length(max=255)] @@ -38,6 +38,8 @@ class CreateFileSetupPipelineJobForm(CreateJobBaseForm): raise ValidationError('JPEG, PNG and TIFF files only!') def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-file-setup-pipeline-job-form' service_manifest = SERVICES['file-setup-pipeline'] version = kwargs.pop('version', service_manifest['latest_version']) super().__init__(*args, **kwargs) @@ -65,6 +67,8 @@ class CreateTesseractOCRPipelineJobForm(CreateJobBaseForm): raise ValidationError('PDF files only!') def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-tesseract-ocr-pipeline-job-form' service_manifest = SERVICES['tesseract-ocr-pipeline'] version = kwargs.pop('version', service_manifest['latest_version']) super().__init__(*args, **kwargs) @@ -111,6 +115,8 @@ class CreateTranskribusHTRPipelineJobForm(CreateJobBaseForm): raise ValidationError('PDF files only!') def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-transkribus-htr-pipeline-job-form' transkribus_htr_pipeline_models = kwargs.pop('transkribus_htr_pipeline_models', []) service_manifest = SERVICES['transkribus-htr-pipeline'] version = kwargs.pop('version', service_manifest['latest_version']) @@ -149,6 +155,8 @@ class CreateSpacyNLPPipelineJobForm(CreateJobBaseForm): raise ValidationError('Plain text files only!') def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'create-spacy-nlp-pipeline-job-form' service_manifest = SERVICES['spacy-nlp-pipeline'] version = kwargs.pop('version', service_manifest['latest_version']) super().__init__(*args, **kwargs) diff --git a/app/services/routes.py b/app/services/routes.py index 3a3cbd7b..7ab36384 100644 --- a/app/services/routes.py +++ b/app/services/routes.py @@ -35,7 +35,7 @@ def file_setup_pipeline(): version = request.args.get('version', service_manifest['latest_version']) if version not in service_manifest['versions']: abort(404) - form = CreateFileSetupPipelineJobForm(version=version) + form = CreateFileSetupPipelineJobForm(prefix='create-job-form', version=version) if form.is_submitted(): if not form.validate(): response = {'errors': form.errors} @@ -77,7 +77,7 @@ def tesseract_ocr_pipeline(): version = request.args.get('version', service_manifest['latest_version']) if version not in service_manifest['versions']: abort(404) - form = CreateTesseractOCRPipelineJobForm(version=version) + form = CreateTesseractOCRPipelineJobForm(prefix='create-job-form', version=version) if form.is_submitted(): if not form.validate(): response = {'errors': form.errors} @@ -137,8 +137,8 @@ def transkribus_htr_pipeline(): abort(500) transkribus_htr_pipeline_models = r.json()['trpModelMetadata'] transkribus_htr_pipeline_models.append({'modelId': 48513, 'name': 'Caroline Minuscle', 'language': 'lat', 'isoLanguages': ['lat']}) - print(transkribus_htr_pipeline_models[len(transkribus_htr_pipeline_models)-1]) form = CreateTranskribusHTRPipelineJobForm( + prefix='create-job-form', transkribus_htr_pipeline_models=transkribus_htr_pipeline_models, version=version ) @@ -186,7 +186,7 @@ def spacy_nlp_pipeline(): version = request.args.get('version', SERVICES[service]['latest_version']) if version not in service_manifest['versions']: abort(404) - form = CreateSpacyNLPPipelineJobForm(version=version) + form = CreateSpacyNLPPipelineJobForm(prefix='create-job-form', version=version) spacy_nlp_pipeline_models = SpaCyNLPPipelineModel.query.all() if form.is_submitted(): if not form.validate(): diff --git a/app/settings/forms.py b/app/settings/forms.py index 6778bbe6..77c8687c 100644 --- a/app/settings/forms.py +++ b/app/settings/forms.py @@ -1,4 +1,5 @@ from flask_login import current_user +from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileRequired from wtforms import ( PasswordField, @@ -15,11 +16,11 @@ from wtforms.validators import ( Length, Regexp ) -from app.forms import NopaqueForm, LimitFileSize from app.models import User, UserSettingJobStatusMailNotificationLevel +from app.wtforms.validators import FileSize -class UpdateAccountInformationForm(NopaqueForm): +class UpdateAccountInformationForm(FlaskForm): email = StringField( 'E-Mail', validators=[DataRequired(), Length(max=254), Email()] @@ -43,6 +44,8 @@ class UpdateAccountInformationForm(NopaqueForm): def __init__(self, *args, user=current_user, **kwargs): if 'data' not in kwargs: kwargs['data'] = user.to_json_serializeable() + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-account-information-form' super().__init__(*args, **kwargs) self.user = user @@ -57,7 +60,7 @@ class UpdateAccountInformationForm(NopaqueForm): raise ValidationError('Username already in use') -class UpdateProfileInformationForm(NopaqueForm): +class UpdateProfileInformationForm(FlaskForm): full_name = StringField( 'Full name', validators=[Length(max=128)] @@ -91,11 +94,13 @@ class UpdateProfileInformationForm(NopaqueForm): def __init__(self, *args, user=current_user, **kwargs): if 'data' not in kwargs: kwargs['data'] = user.to_json_serializeable() + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-profile-information-form' super().__init__(*args, **kwargs) -class UpdateAvatarForm(NopaqueForm): - avatar = FileField('File', validators=[FileRequired(), LimitFileSize(2)]) +class UpdateAvatarForm(FlaskForm): + avatar = FileField('File', validators=[FileRequired(), FileSize(2)]) submit = SubmitField() def validate_avatar(self, field): @@ -103,7 +108,13 @@ class UpdateAvatarForm(NopaqueForm): if field.data.mimetype not in valid_mimetypes: raise ValidationError('JPEG and PNG files only!') -class UpdatePasswordForm(NopaqueForm): + def __init__(self, *args, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-avatar-form' + super().__init__(*args, **kwargs) + + +class UpdatePasswordForm(FlaskForm): password = PasswordField('Old password', validators=[DataRequired()]) new_password = PasswordField( 'New password', @@ -122,6 +133,8 @@ class UpdatePasswordForm(NopaqueForm): submit = SubmitField() def __init__(self, *args, user=current_user, **kwargs): + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-password-form' super().__init__(*args, **kwargs) self.user = user @@ -130,7 +143,7 @@ class UpdatePasswordForm(NopaqueForm): raise ValidationError('Invalid password') -class UpdateNotificationsForm(NopaqueForm): +class UpdateNotificationsForm(FlaskForm): job_status_mail_notification_level = SelectField( 'Job status mail notification level', choices=[ @@ -144,4 +157,6 @@ class UpdateNotificationsForm(NopaqueForm): def __init__(self, *args, user=current_user, **kwargs): if 'data' not in kwargs: kwargs['data'] = user.to_json_serializeable() + if 'prefix' not in kwargs: + kwargs['prefix'] = 'update-notifications-form' super().__init__(*args, **kwargs) diff --git a/app/templates/services/corpus_analysis.html.j2 b/app/templates/services/corpus_analysis.html.j2 index 9ddc9ec3..47fc6a47 100644 --- a/app/templates/services/corpus_analysis.html.j2 +++ b/app/templates/services/corpus_analysis.html.j2 @@ -28,38 +28,11 @@
- Import Corpusimport_export + Import Corpusimport_export Create corpusadd
- -
-

My query results

-
-
-
- search - - -
- - - - - - - - - -
Title and DescriptionCorpus and Query
-
    -
    - -
    -
    {% endblock page_content %} diff --git a/app/wtforms/__init__.py b/app/wtforms/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/app/wtforms/validators.py b/app/wtforms/validators.py new file mode 100644 index 00000000..bef95681 --- /dev/null +++ b/app/wtforms/validators.py @@ -0,0 +1,14 @@ +from wtforms.validators import ValidationError + + +def FileSize(max_size_mb): + max_size_b = max_size_mb * 1024 * 1024 + + def file_length_check(form, field): + if len(field.data.read()) >= max_size_b: + raise ValidationError( + f'File size must be less or equal than {max_size_mb} MB' + ) + field.data.seek(0) + + return file_length_check