from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileRequired, FileSize from wtforms import ( PasswordField, SelectField, StringField, SubmitField, TextAreaField, ValidationError ) from wtforms.validators import ( DataRequired, Email, EqualTo, Length, Regexp ) from app.models import User, UserSettingJobStatusMailNotificationLevel class UpdateAccountInformationForm(FlaskForm): email = StringField( 'E-Mail', validators=[DataRequired(), Length(max=254), Email()] ) username = StringField( 'Username', validators=[ DataRequired(), Length(max=64), Regexp( User.username_pattern, message=( 'Usernames must have only letters, numbers, dots or ' 'underscores' ) ) ] ) submit = SubmitField() def __init__(self, user: User, *args, **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 def validate_email(self, field): if (field.data != self.user.email and User.query.filter_by(email=field.data).first()): raise ValidationError('Email already registered') def validate_username(self, field): if (field.data != self.user.username and User.query.filter_by(username=field.data).first()): raise ValidationError('Username already in use') class UpdateProfileInformationForm(FlaskForm): full_name = StringField( 'Full name', validators=[Length(max=128)] ) about_me = TextAreaField( 'About me', validators=[ Length(max=254) ] ) website = StringField( 'Website', validators=[ Length(max=254) ] ) organization = StringField( 'Organization', validators=[ Length(max=128) ] ) location = StringField( 'Location', validators=[ Length(max=128) ] ) submit = SubmitField() def __init__(self, user: User, *args, **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(FlaskForm): avatar = FileField('File', validators=[FileRequired(), FileSize(2_000_000)]) submit = SubmitField() def validate_avatar(self, field): valid_mimetypes = ['image/jpeg', 'image/png'] if field.data.mimetype not in valid_mimetypes: raise ValidationError('JPEG and PNG files only!') 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', validators=[ DataRequired(), EqualTo('new_password_2', message='Passwords must match') ] ) new_password_2 = PasswordField( 'New password confirmation', validators=[ DataRequired(), EqualTo('new_password', message='Passwords must match') ] ) submit = SubmitField() def __init__(self, user: User, *args, **kwargs): if 'prefix' not in kwargs: kwargs['prefix'] = 'update-password-form' super().__init__(*args, **kwargs) self.user = user def validate_current_password(self, field): if not self.user.verify_password(field.data): raise ValidationError('Invalid password') class UpdateNotificationsForm(FlaskForm): job_status_mail_notification_level = SelectField( 'Job status mail notification level', choices=[ (x.name, x.name.capitalize()) for x in UserSettingJobStatusMailNotificationLevel ], validators=[DataRequired()] ) submit = SubmitField() def __init__(self, user: User, *args, **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)