class PasswordResetForm(form.Form): messages = { 'password_match': _("The entered passwords do not match."), 'invalid_token': _('Password reset token does not match any user'), } # Translators, used as label in create user form reset_token = form.StringField(_("Password reset token"), validators=[RequiredIfNotAuthenticated()], placeholder='123456') # Translators, used as label in password reset form password1 = form.PasswordField(_("Password"), validators=[form.Required()], placeholder=_('password')) # Translators, used as label in password reset form password2 = form.PasswordField(_("Confirm Password"), validators=[form.Required()], placeholder=_('confirm password')) def validate(self): password1 = self.processed_data['password1'] password2 = self.processed_data['password2'] if password1 != password2: raise form.ValidationError('password_match', {}) user = (request.user if request.user.is_authenticated else User.from_reset_token(self.processed_data['reset_token'])) if not user: raise form.ValidationError('invalid_token', {'value': ''}) self.processed_data['username'] = user.username
def get_form(self): attrs = dict() for (group_name, group) in self._groups.items(): for (field_name, options) in group.items(): name = self._field_template.format(group=group_name, name=field_name) field_cls = self._field_types[options['value_type']] validators = ([], [form.Required()])[options['required']] # actual value from config overrides default value value = exts.config.get(name, options['default']) kwargs = dict(label=options['label'], help_text=options['help_text'], validators=validators) if options['value_type'] == self._select_type: kwargs['choices'] = options['choices'] if options['value_type'] is bool: kwargs['default'] = value kwargs['value'] = name else: kwargs['value'] = value attrs[name] = field_cls(**kwargs) return type('SettingsForm', (form.Form, ), attrs)
class SetupDateTimeForm(form.Form): TIMEZONES = [(tzname, tzname) for tzname in pytz.common_timezones] DEFAULT_TIMEZONE = pytz.common_timezones[0] # Translators, used as label for date and time setup timezone = form.SelectField(_("Timezone"), value=DEFAULT_TIMEZONE, validators=[form.Required()], choices=TIMEZONES)
class FirmwareUpdateForm(form.Form): firmware = form.FileField( _("Firmware"), validators=[ form.Required( messages={ # Translators, shown as a prompt to user in dashboard 'required': _('Please select the firmware') }) ])
class LoginForm(form.Form): messages = { 'login_error': _("Please enter the correct username and password.") } # Translators, used as label for a login field username = form.StringField(_("Username"), placeholder=_('username'), validators=[form.Required()]) # Translators, used as label for a password field password = form.PasswordField(_("Password"), placeholder=_('password'), validators=[form.Required()]) def validate(self): username = self.processed_data['username'] password = self.processed_data['password'] if not User.login(username, password): raise form.ValidationError('login_error', {})
class SDRForm(form.Form): sdr_binary = form.FileField( _("SDR Executable"), validators=[ form.Required( messages={ # Translators, shown as a prompt to user during setup wizard # step. 'required': _('Please select the SDR executable') }) ])
class RegistrationForm(form.Form): messages = {'registration_error': _("The entered passwords do not match.")} # Translators, used as label in create user form username = form.StringField(_("Username"), validators=[form.Required()], placeholder=_('username')) # Translators, used as label in create user form password1 = form.PasswordField(_("Password"), validators=[form.Required()], placeholder=_('password')) # Translators, used as label in create user form password2 = form.PasswordField(_("Confirm Password"), validators=[form.Required()], placeholder=_('confirm password')) def validate(self): password1 = self.processed_data['password1'] password2 = self.processed_data['password2'] if password1 != password2: raise form.ValidationError('registration_error', {})
class DeleteForm(form.Form): messages = { # Translators, used as message when a file's removal is # retried, but it was already deleted before 'already_deleted': _("The specified file has already been removed.") } path = form.HiddenField(_("Path"), validators=[form.Required()]) def postprocess_path(self, value): if not exts.fsal.exists(value): raise form.ValidationError('already_deleted', {}) return value
class EmergencyResetForm(RegistrationForm): messages = { 'registration_error': _("The entered passwords do not match."), # Translators, used as error message for emergency reset token form # field 'bad_token': _('Invalid emergency reset token'), } # Translators, used as label for emergency reset token field emergency_reset = form.StringField( _('Emergency reset token'), validators=[form.Required(), TokenValidator()], placeholder='12345678')
class ConsolidateForm(form.Form): messages = { # There is already a task running, so we can't schedule another one # Translators, error message shown when moving of files is # attempted while another move task is already running. 'already_running': _('A scheduled move is already running. You will ' 'be notified when it finishes. Please try again ' 'once the current operation is finished.'), # Translators, error message shown when destination drive is removed # or otherwise becomes inaccessible before files are moved to it. 'storage_not_found': _('Destination drive disappeared. Please ' 'reattach the drive and retry.'), # Translators, error message shown when moving files to a storage # device where no other storage devices are present other than the # target device. 'no_move_target': _('There are no other drives to move files from.'), # Translators, error message shown when moving files to a storage # device, where no movable files are present. 'nothing_to_move': _('There are no files to be moved.'), # Translators, error message shown when moving files to a storage # device, that has not enough free space. 'not_enough_space': _('Not enough free space. {size} needed.'), } storage_id = form.StringField(validators=[form.Required()]) def validate(self): active_storage_id = storage.get_consolidate_status() if active_storage_id: raise form.ValidationError('already_running', {}) # Perform preflight check storages = storage.get_content_storages() storage_id = self.processed_data['storage_id'] try: dest = storages.move_preflight(storage_id) except storage.NotFoundError: raise form.ValidationError('storage_not_found', {}) except storage.NoMoveTargetError: raise form.ValidationError('no_move_target', {}) except storage.NothingToMoveError: raise form.ValidationError('nothing_to_move', {}) except storage.CapacityError as err: params = dict(size=hsize(err.capacity)) raise form.ValidationError('not_enough_space', params) else: self.processed_data['storages'] = storages self.processed_data['dest'] = dest
class SetupImportContentForm(form.Form): IMPORT = 'import' IGNORE = 'ignore' ACTIONS = ( # Translators, used for setup wizard action of importing legacy content (IMPORT, _("Import")), # Translators, used for setup wizard action of discarding legacy # content (IGNORE, _("Discard")), ) chosen_action = form.SelectField(_("Action"), value=IMPORT, validators=[form.Required()], choices=ACTIONS)
class PasswordResetForm(form.Form): messages = { 'password_match': _("The entered passwords do not match."), 'invalid_token': _('Password reset token does not match any user'), } # Translators, used as label in create user form reset_token = form.StringField(_("Password reset token"), validators=[form.Required()], placeholder='123456') # Translators, used as label in password reset form password1 = form.PasswordField(_("Password"), validators=[form.Required()], placeholder=_('password')) # Translators, used as label in password reset form password2 = form.PasswordField(_("Confirm Password"), validators=[form.Required()], placeholder=_('confirm password')) def validate(self): password1 = self.processed_data['password1'] password2 = self.processed_data['password2'] if password1 != password2: raise form.ValidationError('password_match', {})
class WifiSTAForm(WifiForm): #: Used to differentiate between the AP / STA forms in templates MODE = consts.STA_MODE #: Protocol aliases NO_SECURITY = consts.NO_SECURITY WPA_PROTOCOL = consts.WPA WEP_PROTOCOL = consts.WEP #: List of supported security protocols VALID_SECURITY_PROTOCOLS = dict(consts.SECURITY_PROTOCOLS).keys() #: Use this security protocol if no valid one was chosen DEFAULT_SECURITY = WPA_PROTOCOL #: Validation error messages messages = { 'save_error': _('Wireless settings could not be applied'), } ssid = form.StringField(validators=[form.Required()]) security = form.SelectField(choices=consts.SECURITY_PROTOCOLS) def validate(self): """ Perform form-level validation and set the configuration options. """ params = dict(('wireless.{}'.format(key), value) for (key, value) in self.processed_data.items()) try: sta.setup(params) except Exception: logging.exception("Wireless STA settings saving failed.") sta.teardown() raise self.ValidationError('save_error') else: # on successful setup, store persistent config exts.setup.append(params) @classmethod def for_security_protocol(cls, security): if security not in cls.VALID_SECURITY_PROTOCOLS: security = exts.config.get('wireless.security', cls.DEFAULT_SECURITY) cls._subclasses = cls._subclasses or cls.subclasses() (form_cls,) = [sc for sc in cls._subclasses if getattr(sc, 'SECURITY', None) == security] return form_cls
class ONDDForm(form.Form): PRESETS = consts.PRESETS messages = { 'tuning_error': _("Tuner configuration could not be saved. " "Please make sure that the tuner is connected.") } # TODO: Add support for DiSEqC azimuth value lnb = form.SelectField( _("LNB Type"), # Translators, error message when LNB type is incorrect validators=[ form.Required( messages={'required': _('Invalid choice for LNB type')}) ], choices=consts.LNB_TYPES) frequency = form.IntegerField( _("Frequency"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when frequency value is wrong messages={'min_val': _('Frequency must be a positive number')}) ]) symbolrate = form.IntegerField( _("Symbol rate"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when symbolrate value is wrong messages={ 'min_val': _('Symbolrate must be a positive number') }) ]) delivery = form.SelectField( _("Delivery system"), choices=consts.DELIVERY, # Translators, error message when wrong delivery system is selected validators=[ form.Required( messages={'required': _('Invalid choice for delivery system')}) ]) modulation = form.SelectField( _("Modulation"), choices=consts.MODULATION, # Translators, error message when wrong modulation mode is selected validators=[ form.Required( messages={'required': _('Invalid choice for modulation mode')}) ]) polarization = form.SelectField( _("Polarization"), choices=consts.POLARIZATION, # Translators, error message when wrong polarization is selected validators=[ form.Required( messages={'required': _('Invalid choice for polarization')}) ]) def validate(self): if not has_tuner(): # Translators, error message shown when a tuner is not detected raise form.ValidationError('tuning_error', {}) lnb = self.processed_data['lnb'] frequency = self.processed_data['frequency'] symbolrate = self.processed_data['symbolrate'] delivery = self.processed_data['delivery'] modulation = self.processed_data['modulation'] polarization = self.processed_data['polarization'] settings = dict(frequency=freq_conv(frequency, lnb), symbolrate=symbolrate, delivery=delivery, tone=needs_tone(frequency, lnb), modulation=dict(consts.MODULATION)[modulation], voltage=consts.VOLTS[polarization]) ondd_client = request.app.supervisor.exts.ondd response = ondd_client.set_settings(**settings) if not response.startswith('2'): # Translators, error message shown when setting transponder # configuration is not successful raise form.ValidationError('tuning_error', {})
class LForm(ONDDFormBase): PRESETS = ondd.L_PRESETS preset = form.IntegerField( _("Satellite"), validators=[ form.Required(messages={ # Translators, message shown when user does not select a # satellite preset nor 'Custom' option to enter custom data. 'required': _("Please select a satellite or select 'Custom'") }), form.InRangeValidator(min_value=-1, max_value=len(PRESETS)) ] ) frequency = form.FloatField( _("Frequency"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when frequency value is wrong messages={'min_val': _('Frequency must be a positive number')} ) ] ) uncertainty = form.IntegerField( _("Frequency uncertainty"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when uncertainty value is wrong messages={'min_val': _('Frequency uncertainty must be a ' 'positive number')} ) ] ) symbolrate = form.IntegerField( _("Symbol rate"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when symbolrate value is wrong messages={'min_val': _('Symbolrate must be a positive number')} ) ] ) sample_rate = form.FloatField( _("Sample rate"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when sample rate is wrong messages={ 'min_val': _('Sample rate must be a positive number') } ) ] ) rf_filter = form.SelectField( _("RF filter"), # Translators, error message when LNB type is incorrect choices=ondd.RF_FILTERS ) descrambler = form.BooleanField( _("Descrambler"), value='descrambler', default=False, ) def preprocess_frequency(self, value): return self.preset_data.get('frequency', value) def preprocess_uncertainty(self, value): return self.preset_data.get('uncertainty', value) def preprocess_symbolrate(self, value): return self.preset_data.get('symbolrate', value) def preprocess_sample_rate(self, value): return self.preset_data.get('sample_rate', value) def preprocess_rf_filter(self, value): return int(self.preset_data.get('rf_filter', value)) def preprocess_descrambler(self, value): return self.preset_data.get('descrambler', value) def validate(self): ondd.write_ondd_setup(self.processed_data) try: ondd.restart_demod() except ondd.DemodRestartError: raise form.ValidationError('tuning_error', {})
class KuForm(ONDDFormBase): PRESETS = ondd.KU_PRESETS preset = form.IntegerField( _("Satellite"), validators=[ form.Required(messages={ # Translators, message shown when user does not select a # satellite preset nor 'Custom' option to enter custom data. 'required': _("Please select a satellite or select 'Custom'") }), form.InRangeValidator(min_value=-1, max_value=len(PRESETS)) ] ) # TODO: Add support for DiSEqC azimuth value lnb = form.SelectField( _("LNB Type"), # Translators, error message when LNB type is incorrect validators=[form.Required(messages={ 'required': _('Invalid choice for LNB type') })], choices=ondd.LNB_TYPES ) frequency = form.IntegerField( _("Frequency"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when frequency value is wrong messages={'min_val': _('Frequency must be a positive number')} ) ] ) symbolrate = form.IntegerField( _("Symbol rate"), validators=[ form.Required(), form.InRangeValidator( min_value=0, # Translators, error message when symbolrate value is wrong messages={'min_val': _('Symbolrate must be a positive number')} ) ] ) delivery = form.SelectField( _("Delivery system"), choices=ondd.DELIVERY, # Translators, error message when wrong delivery system is selected validators=[ form.Required(messages={ 'required': _('Invalid choice for delivery system') }) ] ) modulation = form.SelectField( _("Modulation"), choices=ondd.MODULATION, # Translators, error message when wrong modulation mode is selected validators=[ form.Required(messages={ 'required': _('Invalid choice for modulation mode') }) ] ) polarization = form.SelectField( _("Polarization"), choices=ondd.POLARIZATION, # Translators, error message when wrong polarization is selected validators=[ form.Required(messages={ 'required': _('Invalid choice for polarization') }) ] ) def preprocess_frequency(self, value): return self.preset_data.get('frequency', value) def preprocess_symbolrate(self, value): return self.preset_data.get('symbolrate', value) def preprocess_delivery(self, value): return self.preset_data.get('delivery', value) def preprocess_modulation(self, value): return self.preset_data.get('modulation', value) def preprocess_polarization(self, value): return self.preset_data.get('polarization', value) def validate(self): if not ondd.has_tuner(): # Translators, error message shown when a tuner is not detected raise form.ValidationError('tuning_error', {}) lnb = self.processed_data['lnb'] frequency = self.processed_data['frequency'] symbolrate = self.processed_data['symbolrate'] delivery = self.processed_data['delivery'] modulation = self.processed_data['modulation'] polarization = self.processed_data['polarization'] settings = dict(frequency=freq_conv(frequency, lnb), symbolrate=symbolrate, delivery=delivery, tone=needs_tone(frequency, lnb), modulation=dict(ondd.MODULATION)[modulation], voltage=ondd.VOLTS[polarization]) ondd_client = request.app.supervisor.exts.ondd response = ondd_client.set_settings(**settings) if not response.startswith('2'): # Translators, error message shown when setting transponder # configuration is not successful raise form.ValidationError('tuning_error', {}) ondd.write_ondd_setup(self.processed_data)
class WifiAPForm(WifiForm): #: Used to differentiate between the AP / STA forms in templates MODE = consts.AP_MODE #: Validation error messages messages = { 'invalid_channel': _('The selected channel is not legal in the ' 'chosen country.'), 'save_error': _('Wireless settings could not be applied'), } def __init__(self, *args, **kwargs): super(WifiAPForm, self).__init__(*args, **kwargs) self.show_driver = request.app.config['wireless.driver_selection'] ssid = form.StringField(validators=[form.Required()]) hide_ssid = form.BooleanField(value='hide_ssid') channel = form.SelectField(choices=consts.CHANNELS) country = form.SelectField(choices=consts.COUNTRIES) security = form.SelectField(choices=consts.WPA_MODES) password = form.StringField( validators=[form.LengthValidator(min_len=8, max_len=63)], messages={ 'min_len': _('Password must be at least {len} characters long.'), 'max_len': _('Password cannot be longer than {len} characters.'), 'no_password': _('Password must be specified when security is ' 'enabled'), }) driver = form.SelectField(choices=consts.DRIVERS) def wpa_mode(self): """ Get config format of wpa mode """ return SECURITY_MAP.get(self.security.processed_value, helpers.WPA2_ONLY) def driver_type(self): """ Get config format of the driver setting """ if self.driver.processed_value == consts.ALTERNATIVE: return helpers.REALTEK else: return helpers.STANDARD def integer_value(self, value): if value is None: return return int(value) postprocess_channel = integer_value postprocess_security = integer_value def preprocess_country(self, value): return value.upper() if value else None def validate(self): """ Perform form-level validation and set the configuration options """ if self.security.processed_value and not self.password.processed_value: self._add_error(self.password, self.ValidationError('no_password')) conf = self.getconf() helpers.set_ssid(conf, self.ssid.processed_value) helpers.set_country(conf, self.country.processed_value) try: helpers.set_channel(conf, self.channel.processed_value) except helpers.ConfigurationError: raise self.ValidationError('invalid_channel') if self.hide_ssid.processed_value: helpers.hide_ssid(conf) else: helpers.reveal_ssid(conf) if self.security.processed_value: helpers.enable_wpa(conf, self.password.processed_value, self.wpa_mode()) else: helpers.disable_wpa(conf) helpers.set_driver(conf, self.driver_type()) try: conf.write(header=consts.HEADER) sta.teardown() except OSError: logging.exception("Wireless AP settings saving failed.") raise self.ValidationError('save_error') else: exts.setup.append({'wireless.mode': self.MODE}) @staticmethod def getconf(): """ Get configuration from file, and fall back on defaults if configuration file is not present on disk """ conf_file_path = request.app.config['wireless.config'] if os.path.exists(conf_file_path): conf = parser.HostapdConf(conf_file_path) else: conf = parser.HostapdConf() conf.path = conf_file_path conf.update(consts.WIRELESS_DEFAULTS) return conf @staticmethod def security_from_conf(conf): """ Get security field value from the configuration """ # Determine the security mode if conf.get('wpa') in [None, str(helpers.WPA_NONE)]: return consts.WPA_NONE elif conf.get('wpa') in [str(helpers.WPA_BOTH), str(helpers.WPA1_ONLY)]: return consts.WPA_COMPATIBLE else: return consts.WPA_SECURE @staticmethod def driver_from_conf(conf): """ Get driver field value from the configuration """ if conf.get('driver') == helpers.REALTEK: return consts.ALTERNATIVE else: return consts.STANDARD @staticmethod def hide_from_conf(conf): """ Get hide_ssid field value from configuration """ return conf.get('ignore_broadcast_ssid') == '1' @classmethod def from_conf_file(cls): """ Initialize the form using configuration file or default config """ data = {} conf = cls.getconf() data['mode'] = cls.MODE data['ssid'] = conf.get('ssid') data['hide_ssid'] = cls.hide_from_conf(conf) data['channel'] = conf.get('channel') data['country'] = conf.get('country_code') data['security'] = cls.security_from_conf(conf) data['password'] = conf.get('wpa_passphrase') data['driver'] = cls.driver_from_conf(conf) return cls(data=data)
class SetupLanguageForm(form.Form): # Translators, used as label for language language = form.SelectField(_('Language'), value=get_default_locale(locales, config), validators=[form.Required()], choices=ui_languages)