def languages_save():
    (form, region, region_languages) = validate_region()
    # languages were chosen for the selected region
    selected_languages = map(urlunquote, request.forms.getall('language'))
    has_invalid = any(lang not in region_languages
                      for lang in selected_languages)
    if not selected_languages or has_invalid:
        # some of the chosen languages were invalid or no languages were chosen
        return dict(form=form,
                    region=region,
                    region_languages=region_languages,
                    selected_languages=selected_languages,
                    # Translators, message displayed as help text for
                    # language selection
                    message=_("Please select languages from the list below."))
    # languages are valid, store them in setup file and inform other about it
    exts.setup.append({'contentfilter.region': region,
                       'contentfilter.languages': selected_languages})
    set_fsal_whitelist(request.app.config)
    return dict(form=form,
                region=region,
                region_languages=region_languages,
                selected_languages=selected_languages,
                message=_("Content filter has been set."),
                redirect_url=i18n_url('dashboard:main'))
Пример #2
0
def send_confirmation(email=None, next_path=None):
    if email is None:
        form = ConfirmationForm(request.params)
        if not form.is_valid():
            return template('confirmation', form=form)

        email = form.processed_data['email']

    next_path = next_path or request.params.get('next', '/')
    if request.user.is_authenticated:
        redirect_url = next_path
        redirect_target = _("your previous location")
    else:
        login_path = request.app.get_url('login')
        redirect_url = get_redirect_path(login_path, next_path)
        redirect_target = _('log-in')

    expiration = request.app.config['authentication.confirmation_expires']
    confirmation_key = create_temporary_key(email, expiration)
    task_runner = request.app.config['task.runner']
    task_runner.schedule(send_mail,
                         email,
                         _("Confirm registration"),
                         text='email/confirm',
                         data={'confirmation_key': confirmation_key,
                               'next_path': next_path},
                         config=request.app.config)
    return template('feedback',
                    page_title=_('Account registration complete'),
                    status='email',
                    redirect_url=redirect_url,
                    message=_('Confirmation email has been sent to '
                              '{address}. Check your inbox.').format(
                                  address=email),
                    redirect_target=redirect_target)
Пример #3
0
def update_content_details(id):
    to_put = []
    content = get_content_or_404(id)
    ref_path = i18n_path(request.forms.get('back', content.path))

    if not content.is_editable:
        response.flash(_('Voting is disabled for content that is being '
                         'broadcast'))
        redirect(ref_path)

    vote = request.forms.get('vote')

    if vote not in ['up', 'down']:
        response.flash(_('There was a problem with the request. Please try '
                         'again later.'))
        redirect(ref_path)

    if vote == 'up':
        content.upvotes += 1
        to_put.append(Event.create(Event.UPVOTE, content.key))
    elif vote == 'down':
        content.downvotes += 1
        to_put.append(Event.create(Event.DOWNVOTE, content.key))
    to_put.append(content)
    ndb.put_multi(to_put)
    redirect(ref_path)
Пример #4
0
def update_content_details(id):
    content = get_content_or_404(id)

    if not content.is_editable:
        # Translators, shown when content is not editable (it's on air, etc)
        response.flash(_('This content is not editable'))
        redirect(i18n_path(content.path))

    errors = {}

    title = request.forms.getunicode('title', '').strip()
    license = request.forms.get('license') or None

    if not content.title and not title:
        errors['title'] = _('Title cannot be blank')

    if license and license not in Content.LICENSE_CHOICES:
        errors['license'] = _('Please select a license from provided choices')

    if not errors:
        to_put = []
        if title and content.title != title:
            content.title = title
            to_put.append(Event.create(Event.TITLE, content.key))
        if license and content.license != license:
            content.license = license
            to_put.append(Event.create(Event.LICENSE, content.key))
        if to_put:
            # If we have events in to_put list, we also need to put the content
            to_put.append(content)
        ndb.put_multi(to_put)
        response.flash(_('Content has been updated'))
        redirect(content.path)

    return dict(vals=request.forms, errors=erorrs, content=content)
Пример #5
0
def manage_downloads():
    """ Manage the downloaded content """
    action_handlers = {'add': add,
                       'add_all': add_all,
                       'delete': delete,
                       'delete_all': delete_all}
    action = request.forms.get('action')
    file_list = request.forms.getall('selection')
    try:
        handler = action_handlers[action]
    except KeyError:
        # Translators, used as error title shown to user when wrong action
        # code is submitted to server
        title = _("Invalid action")
        # Translators, used as error message shown to user when wrong action
        # code is submitted to server
        message = _('Invalid action, please use one of the form buttons.')
        status = 'error'
        feedback = dict(page_title=title,
                        message=message,
                        redirect_url=i18n_url('downloads:list'),
                        redirect_target=_("Updates"))
    else:
        status = 'success'
        feedback = handler(file_list)

    return dict(status=status, **feedback)
Пример #6
0
def reset():
    next_path = request.params.get('next', '/')
    form = PasswordResetForm(request.params)
    if request.user.is_authenticated:
        # Set arbitrary non-empty value to prevent form error. We don't really
        # care about this field otherwise.
        form.reset_token.bind_value('not needed')
    if not form.is_valid():
        return dict(next_path=next_path, form=form)
    if request.user.is_authenticated:
        username = request.user.username
    else:
        user = get_user_by_reset_token(form.processed_data['reset_token'])
        if not user:
            form._error = ValidationError('invalid_token', {'value': ''})
            return dict(next_path=next_path, form=form)
        username = user.username
    set_password(username, form.processed_data['password1'])
    if request.user.is_authenticated:
        request.user.logout()
    login_url = i18n_url('auth:login_form') + set_qparam(
        next=next_path).to_qs()
    return template('feedback.tpl',
                    # Translators, used as page title on feedback page
                    page_title=_('New password was set'),
                    # Translators, used as link label on feedback page in "You
                    # will be taken to log-in page..."
                    redirect_target=_('log-in page'),
                    # Translators, shown after password has been changed
                    message=_("Password for username '%(username)s' has been "
                              "set.") % {'username': username},
                    status='success',
                    redirect_url=login_url)
Пример #7
0
def do_enter():
    """Enter numbers into database"""
    numbers = set(parse_numbers(request.forms.get('numbers', '')))
    timestamp = datetime.datetime.now()

    usr_hash = get_fingerprint(request)

    result_num = []

    # TODO make place variable, depending on current request
    q = Place.select().where(Place.place == 'LAGESO')
    lageso = q.get() if q.count() == 1 else None

    if not numbers:
        result_num.append(_('novalidnumbers'))
    else:
        for num in numbers:
            if is_valid_number(num):
                try:
                    n = Number.create(number=num.upper(), time=timestamp, place=lageso, fingerprint=usr_hash)
                    result_num.append(n.number)
                except IntegrityError:
                    try:
                        n = Number.get(Number.number == num.upper())
                        # FIXME Why ain't there any value placeholder in translation string?
                        result_num.append(_(u'erruniquenumber') + ': {}'.format(n.number))
                    except DoesNotExist:
                        result_num.append(u'Something weired happend with {}'.format(num))

    # FIXME result_num is horrible, as it contains success and failures, indistinguishable
    return {'entered': result_num, 'timestamp': timestamp.strftime('%x %X')}
def send_payment_confirmation(item, stripe_obj, email, config):
    interval_types = {
        'month': _("monthly"),
        'year': _("annual")
    }
    item_types = {
        'twitter': _("twitter feed"),
        'content': _("content"),
    }
    is_subscription = stripe_obj.object == 'customer'
    if is_subscription:
        card = stripe_obj.sources.data[-1]
        last4digits = card.last4
        subscription = stripe_obj.subscriptions.data[-1]
        interval = interval_types[subscription.plan.interval]
        timestamp = subscription.start
        amount = subscription.plan.amount
    else:
        last4digits = stripe_obj.source.last4
        interval = None
        timestamp = stripe_obj.created
        amount = stripe_obj.amount

    context_data = {'email': email,
                    'item_type': item_types[item.type],
                    'last4digits': last4digits,
                    'timestamp': datetime.datetime.fromtimestamp(timestamp),
                    'total_amount': humanize_amount(amount, config=config),
                    'interval': interval,
                    'is_subscription': is_subscription}
    send_mail(email,
              _("Payment Confirmation"),
              text='email/payment_confirmation',
              data=context_data,
              config=config)
Пример #9
0
def perform_backup():
    dbpath = get_dbpath()
    bpath = get_backup_path()
    try:
        btime = backup(dbpath, bpath)
        logging.debug('Database backup took %s seconds', btime)
    except AssertionError as err:
        # Translators, error message displayed if database backup fails
        base_msg = _('Database backup could not be completed. '
                     'The following error occurred:')
        message = ' '.join(map(unicode, [base_msg, err.message]))
        status = 'error'
        url = i18n_url('dashboard:main')
        # Translators, redirection target if database backup was successful
        target = _('Dashboard')
    else:
        # Translators, message displayed if database backup was successful
        base_msg = _('Database backup has been completed successfully.')
        took_msg = lazy_ngettext('The operation took %s second',
                                 'The operation took %s seconds',
                                 btime) % round(btime, 2)
        message = ' '.join(map(unicode, [base_msg, took_msg]))
        status = 'success'
        url = get_file_url()
        # Translators, redirection target if database backup was successful
        target = _('the backup folder')

    # Translators, used as page title
    title = _('Database backup')
    return dict(status=status,
                page_title=title,
                message=message,
                redirect_url=url,
                redirect_target=target)
Пример #10
0
def content_sites_list():
    """ Show list of multipage content only """
    result = prepare_content_list(multipage=True)
    result.update({'base_path': i18n_url('content:sites_list'),
                   'page_title': _('Sites'),
                   'empty_message': _('There are no sites in the library.')})
    return result
Пример #11
0
def content_list():
    """ Show list of content """
    result = prepare_content_list()
    result.update({'base_path': i18n_url('content:list'),
                   'page_title': _('Library'),
                   'empty_message': _('Content library is currently empty')})
    return result
Пример #12
0
def reset():
    reset_token = request.params.get('reset_token')
    form = EmergencyResetForm(request.params)
    if not form.is_valid():
        return dict(form=form,
                    reset_token=reset_token)

    db = request.db.sessions
    query = db.Delete('users')
    db.query(query)
    query = db.Delete('sessions')
    db.query(query)
    username = form.processed_data['username']
    create_user(username,
                form.processed_data['password1'],
                is_superuser=True,
                db=request.db.sessions,
                overwrite=True,
                reset_token=reset_token)
    return template('feedback.tpl',
                    # Translators, used as page title on feedback page
                    page_title=_('Emergency reset successful'),
                    # Translators, used as link label on feedback page in "You
                    # will be taken to log-in page..."
                    redirect_target=_('log-in page'),
                    # Translators, shown after emergency reset
                    message=_("You may now log in as "
                              "'%(username)s'.") % {'username': username},
                    status='success',
                    redirect_url=i18n_url('auth:login_form'))
Пример #13
0
def password_reset_request():
    next_path = request.params.get('next', '/')
    form = PasswordResetRequestForm(request.params)
    if not form.is_valid():
        return template('password_reset_request', form=form)

    email = form.processed_data['email']
    if get_user(email):
        expires = request.app.config['authentication.password_reset_expires']
        reset_key = create_temporary_key(email, expires)
        task_runner = request.app.config['task.runner']
        task_runner.schedule(send_mail,
                             email,
                             _("Reset Password"),
                             text='email/password_reset',
                             data={'reset_key': reset_key,
                                   'next_path': next_path},
                             config=request.app.config)
    redirect_url = get_redirect_path(request.app.get_url('login'), next_path)
    return template('feedback',
                    page_title=_('Password reset email sent'),
                    status='email',
                    redirect_url=redirect_url,
                    message=_('An email with a password reset link has been '
                              'sent to {address}. Check your inbox.').format(
                                  address=email),
                    redirect_target=_('log-in'))
Пример #14
0
 def form_valid(self):
     if self.form.processed_data['action'] == self.form.UPLOAD_OPERATION:
         # Translators, message displayed when overlay upload was successful
         return dict(message=_("Overlay successfully uploaded."))
     # Translators, message displayed when overlay operation was successful
     return dict(message=_("Overlay operation successfully completed. "
                           "Please restart the device for the changes "
                           "to take effect."))
Пример #15
0
 def validate(self, value):
     try:
         return dateutil.parser.parse(value)
     except ValueError as exc:
         msg = self.message or _("Invalid date: {0}")
         raise ValidationError(msg.format(exc), {'value': value})
     except TypeError as exc:
         msg = self.message or _("Invalid input.")
         raise ValidationError(msg, {'value': value})
Пример #16
0
def confirm(key):
    next_path = request.params.get('next', '/')
    redir_onfail = get_redirect_path(request.app.get_url('login'), next_path)
    try:
        email = confirm_user(key)
    except KeyExpired:
        return {'message': _("The confirmation key has already expired."),
                'page_title': _("Confirmation"),
                'status': 'error',
                'redirect_url': redir_onfail,
                'redirect_target': _('log-in')}
    except KeyNotFound:
        return {'message': _("The confirmation key is not valid."),
                'page_title': _("Confirmation"),
                'status': 'error',
                'redirect_url': redir_onfail,
                'redirect_target': _('log-in')}
    else:
        login_user_no_auth(email)
        return {'message': _("E-mail address successfully confirmed. You have "
                             "been automatically logged in."),
                'page_title': _("Confirmation"),
                'status': 'success',
                'redirect_url': next_path,
                'redirect_target': _('the main page')}
Пример #17
0
def show_file_list(path='.'):
    search = request.params.get('p')
    resp_format = request.params.get('f', '')
    conf = request.app.config
    is_missing = False
    is_search = False
    files = init_filemanager()
    if search:
        relpath = '.'
        up = ''
        dirs, file_list = files.get_search_results(search)
        is_search = True
        if not len(file_list) and len(dirs) == 1:
            redirect(i18n_url('files:path',
                              path=dirs[0].path.replace('\\', '/')))
        if not dirs and not file_list:
            is_missing = True
            readme = _('The files you were looking for could not be found')
        else:
            readme = _('This list represents the search results')
    else:
        is_search = False
        try:
            dir_contents = files.get_dir_contents(path)
            (path, relpath, dirs, file_list, readme) = dir_contents
        except files.DoesNotExist:
            is_missing = True
            relpath = '.'
            dirs = []
            file_list = []
            readme = _('This folder does not exist')
        except files.IsFileError as err:
            if resp_format == 'json':
                fstat = os.stat(path)
                response.content_type = 'application/json'
                return json.dumps(dict(
                    name=os.path.basename(path),
                    size=fstat[stat.ST_SIZE],
                ))
            options = {'download': request.params.get('filename', False)}
            return static_file(err.path, root=files.filedir, **options)
    up = os.path.normpath(os.path.join(path, '..'))
    up = os.path.relpath(up, conf['content.filedir'])
    if resp_format == 'json':
        response.content_type = 'application/json'
        return json.dumps(dict(
            dirs=dirs,
            files=dictify_file_list(file_list),
            readme=to_unicode(readme),
            is_missing=is_missing,
            is_search=is_search,
        ))
    return dict(path=relpath, dirs=dirs, files=file_list, up=up, readme=readme,
                is_missing=is_missing, is_search=is_search)
Пример #18
0
    def wrapper(**kwargs):
        item_type = kwargs.pop('item_type', None)
        item_id = kwargs.pop('item_id', None)
        if not item_type or not item_id:
            abort(404, _("The specified item was not found."))

        item = get_item(item_type, id=item_id)
        if not item:
            abort(404, _("The specified item was not found."))

        return func(item=item, **kwargs)
Пример #19
0
 def removal_failed(self, path):
     # Translators, used as page title of unsuccessful file removal feedback
     page_title = _("File not removed")
     # Translators, used as message of unsuccessful file removal feedback
     message = _("File could not be removed.")
     body = self.template_func('ui/feedback.tpl',
                               status='error',
                               page_title=page_title,
                               message=message,
                               redirect_url=get_parent_url(path),
                               redirect_target=_("file list"))
     return self.HTTPResponse(body)
Пример #20
0
def show_broadcast_priority_scheduled(item):
    if item.charge_id is None:
        # attempted access to success-page, while not charged
        priority_url = request.app.get_url('broadcast_priority_form',
                                           item_type=item.type,
                                           item_id=item.id)
        redirect(priority_url)

    return dict(item=item,
                status='success',
                page_title=_('Thank You'),
                message=_('Your payment has been completed. You will receive'
                          ' an email with your receipt shortly.'))
Пример #21
0
def remove_content(content):
    """ Delete a single piece of content from archive """
    archive = open_archive()
    archive.remove_from_archive([content.md5])
    request.app.exts.cache.invalidate(prefix='content')
    # Translators, used as page title of successful content removal feedback
    page_title = _("Content removed")
    # Translators, used as message of successful content removal feedback
    message = _("Content successfully removed.")
    return dict(status='success',
                page_title=page_title,
                message=message,
                redirect_url=i18n_url('content:list'),
                redirect_target=_("Library"))
Пример #22
0
 def already_removed(self, path):
     # Translators, used as page title when a file's removal is
     # retried, but it was already deleted before
     page_title = _("File already removed")
     # Translators, used as message when a file's removal is
     # retried, but it was already deleted before
     message = _("The specified file has already been removed.")
     body = self.template_func('ui/feedback.tpl',
                               status='success',
                               page_title=page_title,
                               message=message,
                               redirect_url=get_parent_url(path),
                               redirect_target=_("Files"))
     return self.HTTPResponse(body)
Пример #23
0
 def validate(self, value):
     try:
         if self.min_value is not None and self.min_value > value:
             msg = self.message or _("Input value is too small.")
             msg = msg.format(min=self.min_value, max=self.max_value)
             raise ValidationError(msg, {'value': value})
         if self.max_value is not None and self.max_value < value:
             msg = self.message or _("Input value is too large.")
             msg = msg.format(min=self.min_value, max=self.max_value)
             raise ValidationError(msg, {'value': value})
     except Exception:
         msg = self.message or _("Invalid input.")
         msg = msg.format(min=self.min_value, max=self.max_value)
         raise ValidationError(msg, {'value': value})
Пример #24
0
def delete(file_list):
    spooldir = request.app.config['content.spooldir']
    removed_count = downloads.remove_downloads(spooldir, content_ids=file_list)
    # Translators, used as confirmation title after the chosen updates were
    # deleted on the updates page
    title = _("Updates deleted")
    # Translators, used as confirmation message after the chosen updates were
    # deleted on the updates page
    message = lazy_ngettext("An update has been deleted.",
                            "{update_count} updates have been deleted.",
                            removed_count).format(update_count=removed_count)
    return dict(page_title=title,
                message=message,
                redirect_url=i18n_url('downloads:list'),
                redirect_target=_("Updates"))
def ago(dt, days_only=False):
    # It may appear as if there's quite a bit of redundancy here, but it all
    # boils down to the need to mark translations using ngettext. We can't be
    # too 'progammatic' about this because various languages have different
    # numeber of plural forms and different rules about plural calculations.
    # Because of this, we sacrifice DRY for tranlsator-friendly strings.
    diff = utcnow().date() - dt
    divdays = functools.partial(divround, diff.days)
    period = divdays(365)
    if period:
        return ngettext("{number} year ago",
                        "{number} years ago",
                        period).format(number=period)
    period = divdays(30)
    if period:
        return ngettext("{number} month ago",
                        "{number} months ago",
                        period).format(number=period)
    period = divdays(7)
    if period:
        return ngettext("{number} week ago",
                        "{number} weeks ago",
                        period).format(number=period)
    if diff.days > 1:
        return ngettext("{number} day ago",
                        "{number} days ago",
                        diff.days).format(number=diff.days)
    if diff.days == 1:
        return _('Yesterday')
    if days_only:
        return _('Today')

    divsecs = functools.partial(divround, diff.seconds)
    period = divsecs(3600)
    if period:
        return ngettext("{number} hour ago",
                        "{number} hours ago",
                        period).format(number=period)
    period = divsecs(60)
    if period:
        return ngettext("{number} minute ago",
                        "{number} minutes ago",
                        period).format(number=period)
    if diff.seconds > 5:
        return ngettext("{number} second ago",
                        "{number} seconds ago",
                        diff.seconds).format(number=diff.seconds)
    return _('just now')
Пример #26
0
def prepare_content_list(multipage=None):
    # parse search query
    query = request.params.getunicode('q', '').strip()
    # parse language filter
    default_lang = request.user.options.get('content_language', None)
    lang = request.params.get('lang', default_lang)
    request.user.options['content_language'] = lang
    # parse tag filter
    archive = open_archive()
    try:
        tag = int(request.params.get('tag'))
    except (TypeError, ValueError):
        tag = None
        tag_name = None
    else:
        try:
            tag_name = archive.get_tag_name(tag)['name']
        except (IndexError, KeyError):
            abort(404, _('Specified tag was not found'))
    # parse pagination params
    page = Paginator.parse_page(request.params)
    per_page = Paginator.parse_per_page(request.params)
    # get content list filtered by above parsed filter params
    metas = filter_content(query, lang, tag, multipage)
    pager = Paginator(metas, page, per_page)
    return dict(metadata=pager.items,
                pager=pager,
                vals=request.params.decode(),
                query=query,
                lang=dict(lang=lang),
                tag=tag_name,
                tag_id=tag,
                tag_cloud=archive.get_tag_cloud())
Пример #27
0
    def parse(self, value):
        chosen = unicode(value)
        for (candidate, label) in self.choices:
            if unicode(candidate) == chosen:
                return chosen if value is not None else value

        raise ValueError(_("This is not a valid choice."))
Пример #28
0
def validate_datetime(dt_str):
    try:
        parse_datetime(dt_str)
    except ValueError as exc:
        return str(exc)
    except TypeError:
        return _("Invalid input.")
 def wrapper(path, **kwargs):
     manager = Manager(request.app.supervisor)
     if not manager.exists(path):
         # Translators, used as page title when a file's removal is
         # retried, but it was already deleted before
         title = _("File already removed")
         # Translators, used as message when a file's removal is
         # retried, but it was already deleted before
         message = _("The specified file has already been removed.")
         return template('feedback',
                         status='success',
                         page_title=title,
                         message=message,
                         redirect_url=get_parent_url(path),
                         redirect_target=_("Files"))
     return func(path=path, **kwargs)
Пример #30
0
def password_reset(key):
    next_path = request.params.get('next', '/')
    form = PasswordResetForm(request.forms)
    if not form.is_valid():
        return template('password_reset', form=form, next_path=next_path)

    key = form.processed_data['key']
    new_password = form.processed_data['new_password1']
    reset_password(key, new_password)
    redirect_url = get_redirect_path(request.app.get_url('login'), next_path)
    return template('feedback',
                    page_title=_('Password reset successful'),
                    status='success',
                    redirect_url=redirect_url,
                    message=_('You have successfully reset your password.'),
                    redirect_target=_('log-in'))
Пример #31
0
 def form_valid(self):
     exts.cache.set(FIRMWARE_UPDATE_KEY, 'processing')
     firmware = self.form.processed_data['firmware']
     try:
         path = exts.config['firmware.save_path']
         exts.tasks.schedule(update_firmware, args=(firmware, path))
     except Exception:
         logging.exception('Firmware upload error.')
         # Translators, shown when firmware upload failed
         return dict(saved=False,
                     message=_('Firmware upload failed.'))
     else:
         return dict(saved=True)
Пример #32
0
def save_settings():
    settings = request.app.supervisor.exts.settings
    form_cls = settings.get_form()
    form = form_cls(request.forms)
    if not form.is_valid():
        return dict(form=form, groups=settings.groups)

    request.app.supervisor.exts.setup.append(form.processed_data)
    request.app.supervisor.exts.events.publish('SETTINGS_SAVED',
                                               form.processed_data)
    return dict(form=form,
                groups=settings.groups,
                message=_('Settings saved.'),
                redirect_url=i18n_url('dashboard:main'))
Пример #33
0
class LengthValidator(Validator):
    """
    Validates that value's length is within specified range. This validator
    works with any objects that support the ``len()`` function.

    The ``min_len`` and ``max_len`` arguments are used to set the lower and
    upper bounds respectively. The check for those bounds are only done when
    the arguments are supplied so, when both arguments are omitted, this
    validator is effectively pass-through.

    :error name(s): min_len, max_len
    """

    messages = {
        'min_len': _('Must be at least {len} long'),
        'max_len': _('Must not be longer than {len}'),
    }

    def __init__(self, min_len=None, max_len=None, **kwargs):
        self.min_len = min_len
        self.max_len = max_len
        super(LengthValidator, self).__init__(**kwargs)

    def validate(self, value):
        if not value:
            return
        if self.min_len is not None and len(value) < self.min_len:
            raise ValidationError('min_len', {
                'value': value,
                'len': self.min_len
            })
        if self.max_len is not None and len(value) > self.max_len:
            raise ValidationError('max_len', {
                'value': value,
                'len': self.max_len
            })
Пример #34
0
class InRangeValidator(Validator):
    """
    Validates that value is within a range between two values. This validator
    works with any objects that support ``>`` and ``<`` operators.

    The ``min_value`` and ``max_value`` arguments are used to set the lower and
    upper bounds respectively. The check for those bounds are only done when
    the arguments are supplied so, when both arguments are omitted, this
    validator is effectively pass-through.

    :error name(s): min_val, max_val
    """

    messages = {
        'min_val': _('{value} is too small'),
        'max_val': _('{value} is too large'),
    }

    def __init__(self, min_value=None, max_value=None, **kwargs):
        self.min_value = min_value
        self.max_value = max_value
        super(InRangeValidator, self).__init__(**kwargs)

    def validate(self, value):
        if value is None:
            return
        if self.min_value is not None and self.min_value > value:
            raise ValidationError('min_val', {
                'value': value,
                'min': self.min_value
            })
        if self.max_value is not None and self.max_value < value:
            raise ValidationError('max_val', {
                'value': value,
                'max': self.max_value
            })
Пример #35
0
def do_enter():
    """Enter numbers into database"""
    numbers = set(parse_numbers(request.forms.get('numbers', '')))
    timestamp = datetime.datetime.now()

    usr_hash = get_fingerprint(request)

    result_num = []

    # TODO make place variable, depending on current request
    q = Place.select().where(Place.place == 'LAGESO')
    lageso = q.get() if q.count() == 1 else None

    if not numbers:
        result_num.append(_('novalidnumbers'))
    else:
        for num in numbers:
            if is_valid_number(num):
                try:
                    n = Number.create(number=num.upper(),
                                      time=timestamp,
                                      place=lageso,
                                      fingerprint=usr_hash)
                    result_num.append(n.number)
                except IntegrityError:
                    try:
                        n = Number.get(Number.number == num.upper())
                        # FIXME Why ain't there any value placeholder in translation string?
                        result_num.append(
                            _(u'erruniquenumber') + ': {}'.format(n.number))
                    except DoesNotExist:
                        result_num.append(
                            u'Something weired happend with {}'.format(num))

    # FIXME result_num is horrible, as it contains success and failures, indistinguishable
    return {'entered': result_num, 'timestamp': timestamp.strftime('%x %X')}
class WifiWEPForm(WifiSTAForm):
    #: Which security protocol is supported by the form
    SECURITY = consts.WEP
    #: WEP supports up to 4 keys to be specified, but only 1 can be active
    KEY_INDEXES = (
        (0, 0),
        (1, 1),
        (2, 2),
        (3, 3),
    )
    #: Validation error messages
    messages = {
        'missing_key': _('The selected key index has no key specified'),
    }

    key0 = form.StringField()
    key1 = form.StringField()
    key2 = form.StringField()
    key3 = form.StringField()
    key_index = form.SelectField(choices=KEY_INDEXES)

    @classmethod
    def from_conf_file(cls):
        """
        Initialize the form using configuration file or default config
        """
        ssid = exts.config.get('wireless.ssid', '')
        key0 = exts.config.get('wireless.key0', '')
        key1 = exts.config.get('wireless.key1', '')
        key2 = exts.config.get('wireless.key2', '')
        key3 = exts.config.get('wireless.key3', '')
        key_index = exts.config.get('wireless.key_index', '')
        return cls(data=dict(mode=cls.MODE,
                             security=cls.SECURITY,
                             ssid=ssid,
                             key0=key0,
                             key1=key1,
                             key2=key2,
                             key3=key3,
                             key_index=key_index))

    def validate(self):
        key_index = self.processed_data['key_index']
        key = self.processed_data['key{}'.format(key_index)]
        if not key:
            raise self.ValidationError('missing_key')
        # call superclass so saving is executed
        super(WifiWEPForm, self).validate()
Пример #37
0
class DateValidator(Validator):
    """
    Validates date fields. This validator attempts to parse the data as date (or
    date/time) data. When the data cannot be parsed, it fails.

    :error name(s): date
    """
    messages = {
        'date': _('{value} does not look like a valid date'),
    }

    def validate(self, value):
        try:
            dateutil.parser.parse(value)
        except (TypeError, ValueError) as exc:
            raise ValidationError('date', {'value': value, 'exc': str(exc)})
Пример #38
0
    def btmactable():
        global DEVICES

        if request.method == 'POST':
            # update all bt_macs.
            if len(request.forms) > 0:
                for idx, btmac in enumerate(request.forms):
                    #print(btmac)
                    #print(idx, bottle.request.forms.get(btmac), btmac)
                    DEVICES[idx]['bt_mac'] = request.forms.get(btmac)
                    # save directly in DB
                    # db is changed but not the memory data from Server!?
                    if msgDb:
                        msgDb.update_db(account=DEVICES[idx]['account'] , bt_mac=DEVICES[idx]['bt_mac'])

        return bottle.jinja2_template('btmactable', title=_("BT-Mac Table"), devices=DEVICES)
Пример #39
0
    def post():
        ondd_client = request.app.supervisor.exts.ondd
        is_test_mode = request.forms.get('mode', 'submit') == 'test'
        ONDDForm = get_form()
        form = ONDDForm(request.forms)
        form_valid = form.is_valid()
        snr_min = request.app.config.get('ondd.snr_min', 0.2)
        snr_max = request.app.config.get('ondd.snr_max', 0.9)
        band = ondd_helpers.get_band()

        if form_valid:
            # Store full settings
            logging.info('ONDD: tuner settings updated')
            ondd_helpers.write_ondd_setup(form.processed_data)
            if is_test_mode:
                return dict(successful=False,
                            form=form,
                            status=ondd_client.get_status(),
                            # Translators, shown when tuner settings are
                            # updated during setup wizard step.
                            message=_('Tuner settings have been updated'),
                            band=band,
                            lband=ondd_helpers.LBAND,
                            kuband=ondd_helpers.KUBAND,
                            is_l=band == ondd_helpers.LBAND,
                            is_ku=band == ondd_helpers.KUBAND,
                            preset_keys=ONDDForm.PRESETS[0].values.keys(),
                            SNR_MIN=snr_min,
                            SNR_MAX=snr_max)
            return dict(successful=True)
        # Form is not valid
        if is_test_mode:
            # We only do something about this in test mode
            return dict(successful=False,
                        form=form,
                        status=ondd_client.get_status(),
                        band=band,
                        lband=ondd_helpers.LBAND,
                        kuband=ondd_helpers.KUBAND,
                        is_l=band == ondd_helpers.LBAND,
                        is_ku=band == ondd_helpers.KUBAND,
                        preset_keys=ONDDForm.PRESETS[0].values.keys(),
                        SNR_MIN=snr_min,
                        SNR_MAX=snr_max)

        ondd_helpers.write_ondd_setup({})
        return dict(successful=True)
Пример #40
0
class Username(form.Validator):
    USERNAME_RE = USERNAME_REGEX

    messages = {
        # Translators, error message shown when username does not meet the
        # requirements during sign-up.
        'bad_username':
        _('Usernames must start with an English letter (a-z) '
          'and may contain up to 12 letters, numbers and an '
          "underscore character, '_'")
    }

    def validate(self, v):
        if not v:
            return
        if self.USERNAME_RE.match(v.strip()) is None:
            raise form.ValidationError('bad_username', {'value': v})
Пример #41
0
def handle_manual_add():
    url = request.params.get('url', '').strip()
    title = request.params.getunicode('title', '').strip()
    license = request.params.get('license') or None
    archive = request.params.get('archive') or None

    errors = {}
    if not url:
        # Translators, used as error message on failure to submit content
        errors['url'] = _('Please type in a valid URL')

    if not errors:
        try:
            content = Content.create(url=url,
                                     license=license,
                                     title=title,
                                     archive=archive)
            logging.info("Created content for '%s' (real url: '%s')", url,
                         content.url)
            response.flash(_('Content has been added'))
            redirect(i18n_path(PREFIX + '/'))
        except Content.InvalidURLError as err:
            logging.debug("URL error while parsing '%s': %s", url, err)
            # Translators, used as error message on failure submit suggestion
            errors['url'] = _('This URL is invalid')
        except Content.FetchError as err:
            logging.debug("Fetch error while parsing '%s': %s (%s)", url, err,
                          err.error)
            # Translators, used as error message on failure submit suggestion
            errors['url'] = _('The page at specified URL does not exist')
        except Content.NotAllowedError as err:
            logging.debug("Access error while parsing '%s': %s", url, err)
            # Translators, used as error message on failure submit suggestion
            errors['url'] = _('The page must be accessible to robots')
        except Content.ContentError as err:
            logging.debug("Content error while parsing '%s': %s (%s)", url,
                          err, err.error)
            # Translators, used as error message on failure submit suggestion
            errors['url'] = _('The content on the page could not be '
                              'understood, please provide and URL to a valid '
                              'web page')
        except Content.BotError as err:
            logging.exception("Error while fetching '%s':  %s", url, err)
            # Translators, used as error message on failure submit suggestion
            errors['url'] = _('There was an unknown error with the URL')

    return get_common_context(dict(vals=request.forms, errors=errors))
Пример #42
0
class Required(Validator):
    """
    Validates the presence of data. Technically, this validator fails for any
    data that is an empty string, a string that only contains whitespace, or
    data that is not a string and evaluates to ``False`` when coerced into
    boolean (e.g., 0, empty arrays and dicts, etc).

    :error name(s): required
    """

    messages = {
        'required': _('This field is required'),
    }

    def validate(self, data):
        if not data or isinstance(data, basestring) and not data.strip():
            # Translator, represents empty field's value
            raise ValidationError('required', {'value': _('(empty)')})
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
Пример #44
0
class ONDDFormBase(form.Form):
    messages = {
        # Translators, error message shown when a tuner is not detected
        'tuning_error': _("Tuner configuration could not be saved. "
                          "Please make sure that the tuner is connected.")
    }

    @property
    def preset_data(self):
        index = self.processed_data.get('preset', 0)
        # Negative indexing is valid on lists, so to properly handle when the
        # custom preset is chosen, it must be checked here
        if index < 0:
            return {}
        try:
            preset = self.PRESETS[index - 1]
        except IndexError:
            return {}
        else:
            (_, _, data) = preset
            return data
Пример #45
0
 def tohtml(self, label=True):
     s = ""
     if label and self.type != "hidden":
         s += "<label>%s</label>\n" % _(self.name)
     s += "<input type=%s name='%s'" % (self.type, self.name)
     s += " size='%s'" % self.size
     s += " id='%s'" % self.name
     if self.checked:
         s += " checked" 
     if self.value:
         s += " value='%s'" % self.value
     if self.url:
         s += " data-url='%s'" % self.url
     if self.path:
         s += " data-url='%s'" % path(self.path)
     if self.pick:
         s += " data-pick='%s'" % json.dumps(self.pick)
     if self.readonly:
         s += " readonly"
     s += ">"
     return s
Пример #46
0
    def sms():
        """SMS messaging page. Let's you select reciepients and message to send to M900 multicell.

        Returns:
            web page : Post or Get request answer resulting from the sms template
        """
        global DEVICES

        if request.method == 'POST':
            ip = '127.0.0.1'
            port = 10300

            print('init socket...')

            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                s.connect((ip, port))
                s.settimeout(500)
            except socket.error as exc:
                print('Caught exception socket.error: {0}'.format(exc))
                sys.exit(0)
            print("init socket successfull")


            d = json.dumps(request.json).encode("ascii")
            #print('data:', d)

            # prepare XML data request
            xml_message = "<?xml version='1.0' encoding='UTF-8'?> <request version='1.0' type='json-data'><json-data><![CDATA[ {0} ]]></json-data> <jobtype>sms</jobtype> </request>".format(d.decode('ascii'))
            #print(xml_message)

            s.send(bytes(xml_message, 'utf-8'))
            #print('data sent')

            s.close()
        else:
            print('GET request of the page, do nothing')

        return bottle.jinja2_template('sms', title=_("SMS View"), devices=DEVICES)
Пример #47
0
class ONDDDashboardPlugin(DashboardPlugin):
    # Translators, used as dashboard section title
    heading = _('Tuner Settings')
    name = 'ondd'
    priority = 10

    def get_template(self):
        return 'ondd/dashboard'

    def get_context(self):
        initial_data = ondd_helpers.read_ondd_setup()
        preset = match_preset(initial_data)
        ONDDForm = ondd_forms.FORMS[ondd_helpers.get_band()]
        band = ondd_helpers.get_band()
        return dict(band=band,
                    lband=ondd_helpers.LBAND,
                    kuband=ondd_helpers.KUBAND,
                    is_l=band == ondd_helpers.LBAND,
                    is_ku=band == ondd_helpers.KUBAND,
                    preset_keys=ONDDForm.PRESETS[0].values.keys(),
                    form=ONDDForm(initial_data),
                    selected_preset=preset)
Пример #48
0
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', {})
Пример #49
0
def setup_ondd():
    ondd_client = request.app.supervisor.exts.ondd
    is_test_mode = request.forms.get('mode', 'submit') == 'test'

    form = ONDDForm(request.forms)
    form_valid = form.is_valid()
    snr_min = request.app.config.get('ondd.snr_min', 0.2)
    snr_max = request.app.config.get('ondd.snr_max', 0.9)

    if form_valid:
        # Store full settings
        logging.info('ONDD: tuner settings updated')
        request.app.supervisor.exts.setup.append({'ondd': form.processed_data})

        if is_test_mode:
            return dict(
                successful=False,
                form=form,
                status=ondd_client.get_status(),
                # Translators, shown when tuner settings are updated
                # during setup wizard step.
                message=_('Tuner settings have been updated'),
                SNR_MIN=snr_min,
                SNR_MAX=snr_max)
        return dict(successful=True)

    # Form is not valid
    if is_test_mode:
        # We only do something about this in test mode
        return dict(successful=False,
                    form=form,
                    status=ondd_client.get_status(),
                    SNR_MIN=snr_min,
                    SNR_MAX=snr_max)

    request.app.supervisor.exts.setup.append({'ondd': {}})
    return dict(successful=True)
Пример #50
0
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', {})
Пример #51
0
def perform_rebuild():
    try:
        rtime = rebuild()
    except LockFailureError:
        logging.debug('DBMANAGE: Global lock could not be acquired')
        # Translators, error message displayed if database rebuild fails
        base_msg = _('Database could not be rebuilt. '
                     'The following error occurred:')
        # Translators, error message displayed when locking fails during
        # database rebuild
        reason = _('Librarian could not enter maintenance mode and '
                   'database rebuild was cancelled. Please make '
                   'sure noone else is using Librarian and '
                   'try again.')
        message = ' '.join(map(unicode, [base_msg, reason]))
        status = 'error'
        url = i18n_url('dashboard:main')
        # Translators, redirection target if database backup was successful
        target = _('Dashboard')
    else:
        # Translators, message displayed if database backup was successful
        base_msg = _('Content database has been rebuilt from scratch. A backup'
                     ' copy of the original database has been created. '
                     'You will find it in the files section.')
        # Translators, message displayed if database backup was successful
        took_msg = lazy_ngettext('The operation took {time} second',
                                 'The operation took {time} seconds',
                                 rtime).format(time=round(rtime, 2))
        message = ' '.join(map(unicode, [base_msg, took_msg]))
        # Translators, message displayed if database backup was successful
        status = 'success'
        url = i18n_url(request.app.config['app.default_route'])
        # Translators, redirection target if database backup was successful
        target = _('Library')

    # Translators, used as page title
    title = _('Database rebuild')
    return dict(status=status,
                page_title=title,
                message=message,
                redirect_url=url,
                redirect_target=target)
def delete_path(path):
    manager = Manager(request.app.supervisor)
    (success, error) = manager.remove(path)
    if success:
        # Translators, used as page title of successful file removal feedback
        page_title = _("File removed")
        # Translators, used as message of successful file removal feedback
        message = _("File successfully removed.")
        return dict(status='success',
                    page_title=page_title,
                    message=message,
                    redirect_url=get_parent_url(path),
                    redirect_target=_("file list"))

    # Translators, used as page title of unsuccessful file removal feedback
    page_title = _("File not removed")
    # Translators, used as message of unsuccessful file removal feedback
    message = _("File could not be removed.")
    return dict(status='error',
                page_title=page_title,
                message=message,
                redirect_url=get_parent_url(path),
                redirect_target=_("file list"))
Пример #53
0
from collections import namedtuple

from bottle_utils.i18n import lazy_gettext as _

__all__ = ('LBAND', 'KUBAND', 'L_PRESETS', 'KU_PRESETS', 'PRESETS')

Preset = namedtuple('Preset', ('label', 'index', 'values'))

LBAND = 'l'
KUBAND = 'ku'

L_PRESETS = [
    # Translators, name of the L-band tuner preset covering AF-EU-ME
    Preset(
        _('Africa-Europe-Middle East (25E)'),
        1,
        {
            'frequency': '1545.94',
            'uncertainty': '4000',
            'symbolrate': '4200',
            'sample_rate': '1',
            'rf_filter': '20',
            'descrambler': True,
            # Translators, used as coverage area of a transponder
            'coverage': _('Africa, Europe, Middle East'),
        }),
    # Translators, name of the L-band tuner preset covering the Americas
    Preset(
        _('North and South America (98W)'),
        2,
        {
Пример #54
0
 def tohtml(self):
     s = "<button id='%s' name='%s'>%s</button>" % (
             self.name, self.name, _(self.name))
     return s
Пример #55
0
DELIVERY = (
    ('DVB-S', 'DVB-S'),
    ('DVB-S2', 'DVB-S2'),
)

MODULATION = (
    ('QPSK', 'QPSK'),
    ('8PSK', '8PSK'),
    ('16APSK', '16APSK'),
    ('32APSK', '32APSK'),
)

POLARIZATION = (
    # Translators, refers to transponder polarization
    ('0', _('None')),
    # Translators, refers to transponder polarization
    ('v', _('Vertical')),
    # Translators, refers to transponder polarization
    ('h', _('Horizontal')),
)

VOLTS = {
    '0': 0,
    'v': 13,
    'h': 18,
}

LNB_TYPES = (
    # Translators, this is a type of LNB
    (ondd_consts.UNIVERSAL, _('Universal')),
Пример #56
0
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)
Пример #57
0
class Field(Ordered, ErrorMixin):
    """
    Form field base class. This class provides the base functionality for all
    form fields.

    The ``label`` argument is used to specify the field's label.

    The ``validators`` argument is used to specify the validators that will be
    used on the field data.

    If any data should be bound to a field, the ``value`` argument can be used
    to specify it. Value can be a callable, in which case it is called and its
    return value used as ``value``.

    The ``name`` argument is used to specify the field name.

    The ``messages`` argument is used to customize the validation error
    messages. These override any messages found in the :py:attr:`~messages`
    attribute.

    Any extra keyword attributes passed to the constructor are stored as
    :py:attr:`~options` property on the instance.
    """

    ValidationError = ValidationError

    #: Field ID attribute prefix (this is prepended to the field name)
    _id_prefix = ''

    #: Generic error message to be used when no messages match the validation
    #: error.
    # Translators, used as generic error message in form fields, 'value' should
    # not be translated.
    generic_error = _('Invalid value for this field')
    #: Validation error messages.
    messages = {}
    #: Field markup type. This is arbitrary and normally used in the templates
    #: to differentiate between field types. It is up to the template author to
    #: decide how this should be treated.
    type = 'text'

    def __new__(cls, *args, **kwargs):
        if 'name' in kwargs:
            return super(Field, cls).__new__(cls)
        return DormantField(cls, args, kwargs)

    def __init__(self,
                 label=None,
                 validators=None,
                 value=None,
                 name=None,
                 messages={},
                 **options):
        super(Field, self).__init__()  # needed to apply ordering

        #: Field name
        self.name = name

        #: Field label
        self.label = label

        #: Field validators
        self.validators = validators or []

        #: Raw value of the field
        self.value = value() if callable(value) else value

        #: Processed value of the field
        self.processed_value = None

        #: Whether value is bound to this field
        self.is_value_bound = False

        self._error = None

        #: Extra keyword argument passed to the constructor
        self.options = options

        # Copy the messages so that modifying them does not result in class'
        # ``messages`` attribute to be altered.
        self.messages = self.messages.copy()

        # Collect default messages from all validators into the messages dict
        for validator in self.validators:
            self.messages.update(validator.messages)

        # Update the messages dict with any user-supplied messages
        self.messages.update(messages)

    def bind_value(self, value):
        """
        Binds a value. This method also sets the :py:attr:`~is_value_bound`
        property to ``True``.
        """
        self.value = value
        self.is_value_bound = True

    def is_valid(self):
        """
        Validate form field and return ``True`` is data is valid. If there is
        an error during Validation, the error object is stored in the
        :py:attr:`~_error` property. Before validation, the raw value is
        processed using the :py:meth:`~parse` method, and stored in
        :py:attr:`~processed_value` attribute.

        When parsing fails with ``ValueError`` exception, a 'generic' error is
        stored. The default message for this error is stored in the
        :py:attr:`~generic_error` property, and can be customized by passing
        a ``'generic'`` message as part of the ``messages`` constructor
        argument.
        """
        try:
            self.processed_value = self.parse(self.processed_value)
        except ValueError as exc:
            self._error = ValidationError('generic',
                                          {'value': self.processed_value})
            return False

        for validate in self.validators:
            try:
                validate(self.processed_value)
            except ValidationError as exc:
                self._error = exc
                return False

        return True

    def parse(self, value):
        """
        Parse the raw value and convert to Python object. Subclasses should
        return the value in it's correct type. In case the passed in value
        cannot be cast into it's correct type, the method should raise a
        ``ValueError`` exception with an appropriate error message.
        """
        raise NotImplementedError()
Пример #58
0
class DashboardMenuItem(MenuItem):
    name = 'dashboard'
    label = _("Settings")
    icon_class = 'settings'
    route = 'dashboard:main'
Пример #59
0
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', {})
Пример #60
0
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', {})