Beispiel #1
0
class LoginForm(FlaskForm):
    email = wtforms.StringField('Пошта', validators=[DataRequired(), Email()])
    password = wtforms.PasswordField('Пароль', validators=[DataRequired()])
    remember_me = wtforms.BooleanField("Запам'ятати мене")
    submit = wtforms.SubmitField('Увійти')
Beispiel #2
0
class ConfirmDeleteForm(wtforms.Form):
    confirm = wtforms.BooleanField(_('I am sure I want to delete this'))
Beispiel #3
0
class SecurityPolicyForm(BaseSecureForm):
    """ELB Security Policy form"""
    predefined_policy_error_msg = _(u'Policy is required')
    predefined_policy = wtforms.SelectField(
        label=_(u'Policy name'),
        validators=[
            PredefinedPolicyRequired(message=predefined_policy_error_msg)
        ],
    )
    ssl_protocols_error_msg = _(u'At least one protocol is required.')
    ssl_protocols = wtforms.SelectMultipleField(
        label=_(u'SSL Protocols'),
        validators=[validators.InputRequired(message=ssl_protocols_error_msg)],
    )
    ssl_ciphers_error_msg = _(u'At least one cipher is required.')
    ssl_ciphers = wtforms.SelectMultipleField(
        label=_(u'SSL Ciphers'),
        validators=[validators.InputRequired(message=ssl_ciphers_error_msg)],
    )
    server_order_preference = wtforms.BooleanField(
        label=_(u'Server order preference'))  # Under SSL Options

    def __init__(self,
                 request,
                 elb_conn=None,
                 predefined_policy_choices=None,
                 **kwargs):
        super(SecurityPolicyForm, self).__init__(request, **kwargs)
        self.elb_conn = elb_conn
        self.predefined_policy_choices = predefined_policy_choices
        self.set_error_messages()
        self.set_choices()
        self.set_initial_data()

    def set_error_messages(self):
        self.predefined_policy.error_msg = self.predefined_policy_error_msg
        self.ssl_protocols.error_msg = self.ssl_protocols_error_msg
        self.ssl_ciphers.error_msg = self.ssl_ciphers_error_msg

    def set_choices(self):
        self.ssl_protocols.choices = self.get_ssl_protocol_choices()
        self.ssl_ciphers.choices = self.get_ssl_cipher_choices()
        self.predefined_policy.choices = self.get_predefined_policy_choices()

    def set_initial_data(self):
        # Default to TLS 1, 1.1, and 1.2 for ssl_protocols
        self.ssl_protocols.data = [
            val for val, label in self.get_ssl_protocol_choices()
        ]

    def get_predefined_policy_choices(self):
        if self.predefined_policy_choices:
            return self.predefined_policy_choices
        if self.elb_conn is not None:
            return ChoicesManager(
                conn=self.elb_conn).predefined_policy_choices(add_blank=False)
        return []

    @staticmethod
    def get_ssl_protocol_choices():
        return [
            ('Protocol-TLSv1.2', u'TLSv1.2'),
            ('Protocol-TLSv1.1', u'TLSv1.1'),
            ('Protocol-TLSv1', u'TLSv1'),
        ]

    @staticmethod
    def get_ssl_cipher_choices():
        return [(val, val) for val in SSL_CIPHERS]
Beispiel #4
0
class PagureForm(FlaskForm):
    """ Form to configure the pagure hook. """

    active = wtforms.BooleanField("Active", [wtforms.validators.Optional()])
Beispiel #5
0
class UpdateIssueForm(PagureForm):
    """ Form to add a comment to an issue. """

    tag = wtforms.StringField(
        "tag",
        [
            wtforms.validators.Optional(),
            wtforms.validators.Regexp(TAGS_REGEX_MULTI, flags=re.IGNORECASE),
            wtforms.validators.Length(max=255),
        ],
    )
    depending = wtforms.StringField("depending issue",
                                    [wtforms.validators.Optional()])
    blocking = wtforms.StringField("blocking issue",
                                   [wtforms.validators.Optional()])
    comment = wtforms.TextAreaField("Comment", [wtforms.validators.Optional()])
    assignee = wtforms.TextAreaField("Assigned to",
                                     [wtforms.validators.Optional()])
    status = wtforms.SelectField("Status", [wtforms.validators.Optional()],
                                 choices=[])
    priority = wtforms.SelectField("Priority", [wtforms.validators.Optional()],
                                   choices=[])
    milestone = wtforms.SelectField(
        "Milestone",
        [wtforms.validators.Optional()],
        choices=[],
        coerce=convert_value,
    )
    private = wtforms.BooleanField("Private", [wtforms.validators.optional()],
                                   false_values=FALSE_VALUES)
    close_status = wtforms.SelectField(
        "Closed as",
        [wtforms.validators.Optional()],
        choices=[],
        coerce=convert_value,
    )

    def __init__(self, *args, **kwargs):
        """ Calls the default constructor with the normal argument but
        uses the list of collection provided to fill the choices of the
        drop-down list.
        """
        super(UpdateIssueForm, self).__init__(*args, **kwargs)
        if "status" in kwargs:
            self.status.choices = [(status, status)
                                   for status in kwargs["status"]]

        self.priority.choices = []
        if "priorities" in kwargs:
            for key in sorted(kwargs["priorities"]):
                self.priority.choices.append((key, kwargs["priorities"][key]))

        self.milestone.choices = []
        if "milestones" in kwargs and kwargs["milestones"]:
            for key in kwargs["milestones"]:
                self.milestone.choices.append((key, key))
            self.milestone.choices.insert(0, ("", ""))

        self.close_status.choices = []
        if "close_status" in kwargs:
            for key in sorted(kwargs["close_status"]):
                self.close_status.choices.append((key, key))
            self.close_status.choices.insert(0, ("", ""))
Beispiel #6
0
class PagureRequestsForm(FlaskForm):
    ''' Form to configure the pagure hook. '''
    active = wtforms.BooleanField('Active', [wtforms.validators.Optional()])
Beispiel #7
0
class LoginForm(flask_wtf.FlaskForm):
    password = wtforms.PasswordField('Password')
    remember_me = wtforms.BooleanField('Remember me', default=True)
Beispiel #8
0
class MailForm(wtf.Form):
    ''' Form to configure the mail hook. '''
    mail_to = wtforms.TextField('Mail to', [RequiredIf('active')])
    active = wtforms.BooleanField('Active', [wtforms.validators.Optional()])
Beispiel #9
0
class ProposalAdminForm(ProposalForm):
    """Extends Proposal form to use in admin interface"""
    event_id = wtf.StringField()
    approved = wtf.BooleanField()
    submit = None
Beispiel #10
0
class ImageClassificationDatasetForm(ImageDatasetForm):
    """
    Defines the form used to create a new ImageClassificationDatasetJob
    """

    backend = wtforms.SelectField(
        'DB backend',
        choices=[('lmdb', 'LMDB'), ('hdf5', 'HDF5'),
                 ('tfrecords', 'TFRecords')],
        default='lmdb',
    )

    def validate_backend(form, field):
        if field.data == 'lmdb':
            form.compression.data = 'none'
        elif field.data == 'tfrecords':
            form.compression.data = 'none'
        elif field.data == 'hdf5':
            form.encoding.data = 'none'

    compression = utils.forms.SelectField(
        'DB compression',
        choices=[
            ('none', 'None'),
            ('gzip', 'GZIP'),
        ],
        default='none',
        tooltip=(
            'Compressing the dataset may significantly decrease the size '
            'of your database files, but it may increase read and write times.'
        ),
    )

    # Use a SelectField instead of a HiddenField so that the default value
    # is used when nothing is provided (through the REST API)
    method = wtforms.SelectField(
        u'Dataset type',
        choices=[
            ('folder', 'Folder'),
            ('textfile', 'Textfiles'),
            ('s3', 'S3'),
        ],
        default='folder',
    )

    def validate_folder_path(form, field):
        if not field.data:
            pass
        elif utils.is_url(field.data):
            # make sure the URL exists
            try:
                r = requests.get(field.data,
                                 allow_redirects=False,
                                 timeout=utils.HTTP_TIMEOUT)
                if r.status_code not in [
                        requests.codes.ok, requests.codes.moved,
                        requests.codes.found
                ]:
                    raise validators.ValidationError('URL not found')
            except Exception as e:
                raise validators.ValidationError(
                    'Caught %s while checking URL: %s' % (type(e).__name__, e))
            else:
                return True
        else:
            # make sure the filesystem path exists
            # and make sure the filesystem path is absolute
            if not os.path.exists(field.data) or not os.path.isdir(field.data):
                raise validators.ValidationError('Folder does not exist')
            elif not os.path.isabs(field.data):
                raise validators.ValidationError(
                    'Filesystem path is not absolute')
            else:
                return True

    #
    # Method - folder
    #

    folder_train = utils.forms.StringField(
        u'Training Images',
        validators=[
            validate_required_iff(method='folder'),
            validate_folder_path,
        ],
        tooltip=
        ('Indicate a folder which holds subfolders full of images. '
         'Each subfolder should be named according to the desired label for the images that it holds. '
         'Can also be a URL for an apache/nginx auto-indexed folder.'),
    )

    folder_pct_val = utils.forms.IntegerField(
        u'% for validation',
        default=25,
        validators=[
            validate_required_iff(method='folder'),
            validators.NumberRange(min=0, max=100)
        ],
        tooltip=('You can choose to set apart a certain percentage of images '
                 'from the training images for the validation set.'),
    )

    folder_pct_test = utils.forms.IntegerField(
        u'% for testing',
        default=0,
        validators=[
            validate_required_iff(method='folder'),
            validators.NumberRange(min=0, max=100)
        ],
        tooltip=('You can choose to set apart a certain percentage of images '
                 'from the training images for the test set.'),
    )

    folder_train_min_per_class = utils.forms.IntegerField(
        u'Minimum samples per class',
        default=2,
        validators=[
            validators.Optional(),
            validators.NumberRange(min=1),
        ],
        tooltip=
        ('You can choose to specify a minimum number of samples per class. '
         'If a class has fewer samples than the specified amount it will be ignored. '
         'Leave blank to ignore this feature.'),
    )

    folder_train_max_per_class = utils.forms.IntegerField(
        u'Maximum samples per class',
        validators=[
            validators.Optional(),
            validators.NumberRange(min=1),
            validate_greater_than('folder_train_min_per_class'),
        ],
        tooltip=
        ('You can choose to specify a maximum number of samples per class. '
         'If a class has more samples than the specified amount extra samples will be ignored. '
         'Leave blank to ignore this feature.'),
    )

    has_val_folder = wtforms.BooleanField(
        'Separate validation images folder',
        default=False,
        validators=[validate_required_iff(method='folder')])

    folder_val = wtforms.StringField(u'Validation Images',
                                     validators=[
                                         validate_required_iff(
                                             method='folder',
                                             has_val_folder=True),
                                     ])

    folder_val_min_per_class = utils.forms.IntegerField(
        u'Minimum samples per class',
        default=2,
        validators=[
            validators.Optional(),
            validators.NumberRange(min=1),
        ],
        tooltip=
        ('You can choose to specify a minimum number of samples per class. '
         'If a class has fewer samples than the specified amount it will be ignored. '
         'Leave blank to ignore this feature.'),
    )

    folder_val_max_per_class = utils.forms.IntegerField(
        u'Maximum samples per class',
        validators=[
            validators.Optional(),
            validators.NumberRange(min=1),
            validate_greater_than('folder_val_min_per_class'),
        ],
        tooltip=
        ('You can choose to specify a maximum number of samples per class. '
         'If a class has more samples than the specified amount extra samples will be ignored. '
         'Leave blank to ignore this feature.'),
    )

    has_test_folder = wtforms.BooleanField(
        'Separate test images folder',
        default=False,
        validators=[validate_required_iff(method='folder')])

    folder_test = wtforms.StringField(u'Test Images',
                                      validators=[
                                          validate_required_iff(
                                              method='folder',
                                              has_test_folder=True),
                                          validate_folder_path,
                                      ])

    folder_test_min_per_class = utils.forms.IntegerField(
        u'Minimum samples per class',
        default=2,
        validators=[validators.Optional(),
                    validators.NumberRange(min=1)],
        tooltip=
        ('You can choose to specify a minimum number of samples per class. '
         'If a class has fewer samples than the specified amount it will be ignored. '
         'Leave blank to ignore this feature.'),
    )

    folder_test_max_per_class = utils.forms.IntegerField(
        u'Maximum samples per class',
        validators=[
            validators.Optional(),
            validators.NumberRange(min=1),
            validate_greater_than('folder_test_min_per_class'),
        ],
        tooltip=
        ('You can choose to specify a maximum number of samples per class. '
         'If a class has more samples than the specified amount extra samples will be ignored. '
         'Leave blank to ignore this feature.'),
    )

    #
    # Method - textfile
    #

    textfile_use_local_files = wtforms.BooleanField(
        u'Use local files',
        default=False,
    )

    textfile_train_images = utils.forms.FileField(
        u'Training images',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_local_files=False)
        ])

    textfile_local_train_images = wtforms.StringField(
        u'Training images',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_local_files=True)
        ])

    textfile_train_folder = wtforms.StringField(u'Training images folder')

    def validate_textfile_train_folder(form, field):
        if form.method.data != 'textfile':
            field.errors[:] = []
            raise validators.StopValidation()
        if not field.data.strip():
            # allow null
            return True
        if not os.path.exists(field.data) or not os.path.isdir(field.data):
            raise validators.ValidationError('folder does not exist')
        return True

    textfile_use_val = wtforms.BooleanField(
        u'Validation set',
        default=True,
        validators=[validate_required_iff(method='textfile')])
    textfile_val_images = utils.forms.FileField(
        u'Validation images',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_val=True,
                                  textfile_use_local_files=False)
        ])
    textfile_local_val_images = wtforms.StringField(
        u'Validation images',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_val=True,
                                  textfile_use_local_files=True)
        ])
    textfile_val_folder = wtforms.StringField(u'Validation images folder')

    def validate_textfile_val_folder(form, field):
        if form.method.data != 'textfile' or not form.textfile_use_val.data:
            field.errors[:] = []
            raise validators.StopValidation()
        if not field.data.strip():
            # allow null
            return True
        if not os.path.exists(field.data) or not os.path.isdir(field.data):
            raise validators.ValidationError('folder does not exist')
        return True

    textfile_use_test = wtforms.BooleanField(
        u'Test set',
        default=False,
        validators=[validate_required_iff(method='textfile')])
    textfile_test_images = utils.forms.FileField(
        u'Test images',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_test=True,
                                  textfile_use_local_files=False)
        ])
    textfile_local_test_images = wtforms.StringField(
        u'Test images',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_test=True,
                                  textfile_use_local_files=True)
        ])
    textfile_test_folder = wtforms.StringField(u'Test images folder')

    def validate_textfile_test_folder(form, field):
        if form.method.data != 'textfile' or not form.textfile_use_test.data:
            field.errors[:] = []
            raise validators.StopValidation()
        if not field.data.strip():
            # allow null
            return True
        if not os.path.exists(field.data) or not os.path.isdir(field.data):
            raise validators.ValidationError('folder does not exist')
        return True

    # Can't use a BooleanField here because HTML doesn't submit anything
    # for an unchecked checkbox. Since we want to use a REST API and have
    # this default to True when nothing is supplied, we have to use a
    # SelectField
    textfile_shuffle = utils.forms.SelectField(
        'Shuffle lines',
        choices=[
            (1, 'Yes'),
            (0, 'No'),
        ],
        coerce=int,
        default=1,
        tooltip="Shuffle the list[s] of images before creating the database.")

    textfile_labels_file = utils.forms.FileField(
        u'Labels',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_local_files=False)
        ],
        tooltip=
        ("The 'i'th line of the file should give the string label "
         "associated with the '(i-1)'th numeric label. (E.g. the string label "
         "for the numeric label 0 is supposed to be on line 1.)"),
    )

    textfile_local_labels_file = utils.forms.StringField(
        u'Labels',
        validators=[
            validate_required_iff(method='textfile',
                                  textfile_use_local_files=True)
        ],
        tooltip=
        ("The 'i'th line of the file should give the string label "
         "associated with the '(i-1)'th numeric label. (E.g. the string label "
         "for the numeric label 0 is supposed to be on line 1.)"),
    )

    #
    # Method - S3
    #

    s3_endpoint_url = utils.forms.StringField(
        u'Training Images',
        tooltip=('S3 end point URL'),
    )

    s3_bucket = utils.forms.StringField(
        u'Bucket Name',
        tooltip=('bucket name'),
    )

    s3_path = utils.forms.StringField(
        u'Training Images Path',
        tooltip=
        ('Indicate a path which holds subfolders full of images. '
         'Each subfolder should be named according to the desired label for the images that it holds. '
         ),
    )

    s3_accesskey = utils.forms.StringField(
        u'Access Key',
        tooltip=('Access Key to access this S3 End Point'),
    )

    s3_secretkey = utils.forms.StringField(
        u'Secret Key',
        tooltip=('Secret Key to access this S3 End Point'),
    )

    s3_keepcopiesondisk = utils.forms.BooleanField(
        u'Keep Copies of Files on Disk',
        tooltip=
        ('Checking this box will keep raw files retrieved from S3 stored on disk after the job is completed'
         ),
    )

    s3_pct_val = utils.forms.IntegerField(
        u'% for validation',
        default=25,
        validators=[
            validate_required_iff(method='s3'),
            validators.NumberRange(min=0, max=100)
        ],
        tooltip=('You can choose to set apart a certain percentage of images '
                 'from the training images for the validation set.'),
    )

    s3_pct_test = utils.forms.IntegerField(
        u'% for testing',
        default=0,
        validators=[
            validate_required_iff(method='s3'),
            validators.NumberRange(min=0, max=100)
        ],
        tooltip=('You can choose to set apart a certain percentage of images '
                 'from the training images for the test set.'),
    )

    s3_train_min_per_class = utils.forms.IntegerField(
        u'Minimum samples per class',
        default=2,
        validators=[
            validators.Optional(),
            validators.NumberRange(min=1),
        ],
        tooltip=
        ('You can choose to specify a minimum number of samples per class. '
         'If a class has fewer samples than the specified amount it will be ignored. '
         'Leave blank to ignore this feature.'),
    )

    s3_train_max_per_class = utils.forms.IntegerField(
        u'Maximum samples per class',
        validators=[
            validators.Optional(),
            validators.NumberRange(min=1),
            validate_greater_than('s3_train_min_per_class'),
        ],
        tooltip=
        ('You can choose to specify a maximum number of samples per class. '
         'If a class has more samples than the specified amount extra samples will be ignored. '
         'Leave blank to ignore this feature.'),
    )
Beispiel #11
0
class MultiTypeLoginForm(FlaskForm):
    username = wtforms.StringField('Username',
                                   validators=[validators.Required()])
    password = wtforms.PasswordField('Password',
                                     validators=[validators.Required()])
    submit = wtforms.SubmitField('Submit')
    remember_me = wtforms.BooleanField('Remember Me', default=True)
    logintype = wtforms.RadioField(
        'Login Type',
        choices=[
            ('username', 'Username & Password'),
            #('omp', 'Project ID & Project Password'),
            ('ldap', 'Staff Login via ldap')
        ],
        validators=[validators.Required()])

    # def validate_omp_project_password(self):
    #     logger.debug('Validing LoginForm with project id and project password')
    #     # These are stored in the database as plain text.
    #     rsession = ReadOnlySession()
    #     encrypted_db = rsession.query(omp.proj.encrypted).filter(
    #         omp.proj.projectid==self.username.data).one_or_none()[0]
    #     salted_password = crypt.crypt(self.password.data, salt=encrypted_db)
    #     if encrypted_db == salted_password:
    #         self.user = ProjectUser(self.username.data)
    #         login_user(self.user)
    #         return True
    #     else:
    #         self.user = None
    #         return False

    # def validate_username_password(self):
    #     """
    #     Currently looking this up in a file with test (fake) hash
    #     passwords for a couple of user names; should eventually access
    #     hediwg login, via Oauth.
    #     """

    #     # For this to work you must have a connection to the hedwig database.
    #     hedwigdb = hedwig_get_database()
    #     hedwig_id = hedwigdb.authenticate_user(self.username.data, self.password.data)
    #     if hedwig_id is not None:
    #         rsession =  ReadOnlySession()
    #         OMP_username = rsession.query(hedwig2omp.user.omp_id).\
    #                    filter(hedwig2omp.user.hedwig_id==hedwig_id).one_or_none()[0]
    #         rsession.close()
    #         print(self.username.data, OMP_username)
    #         self.user = HedwigUser(hedwig_id, OMP_username)
    #         login_user(self.user)
    #         return True
    #     else:
    #         self.user = None
    #         return False

    def validate_ldap(self):
        """
        Taken from the flask_ldap3_login form, but with different user saving.
        """
        logging.debug('Validating LoginForm against LDAP')
        ldap_mgr = current_app.ldap3_login_manager
        username = self.username.data
        password = self.password.data

        result = ldap_mgr.authenticate(username, password)

        if result.status == AuthenticationResponseStatus.success:
            self.user = LDAPUser(result.user_id, result.user_info)
            login_user(self.user)
            return True

        else:
            self.user = None
            self.username.errors.append('Invalid Username/Password.')
            self.password.errors.append('Invalid Username/Password.')
            return False

    def validate(self, *args, **kwargs):
        """
        Validates the form by calling `validate` on each field, passing any
        extra `Form.validate_<fieldname>` validators to the field validator.

        also calls `validate_ldap`

        If it is successful at loggin in, it will create a form.user
        User object in the output.
        """

        logging.debug(' Form validation in progress')
        valid = FlaskForm.validate(self, *args, **kwargs)
        if not valid:
            logging.debug("Form validation failed before we had a chance to "
                          "check ldap. Reasons: '{0}'".format(self.errors))
            return valid

        print(self.logintype.data, type(self.logintype.data))
        if self.logintype.data == 'ldap':

            logging.debug('IN LDAP VALIDARTION')
            return self.validate_ldap()
Beispiel #12
0
class UserCreateForm(UserRegisterForm):
    status = wtforms.BooleanField("User status", false_values=FALSE_VALUES)
Beispiel #13
0
class CreateLaunchConfigForm(BaseSecureForm):
    """Create Launch Configuration form"""
    image_id = wtforms.HiddenField(label=_(u'Image'))
    name_error_msg = _(
        u'Name must be between 1 and 255 characters long, and must not contain \'/\' and \'\\\''
    )
    name = wtforms.TextField(
        label=_(u'Name'),
        validators=[validators.InputRequired(message=name_error_msg)],
    )
    instance_type_error_msg = _(u'Instance type is required')
    instance_type = wtforms.SelectField(
        label=_(u'Instance type'),
        validators=[validators.InputRequired(message=instance_type_error_msg)],
    )
    keypair_error_msg = _(u'Key pair is required')
    keypair = wtforms.SelectField(
        label=_(u'Key name'),
        validators=[validators.InputRequired(message=keypair_error_msg)],
    )
    securitygroup_error_msg = _(u'Security group is required')
    securitygroup = wtforms.SelectMultipleField(
        label=_(u'Security group'),
        validators=[validators.InputRequired(message=securitygroup_error_msg)],
    )
    associate_public_ip_address = wtforms.SelectField(
        label=_(u'VPC IP assignment'))
    associate_public_ip_address_helptext = _(u'This setting only applies \
        when this launch configuration is used with a scaling group using a VPC network.'
                                             )
    role = wtforms.SelectField()
    userdata = wtforms.TextAreaField(label=_(u'User data'))
    userdata_file_helptext = _(u'User data file may not exceed 16 KB')
    userdata_file = wtforms.FileField(label='')
    kernel_id = wtforms.SelectField(label=_(u'Kernel ID'))
    ramdisk_id = wtforms.SelectField(label=_(u'RAM disk ID (RAMFS)'))
    monitoring_enabled = wtforms.BooleanField(label=_(u'Enable monitoring'))
    create_sg_from_lc = wtforms.BooleanField(
        label=_(u'Create scaling group using this launch configuration'))

    def __init__(self,
                 request,
                 image=None,
                 securitygroups=None,
                 keyname=None,
                 conn=None,
                 iam_conn=None,
                 **kwargs):
        super(CreateLaunchConfigForm, self).__init__(request, **kwargs)
        self.image = image
        self.keyname = keyname
        self.securitygroups = securitygroups
        self.conn = conn
        self.iam_conn = iam_conn
        self.cloud_type = request.session.get('cloud_type', 'euca')
        self.set_error_messages()
        self.monitoring_enabled.data = True
        self.create_sg_from_lc.data = True
        self.choices_manager = ChoicesManager(conn=conn)
        self.set_help_text()
        self.set_choices()
        self.set_monitoring_enabled_field()

        if image is not None:
            self.image_id.data = self.image.id
        if self.keyname is not None:
            self.keypair.data = self.keyname
        instance_id = request.params.get('userdata_instanceid')
        if instance_id is not None:
            with boto_error_handler(self.request):
                userdata = self.conn.get_instance_attribute(
                    instance_id, 'userData')
                userdata = userdata['userData']
                self.userdata.data = base64.b64decode(
                    userdata) if userdata is not None else ''

    def set_monitoring_enabled_field(self):
        if self.cloud_type == 'euca':
            self.monitoring_enabled.data = True
            self.monitoring_enabled.help_text = _(
                u'Gather CloudWatch metric data for instances that use this launch configuration.'
            )
        elif self.cloud_type == 'aws':
            self.monitoring_enabled.label.text = _(
                u'Enable detailed monitoring')
            self.monitoring_enabled.help_text = _(
                u'Gather all CloudWatch metric data at a higher frequency, '
                u'and enable data aggregation by AMI and instance type. '
                u'If left unchecked, data will still be gathered, but less often '
                u'and without aggregation. ')

    def set_help_text(self):
        self.associate_public_ip_address.help_text = self.associate_public_ip_address_helptext
        self.userdata_file.help_text = self.userdata_file_helptext

    def set_choices(self):
        self.instance_type.choices = self.choices_manager.instance_types(
            cloud_type=self.cloud_type)
        empty_key_opt = True
        if self.keyname is not None:
            empty_key_opt = False
        self.keypair.choices = self.choices_manager.keypairs(
            add_blank=empty_key_opt, no_keypair_option=True)
        self.securitygroup.choices = self.choices_manager.security_groups(
            securitygroups=self.securitygroups, use_id=True, add_blank=False)
        self.role.choices = ChoicesManager(self.iam_conn).roles(add_blank=True)
        self.kernel_id.choices = self.choices_manager.kernels(image=self.image)
        self.ramdisk_id.choices = self.choices_manager.ramdisks(
            image=self.image)
        self.associate_public_ip_address.choices = self.get_associate_public_ip_address_choices(
        )

        # Set init data for security group
        if len(self.securitygroup.choices) > 1:
            self.securitygroup.data = [
                value for value, label in self.securitygroup.choices
            ]

    @staticmethod
    def get_associate_public_ip_address_choices():
        return [('None', _(u'Only for instances in default VPC & subnet')),
                ('true', _(u'For all instances')), ('false', _(u'Never'))]

    def set_error_messages(self):
        self.name.error_msg = self.name_error_msg
        self.instance_type.error_msg = self.instance_type_error_msg
        self.securitygroup.error_msg = self.securitygroup_error_msg
Beispiel #14
0
class ModeForm(Form):
    is_ca = wtforms.BooleanField("CA")
    is_server_auth = wtforms.BooleanField("Server Auth")
    is_client_auth = wtforms.BooleanField("Client Auth")
Beispiel #15
0
class MemberForm(wtf.Form):
    gh_login = wtforms.TextField('User\'s GitHub login', [required])
    is_manager = wtforms.BooleanField(
        'Is manager?', [wtforms.validators.NumberRange(0, 1)])
    submit = wtforms.SubmitField('Save')
Beispiel #16
0
    def create_form_cls(mock_chroots=None, user=None, group=None):
        class F(wtf.Form):
            # also use id here, to be able to find out whether user
            # is updating a copr if so, we don't want to shout
            # that name already exists
            id = wtforms.HiddenField()
            group_id = wtforms.HiddenField()

            name = wtforms.StringField(
                "Name",
                validators=[
                    wtforms.validators.DataRequired(),
                    wtforms.validators.Regexp(
                        re.compile(r"^[\w.-]+$"),
                        message="Name must contain only letters,"
                        "digits, underscores, dashes and dots."),
                    CoprUniqueNameValidator(user=user, group=group),
                    NameNotNumberValidator()
                ])

            homepage = wtforms.StringField("Homepage",
                                           validators=[
                                               wtforms.validators.Optional(),
                                               wtforms.validators.URL()
                                           ])

            contact = wtforms.StringField(
                "Contact",
                validators=[wtforms.validators.Optional(),
                            EmailOrURL()])

            description = wtforms.TextAreaField("Description")

            instructions = wtforms.TextAreaField("Instructions")

            repos = wtforms.TextAreaField("External Repositories",
                                          validators=[UrlRepoListValidator()],
                                          filters=[StringListFilter()])

            initial_pkgs = wtforms.TextAreaField(
                "Initial packages to build",
                validators=[UrlListValidator(),
                            UrlSrpmListValidator()],
                filters=[StringListFilter()])

            disable_createrepo = wtforms.BooleanField(default=False)
            build_enable_net = wtforms.BooleanField(default=False)

            @property
            def selected_chroots(self):
                selected = []
                for ch in self.chroots_list:
                    if getattr(self, ch).data:
                        selected.append(ch)
                return selected

            def validate(self):
                if not super(F, self).validate():
                    return False

                if not self.validate_mock_chroots_not_empty():
                    self._mock_chroots_error = "At least one chroot" \
                        " must be selected"
                    return False
                return True

            def validate_mock_chroots_not_empty(self):
                have_any = False
                for c in self.chroots_list:
                    if getattr(self, c).data:
                        have_any = True
                return have_any

        F.chroots_list = list(
            map(
                lambda x: x.name,
                models.MockChroot.query.filter(
                    models.MockChroot.is_active == True).all()))
        F.chroots_list.sort()
        # sets of chroots according to how we should print them in columns
        F.chroots_sets = {}
        for ch in F.chroots_list:
            checkbox_default = False
            if mock_chroots and ch in map(lambda x: x.name, mock_chroots):
                checkbox_default = True

            setattr(F, ch, wtforms.BooleanField(ch, default=checkbox_default))
            if ch[0] in F.chroots_sets:
                F.chroots_sets[ch[0]].append(ch)
            else:
                F.chroots_sets[ch[0]] = [ch]

        return F
class FakeForm(wtforms.Form):
    ''' Form to configure the mail hook. '''
    field1 = wtforms.TextField('Title', [pagure.hooks.RequiredIf('active')])
    field2 = wtforms.BooleanField('Title2', [wtforms.validators.Optional()])
Beispiel #18
0
        class F(wtf.Form):
            # also use id here, to be able to find out whether user
            # is updating a copr if so, we don't want to shout
            # that name already exists
            id = wtforms.HiddenField()
            group_id = wtforms.HiddenField()

            name = wtforms.StringField(
                "Name",
                validators=[
                    wtforms.validators.DataRequired(),
                    wtforms.validators.Regexp(
                        re.compile(r"^[\w.-]+$"),
                        message="Name must contain only letters,"
                        "digits, underscores, dashes and dots."),
                    CoprUniqueNameValidator(user=user, group=group),
                    NameNotNumberValidator()
                ])

            homepage = wtforms.StringField("Homepage",
                                           validators=[
                                               wtforms.validators.Optional(),
                                               wtforms.validators.URL()
                                           ])

            contact = wtforms.StringField(
                "Contact",
                validators=[wtforms.validators.Optional(),
                            EmailOrURL()])

            description = wtforms.TextAreaField("Description")

            instructions = wtforms.TextAreaField("Instructions")

            repos = wtforms.TextAreaField("External Repositories",
                                          validators=[UrlRepoListValidator()],
                                          filters=[StringListFilter()])

            initial_pkgs = wtforms.TextAreaField(
                "Initial packages to build",
                validators=[UrlListValidator(),
                            UrlSrpmListValidator()],
                filters=[StringListFilter()])

            disable_createrepo = wtforms.BooleanField(default=False)
            build_enable_net = wtforms.BooleanField(default=False)

            @property
            def selected_chroots(self):
                selected = []
                for ch in self.chroots_list:
                    if getattr(self, ch).data:
                        selected.append(ch)
                return selected

            def validate(self):
                if not super(F, self).validate():
                    return False

                if not self.validate_mock_chroots_not_empty():
                    self._mock_chroots_error = "At least one chroot" \
                        " must be selected"
                    return False
                return True

            def validate_mock_chroots_not_empty(self):
                have_any = False
                for c in self.chroots_list:
                    if getattr(self, c).data:
                        have_any = True
                return have_any
Beispiel #19
0
class SearchBookmarksForm(FlaskForm):
    keywords = wtforms.FieldList(wtforms.StringField('Keywords'), min_entries=1)
    all_keywords = wtforms.BooleanField('Match all keywords')
    deep = wtforms.BooleanField('Deep search')
    regex = wtforms.BooleanField('Regex')
Beispiel #20
0
class BasePackageForm(wtf.Form):
    package_name = wtforms.StringField(
        "Package name", validators=[wtforms.validators.DataRequired()])
    webhook_rebuild = wtforms.BooleanField(default=False)
Beispiel #21
0
class LoginForm(FlaskForm):
    brugernavn = wtforms.StringField('Brugernavn', validators=[DataRequired()])
    adgangskode = wtforms.PasswordField('Adgangskode',
                                        validators=[DataRequired()])
    husk_mig = wtforms.BooleanField('Husk')
    submit = wtforms.SubmitField('Log ind')
Beispiel #22
0
class AdminPlaygroundForm(wtf.Form):
    playground = wtforms.BooleanField("Playground")
Beispiel #23
0
class ProjectForm(ProjectFormSimplified):
    """ Form to create or edit project. """

    name = wtforms.StringField('Project name <span class="error">*</span>')
    mirrored_from = wtforms.StringField(
        "Mirror from URL",
        [
            wtforms.validators.optional(),
            wtforms.validators.Regexp(urlpattern, flags=re.IGNORECASE),
        ],
    )
    create_readme = wtforms.BooleanField(
        "Create README",
        [wtforms.validators.optional()],
        false_values=FALSE_VALUES,
    )
    namespace = wtforms.SelectField(
        "Project Namespace",
        [user_namespace_if_private,
         wtforms.validators.optional()],
        choices=[],
        coerce=convert_value,
    )
    ignore_existing_repos = wtforms.BooleanField(
        "Ignore existing repositories",
        [wtforms.validators.optional()],
        false_values=FALSE_VALUES,
    )
    repospanner_region = wtforms.SelectField(
        "repoSpanner Region",
        [wtforms.validators.optional()],
        choices=([("none", "Disabled")] +
                 [(region, region)
                  for region in pagure_config["REPOSPANNER_REGIONS"].keys()]),
        coerce=convert_value,
        default=pagure_config["REPOSPANNER_NEW_REPO"],
    )

    def __init__(self, *args, **kwargs):
        """ Calls the default constructor with the normal argument but
        uses the list of collection provided to fill the choices of the
        drop-down list.
        """
        super(ProjectForm, self).__init__(*args, **kwargs)
        # set the name validator
        regex = pagure_config.get("PROJECT_NAME_REGEX",
                                  "^[a-zA-z0-9_][a-zA-Z0-9-_.+]*$")
        self.name.validators = [
            wtforms.validators.DataRequired(),
            wtforms.validators.Regexp(regex, flags=re.IGNORECASE),
        ]
        # Set the list of namespace
        if "namespaces" in kwargs:
            self.namespace.choices = [(namespace, namespace)
                                      for namespace in kwargs["namespaces"]]
            if not pagure_config.get("USER_NAMESPACE", False):
                self.namespace.choices.insert(0, ("", ""))

        if not (is_admin() and
                pagure_config.get("ALLOW_ADMIN_IGNORE_EXISTING_REPOS")) and (
                    flask.g.fas_user.username
                    not in pagure_config["USERS_IGNORE_EXISTING_REPOS"]):
            self.ignore_existing_repos = None

        if not (is_admin()
                and pagure_config.get("REPOSPANNER_NEW_REPO_ADMIN_OVERRIDE")):
            self.repospanner_region = None
Beispiel #24
0
class PagureForceCommitForm(FlaskForm):
    """ Form to configure the pagure hook. """

    branches = wtforms.StringField("Branches", [RequiredIf("active")])

    active = wtforms.BooleanField("Active", [wtforms.validators.Optional()])
Beispiel #25
0
class MergePRForm(PagureForm):
    delete_branch = wtforms.BooleanField(
        "Delete branch after merging",
        [wtforms.validators.optional()],
        false_values=FALSE_VALUES,
    )
Beispiel #26
0
class EditHostCategoryForm(wtf.Form):
    """ Form to edit a host_category. """
    always_up2date = wtforms.BooleanField(
        'Always up to date',
        default=False
    )
Beispiel #27
0
class CreateELBForm(ELBHealthChecksForm, ELBAccessLogsFormMixin):
    """Create Elastic Load Balancer form"""
    ELB_NAME_PATTERN = '^[a-zA-Z0-9-]{1,32}$'
    name_error_msg = _(
        'Name is required, and may only contain alphanumeric characters and/or hyphens. '
        'Length may not exceed 32 characters.')
    name = wtforms.TextField(
        label=_(u'Name'),
        validators=[validators.InputRequired(message=name_error_msg)],
    )
    vpc_network_error_msg = _(u'VPC network is required')
    vpc_network = wtforms.SelectField(
        label=_(u'VPC network'),
        validators=[validators.InputRequired(message=vpc_network_error_msg)],
    )
    vpc_subnet = wtforms.SelectMultipleField(label=_(u'VPC subnets'), )
    securitygroup = wtforms.SelectMultipleField(label=_(u'Security groups'))
    securitygroup_help_text = _(
        u'If you do not select a security group, the default group will be used.'
    )
    zone = wtforms.SelectMultipleField(label=_(u'Availability zones'))
    cross_zone_enabled_help_text = _(
        u'Distribute traffic evenly across all instances in all availability zones'
    )
    cross_zone_enabled = wtforms.BooleanField(
        label=_(u'Enable cross-zone load balancing'))
    add_availability_zones_help_text = _(
        u'Enable this load balancer to route traffic to instances in the selected zones'
    )
    add_vpc_subnets_help_text = _(
        u'Enable this load balancer to route traffic to instances in the selected subnets'
    )
    add_instances_help_text = _(
        u'Balance traffic between the selected instances')

    def __init__(self, request, conn=None, vpc_conn=None, **kwargs):
        super(CreateELBForm, self).__init__(request, **kwargs)
        self.conn = conn
        self.vpc_conn = vpc_conn
        self.cloud_type = request.session.get('cloud_type', 'euca')
        self.is_vpc_supported = BaseView.is_vpc_supported(request)
        self.set_error_messages()
        self.choices_manager = ChoicesManager(conn=conn)
        self.vpc_choices_manager = ChoicesManager(conn=vpc_conn)
        self.set_choices(request)
        self.securitygroup.help_text = self.securitygroup_help_text
        self.cross_zone_enabled.help_text = self.cross_zone_enabled_help_text
        self.bucket_name.help_text = self.bucket_name_help_text
        self.bucket_prefix.help_text = self.bucket_prefix_help_text

    def set_choices(self, request):
        if self.cloud_type == 'euca' and self.is_vpc_supported:
            self.vpc_network.choices = self.vpc_choices_manager.vpc_networks(
                add_blank=False)
        else:
            self.vpc_network.choices = self.vpc_choices_manager.vpc_networks()
        self.vpc_subnet.choices = self.vpc_choices_manager.vpc_subnets()
        self.securitygroup.choices = self.choices_manager.security_groups(
            securitygroups=None, use_id=True, add_blank=False)
        self.zone.choices = self.get_availability_zone_choices()
        self.ping_protocol.choices = self.get_ping_protocol_choices()
        self.time_between_pings.choices = self.get_time_between_pings_choices()
        self.failures_until_unhealthy.choices = self.get_failures_until_unhealthy_choices(
        )
        self.passes_until_healthy.choices = self.get_passes_until_healthy_choices(
        )
        self.bucket_name.choices = self.s3_choices_manager.buckets()
        self.collection_interval.choices = self.get_collection_interval_choices(
        )
        self.cross_zone_enabled.data = True
        # Set default choices where applicable, defaulting to first non-blank choice
        if self.cloud_type == 'aws' and len(self.zone.choices) > 1:
            self.zone.data = self.zone.choices[0]
        # Set the defailt option to be the first choice
        if len(self.vpc_network.choices) > 1:
            self.vpc_network.data = self.vpc_network.choices[0][0]

    def set_error_messages(self):
        self.name.error_msg = self.name_error_msg
        self.bucket_name.error_msg = self.bucket_name_error_msg
        self.bucket_prefix.error_msg = self.bucket_prefix_error_msg

    def get_availability_zone_choices(self):
        return self.choices_manager.availability_zones(self.region,
                                                       add_blank=False)
Beispiel #28
0
class LoginForm(FlaskForm):
    email = wtforms.StringField('Email', validators=[DataRequired(), Length(1, 64), Email()])
    password = wtforms.PasswordField('Password', validators=[DataRequired()])
    remember_me = wtforms.BooleanField('记住我?')
    submit = wtforms.SubmitField('登录')
Beispiel #29
0
class AddMeetingForm(i18nforms.Form):
    """ Form used to create a new meeting. """
    calendar_name = wtforms.SelectField(_('Calendar'),
                                        [wtforms.validators.Required()],
                                        choices=[])

    meeting_name = wtforms.TextField(_('Meeting name'),
                                     [wtforms.validators.Required()])

    meeting_date = wtforms.DateField(_('Date'),
                                     [wtforms.validators.Required()])

    meeting_date_end = wtforms.DateField(_('End date'),
                                         [wtforms.validators.optional()])

    meeting_time_start = wtforms.TextField(
        _('Start time'), [wtforms.validators.Required(), validate_time])

    meeting_time_stop = wtforms.TextField(
        _('Stop time'), [wtforms.validators.Required(), validate_time])

    meeting_timezone = wtforms.SelectField(_('Time zone'),
                                           [wtforms.validators.Required()],
                                           choices=[
                                               (tzone, tzone)
                                               for tzone in common_timezones
                                           ])

    wiki_link = wtforms.TextField(_('More information URL'))

    comanager = wtforms.TextField(_('Co-manager'))

    information = wtforms.TextAreaField(_('Information'))

    meeting_location = wtforms.TextField(
        _('Location'),
        [wtforms.validators.optional(), validate_meeting_location])

    # Recursion
    frequency = wtforms.SelectField(_('Repeat every'),
                                    [wtforms.validators.optional()],
                                    choices=[
                                        ('', ''),
                                        ('7', _('%(days)s days', days='7')),
                                        ('14', _('%(days)s days', days='14')),
                                        ('21', _('%(weeks)s weeks',
                                                 weeks='3')),
                                        ('28', _('%(weeks)s weeks',
                                                 weeks='4')),
                                    ])
    end_repeats = wtforms.DateField(_('End date'),
                                    [wtforms.validators.optional()])

    # Reminder
    remind_when = wtforms.SelectField(
        _('Send reminder'), [wtforms.validators.optional()],
        choices=[
            ('', ''),
            ('H-12', _('%(hours)s hours before', hours='12')),
            ('H-24', _('%(days)s day before', days='1')),
            ('H-48', _('%(days)s days before', days='2')),
            ('H-168', _('%(days)s days before', days='7')),
        ])
    remind_who = wtforms.TextField(
        _('Send reminder to'),
        [validate_multi_email,
         wtforms.validators.optional()])
    reminder_from = wtforms.TextField(
        _('Send reminder from'),
        [wtforms.validators.Email(),
         wtforms.validators.optional()])

    # Full day
    full_day = wtforms.BooleanField(_('Full day meeting'))

    def __init__(self, *args, **kwargs):
        """ Calls the default constructor with the normal argument but
        if a meeting is set using the meeting keyword, then fill the
        value of the form with the value from the Meeting object.
        """
        super(AddMeetingForm, self).__init__(*args, **kwargs)
        if 'timezone' in kwargs:
            self.meeting_timezone.data = kwargs['timezone']

        if 'calendars' in kwargs:
            calendars = kwargs['calendars']
            self.calendar_name.choices = [(calendar.calendar_name,
                                           calendar.calendar_name)
                                          for calendar in calendars]

        if 'meeting' in kwargs:
            meeting = kwargs['meeting']

            self.calendar_name.data = meeting.calendar_name
            self.meeting_name.data = meeting.meeting_name
            self.meeting_date.data = meeting.meeting_date
            self.meeting_date_end.data = meeting.meeting_date_end
            self.meeting_time_start.data = meeting.meeting_time_start.strftime(
                '%H:%M')
            self.meeting_time_stop.data = meeting.meeting_time_stop.strftime(
                '%H:%M')
            self.meeting_timezone.data = meeting.meeting_timezone
            self.information.data = meeting.meeting_information
            meeting_manager = ','.join(meeting.meeting_manager)
            self.comanager.data = meeting_manager
            self.meeting_location.data = meeting.meeting_location
            self.frequency.data = str(meeting.recursion_frequency)
            self.end_repeats.data = meeting.recursion_ends
            self.full_day.data = meeting.full_day
            if meeting.reminder_id:  # pragma: no cover
                self.remind_when.data = meeting.reminder.reminder_offset
                self.reminder_from.data = meeting.reminder.reminder_from
                self.remind_who.data = meeting.reminder.reminder_to
Beispiel #30
0
class ImageClassificationDatasetForm(ImageDatasetForm):
    """
    Defines the form used to create a new ImageClassificationDatasetJob
    """

    ### Upload method

    def required_if_method(value):

        def _required(form, field):
            if form.method.data == value:
                if field.data is None or (isinstance(field.data, str) and not field.data.strip()) or (isinstance(field.data, FileStorage) and not field.data.filename.strip()):
                    raise validators.ValidationError('This field is required.')
            else:
                field.errors[:] = []
                raise validators.StopValidation()

        return _required

    method = wtforms.HiddenField(u'Dataset type',
            default='folder',
            validators=[
                validators.AnyOf(['folder', 'textfile'], message='The method you chose is not currently supported.')
                ]
            )

    def validate_folder_path(form, field):
        if utils.is_url(field.data):
            # make sure the URL exists
            try:
                r = requests.get(field.data,
                        allow_redirects=False,
                        timeout=utils.HTTP_TIMEOUT)
                if r.status_code not in [requests.codes.ok, requests.codes.moved, requests.codes.found]:
                    raise validators.ValidationError('URL not found')
            except Exception as e:
                raise validators.ValidationError('Caught %s while checking URL: %s' % (type(e).__name__, e))
            else:
                return True
        else:
            # make sure the filesystem path exists
            if not os.path.exists(field.data) or not os.path.isdir(field.data):
                raise validators.ValidationError('Folder does not exist')
            else:
                return True

    ### Method - folder

    folder_train = wtforms.StringField(u'Training Images',
            validators=[
                required_if_method('folder'),
                validate_folder_path,
                ]
            )

    folder_pct_val = wtforms.IntegerField(u'% for validation',
            default=25,
            validators=[
                required_if_method('folder'),
                validators.NumberRange(min=0, max=100)
                ]
            )

    folder_pct_test = wtforms.IntegerField(u'% for testing',
            default=0,
            validators=[
                required_if_method('folder'),
                validators.NumberRange(min=0, max=100)
                ]
            )

    has_val_folder = wtforms.BooleanField('Separate validation images folder',
            default = False,
            validators=[
                required_if_method('folder')
                ]
            )

    folder_val = wtforms.StringField(u'Validation Images',
            validators=[
                required_if_method('folder'),
                validate_folder_path,
                ]
            )

    def validate_folder_val(form, field):
        if not form.has_val_folder.data:
            field.errors[:] = []
            raise validators.StopValidation()

    has_test_folder = wtforms.BooleanField('Separate test images folder',
            default = False,
            validators=[
                required_if_method('folder')
                ]
            )

    folder_test = wtforms.StringField(u'Test Images',
            validators=[
                required_if_method('folder'),
                validate_folder_path,
                ]
            )

    def validate_folder_test(form, field):
        if not form.has_test_folder.data:
            field.errors[:] = []
            raise validators.StopValidation()

    ### Method - textfile

    textfile_train_images = wtforms.FileField(u'Training images',
            validators=[
                required_if_method('textfile')
                ]
            )
    textfile_train_folder = wtforms.StringField(u'Training images folder')

    def validate_textfile_train_folder(form, field):
        if form.method.data != 'textfile':
            field.errors[:] = []
            raise validators.StopValidation()
        if not field.data.strip():
            # allow null
            return True
        if not os.path.exists(field.data) or not os.path.isdir(field.data):
            raise validators.ValidationError('folder does not exist')
        return True


    # TODO: fix these validators

    textfile_use_val = wtforms.BooleanField(u'Validation set',
            default=True,
            validators=[
                required_if_method('textfile')
                ]
            )
    textfile_val_images = wtforms.FileField(u'Validation images',
            validators=[
                required_if_method('textfile')
                ]
            )
    textfile_val_folder = wtforms.StringField(u'Validation images folder')

    def validate_textfile_val_folder(form, field):
        if form.method.data != 'textfile' or not form.textfile_use_val.data:
            field.errors[:] = []
            raise validators.StopValidation()
        if not field.data.strip():
            # allow null
            return True
        if not os.path.exists(field.data) or not os.path.isdir(field.data):
            raise validators.ValidationError('folder does not exist')
        return True

    textfile_use_test = wtforms.BooleanField(u'Test set',
            default=False,
            validators=[
                required_if_method('textfile')
                ]
            )
    textfile_test_images = wtforms.FileField(u'Test images',
            validators=[
                required_if_method('textfile')
                ]
            )
    textfile_test_folder = wtforms.StringField(u'Test images folder')

    def validate_textfile_test_folder(form, field):
        if form.method.data != 'textfile' or not form.textfile_use_test.data:
            field.errors[:] = []
            raise validators.StopValidation()
        if not field.data.strip():
            # allow null
            return True
        if not os.path.exists(field.data) or not os.path.isdir(field.data):
            raise validators.ValidationError('folder does not exist')
        return True

    textfile_shuffle = wtforms.BooleanField('Shuffle lines',
            default = True)

    textfile_labels_file = wtforms.FileField(u'Labels',
            validators=[
                required_if_method('textfile')
                ]
            )