Source code for flaskbb.utils.forms

# -*- 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)


[docs]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