Source

ryshcate / ryshcate / forms.py

# -*- coding: utf-8 -*-
"""
ryshcate.forms
==============
Forms for submission and settings, and utilities for dealing with them.

:copyright: 2010 Matthew "LeafStorm" Frazier
:license:   MIT/X11, see LICENSE for details
"""
from ryshcate.locale import _, __, common_timezones, TRANSLATED_LANGUAGES
from ryshcate.utils import contains_profanities, LEXER_LIST, get_all_styles
from wtforms import (Form, BooleanField, TextField, TextAreaField,
                     SelectField, ValidationError, validators as val)
from wtforms.fields import Field
from wtforms.widgets import TextInput

### Custom field

class TagListField(Field):
    widget = TextInput()

    def _value(self):
        if self.data:
            return u', '.join(self.data)
        else:
            return u''

    def process_formdata(self, valuelist):
        if valuelist:
            rawdata = valuelist[0].replace(';', ',')
            self.data = [x.strip() for x in rawdata.split(',')]
        else:
            self.data = []
    
    @staticmethod
    def _remove_duplicates(seq):
        """
        Removes duplicate tags. It normalizes tags to lowercase.
        """
        s = set()
        for item in seq:
            tag = item.lower()
            if tag not in s:
                s.add(tag)
                yield tag


### Validators

length_msg = __(u"This field must not be longer than %(max)d characters")

def required():
    return val.Required(message=__(u"This field is required"))


def clean(form, field):
    if isinstance(field.data, basestring):
        profane = contains_profanities(field.data)
    else:
        profane = any(contains_profanities(i) for i in field.data)
    if profane:
        raise ValidationError(_(u"This field may not contain profanities"))


### Forms

class CreatePasteForm(Form):
    title = TextField(__(u'Title'), [required(),
                      val.Length(max=64, message=length_msg), clean],
                      description=__(u'A title for the paste.'))
    code = TextAreaField(__(u'Code'), [required(), clean],
                         description=__(u'The paste\'s source code.'))
    language = SelectField(__(u'Language'), [required()], default='text',
                           choices=LEXER_LIST,
                           description=__(u'The language this paste is in.'))
    tags = TagListField(__(u'Tags'), [required(), clean],
                        description=__(u'A comma-separated list of tags.'))
    private = BooleanField(__(u'Private'), default=False,
                           description=__(u'Check this if the paste should '
                           'not be listed publicly.'))


class SettingsForm(Form):
    locale = SelectField(
        __(u'Locale'), [required()], choices=TRANSLATED_LANGUAGES,
        description=__(u'The language to use on the site.')
    )
    style = SelectField(
        __(u'Pygments Style'), [required()],
        choices=[(s, s) for s in get_all_styles()],
        description=__(u'The color scheme to use for highlighted code.')
    )
    timezone = SelectField(
        __(u'Timezone'), [required()], default='UTC',
        choices=[(tz, tz.replace('_', ' ')) for tz in common_timezones],
        description=__(u'The timezone to display times in.')
    )