123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- # -*- coding: utf-8 -*-
- """
- flaskbb.utils.forms
- ~~~~~~~~~~~~~~~~~~~
- This module contains stuff for forms.
- :copyright: (c) 2017 by the FlaskBB Team.
- :license: BSD, see LICENSE for more details.
- """
- from wtforms import (TextField, IntegerField, FloatField, BooleanField,
- SelectField, SelectMultipleField, validators)
- from flask_wtf import FlaskForm
- from enum import Enum
- class FlaskBBForm(FlaskForm):
- def populate_errors(self, errors):
- for (attribute, reason) in errors:
- self.errors.setdefault(attribute, []).append(reason)
- field = getattr(self, attribute, None)
- if field:
- field.errors.append(reason)
- class SettingValueType(Enum):
- string = 0
- integer = 1
- float = 3
- boolean = 4
- select = 5
- selectmultiple = 6
- def populate_settings_dict(form, settings):
- new_settings = {}
- for key, value in settings.items():
- try:
- # check if the value has changed
- if value == form[key].data:
- continue
- else:
- new_settings[key] = form[key].data
- except KeyError:
- pass
- return new_settings
- def populate_settings_form(form, settings):
- for key, value in settings.items():
- try:
- form[key].data = value
- except (KeyError, ValueError):
- pass
- return form
- # TODO(anr): clean this up
- def generate_settings_form(settings): # noqa: C901
- """Generates a settings form which includes field validation
- based on our Setting Schema."""
- class SettingsForm(FlaskBBForm):
- pass
- # now parse the settings in this group
- for setting in settings:
- field_validators = []
- if setting.value_type in {SettingValueType.integer,
- SettingValueType.float}:
- validator_class = validators.NumberRange
- elif setting.value_type == SettingValueType.string:
- validator_class = validators.Length
- # generate the validators
- if "min" in setting.extra:
- # Min number validator
- field_validators.append(
- validator_class(min=setting.extra["min"])
- )
- if "max" in setting.extra:
- # Max number validator
- field_validators.append(
- validator_class(max=setting.extra["max"])
- )
- # Generate the fields based on value_type
- # IntegerField
- if setting.value_type == SettingValueType.integer:
- setattr(
- SettingsForm, setting.key,
- IntegerField(setting.name, validators=field_validators,
- description=setting.description)
- )
- # FloatField
- elif setting.value_type == SettingValueType.float:
- setattr(
- SettingsForm, setting.key,
- FloatField(setting.name, validators=field_validators,
- description=setting.description)
- )
- # TextField
- elif setting.value_type == SettingValueType.string:
- setattr(
- SettingsForm, setting.key,
- TextField(setting.name, validators=field_validators,
- description=setting.description)
- )
- # SelectMultipleField
- elif setting.value_type == SettingValueType.selectmultiple:
- # if no coerce is found, it will fallback to unicode
- if "coerce" in setting.extra:
- coerce_to = setting.extra['coerce']
- else:
- coerce_to = str
- setattr(
- SettingsForm, setting.key,
- SelectMultipleField(
- setting.name,
- choices=setting.extra['choices'](),
- coerce=coerce_to,
- description=setting.description
- )
- )
- # SelectField
- elif setting.value_type == SettingValueType.select:
- # if no coerce is found, it will fallback to unicode
- if "coerce" in setting.extra:
- coerce_to = setting.extra['coerce']
- else:
- coerce_to = str
- setattr(
- SettingsForm, setting.key,
- SelectField(
- setting.name,
- coerce=coerce_to,
- choices=setting.extra['choices'](),
- description=setting.description)
- )
- # BooleanField
- elif setting.value_type == SettingValueType.boolean:
- setattr(
- SettingsForm, setting.key,
- BooleanField(setting.name, description=setting.description)
- )
- return SettingsForm
|