Пример #1
0
class BaseZendeskForm(forms.Form):
    """Base Form class for all Zendesk forms."""

    def __init__(self, user, *args, **kwargs):
        super(BaseZendeskForm, self).__init__(*args, **kwargs)

        self.user = user

        # Add email field for users not logged in.
        if not user.is_authenticated():
            email = forms.EmailField(
                label=_lazy(u'Email:'),
                widget=forms.TextInput(attrs={
                    'placeholder': EMAIL_PLACEHOLDER
                }))
            self.fields['email'] = email

    subject = StrippedCharField(
        label=_lazy(u'Subject:'),
        min_length=4,
        max_length=255,
        widget=forms.TextInput(attrs={'placeholder': SUBJECT_PLACEHOLDER}),
        error_messages={'required': SUBJECT_CONTENT_REQUIRED,
                        'min_length': SUBJECT_CONTENT_SHORT,
                        'max_length': SUBJECT_CONTENT_LONG})

    body = StrippedCharField(
        label=_lazy(u'Body:'),
        min_length=5,
        max_length=10000,
        widget=forms.Textarea(attrs={'placeholder': BODY_PLACEHOLDER}),
        error_messages={'required': BODY_CONTENT_REQUIRED,
                        'min_length': BODY_CONTENT_SHORT,
                        'max_length': BODY_CONTENT_LONG})

    def ticket_body(self, email):
        """Body of the ticket to submit to Zendesk."""
        return 'Email: {email}\n{body}'.format(
            email=email,
            body=self.cleaned_data['body'])

    def submit_ticket(self):
        """Submit the ticket to Zendesk."""
        if self.user.is_authenticated():
            email = self.user.email
        else:
            email = self.cleaned_data['email']

        submit_ticket(
            email,
            self.cleaned_data['category'],
            self.cleaned_data['subject'],
            self.ticket_body(email),
            [])
Пример #2
0
class ExampleForm(forms.Form):
    """Example form to test a bunch of Django fields."""
    char = forms.CharField(max_length=10)
    char_optional = forms.CharField(required=False, widget=forms.TextInput())
    file = forms.FileField(max_length=10)
    choice = forms.ChoiceField(choices=((1, 1), (2, 2)))
    stripped_char = StrippedCharField(max_length=10)
    bool = forms.BooleanField()
    textarea = StrippedCharField(widget=forms.Textarea())
    email = forms.EmailField()
    url = forms.URLField(required=False, verify_exists=False)
    date = forms.DateField()
    time = forms.TimeField()
Пример #3
0
class ReviewForm(forms.Form):
    comment = StrippedCharField(max_length=2000, widget=forms.Textarea(),
                                required=False, label=_lazy(u'Comment:'),
                                error_messages={'max_length': COMMENT_LONG})

    _widget = forms.RadioSelect(renderer=RadioFieldRendererWithHelpText)
    significance = forms.TypedChoiceField(
        label=_lazy(u'Significance:'),
        choices=SIGNIFICANCES,
        initial=SIGNIFICANCES[1][0],
        required=False, widget=_widget,
        coerce=int, empty_value=SIGNIFICANCES[1][0])

    is_ready_for_localization = forms.BooleanField(
        initial=False,
        label=_lazy(u'Ready for localization'),
        required=False)

    needs_change = forms.BooleanField(
        label=_lazy(u'Needs change'),
        initial=False,
        required=False)

    needs_change_comment = forms.CharField(
        label=_lazy(u'Comment:'),
        widget=forms.Textarea(),
        required=False)
Пример #4
0
class NewThreadForm(forms.Form):
    """Form to start a new thread."""
    title = StrippedCharField(min_length=5, max_length=255,
                              label=_lazy(u'Title:'),
                              widget=forms.TextInput(attrs={'size': 80}),
                              error_messages={'required': MSG_TITLE_REQUIRED,
                                              'min_length': MSG_TITLE_SHORT,
                                              'max_length': MSG_TITLE_LONG})
    content = StrippedCharField(
        label=_lazy(u'Content:'),
        min_length=5,
        max_length=10000,
        widget=forms.Textarea(attrs={'rows': 30, 'cols': 76}),
        error_messages={'required': MSG_CONTENT_REQUIRED,
                        'min_length': MSG_CONTENT_SHORT,
                        'max_length': MSG_CONTENT_LONG})
Пример #5
0
class EditThreadForm(forms.ModelForm):
    """Form to start a new thread."""
    title = StrippedCharField(min_length=5, max_length=255,
                              label=_lazy(u'Title:'),
                              widget=forms.TextInput(attrs={'size': 80}),
                              error_messages={'required': MSG_TITLE_REQUIRED,
                                              'min_length': MSG_TITLE_SHORT,
                                              'max_length': MSG_TITLE_LONG})

    class Meta:
        model = Thread
        fields = ('title',)
Пример #6
0
class EditPostForm(forms.Form):
    """Form to edit an existing post."""
    content = StrippedCharField(
        label=_lazy(u'Content:'),
        min_length=5,
        max_length=10000,
        widget=forms.Textarea(attrs={'rows': 30, 'cols': 76}),
        error_messages={'required': MSG_CONTENT_REQUIRED,
                        'min_length': MSG_CONTENT_SHORT,
                        'max_length': MSG_CONTENT_LONG})

    class Meta:
        model = Post
        exclude = ('thread', 'author', 'updated', 'created', 'updated_by')
Пример #7
0
class ReplyForm(forms.ModelForm):
    """Reply form for forum threads."""
    content = StrippedCharField(
        label=_lazy(u'Content:'),
        min_length=5,
        max_length=10000,
        widget=forms.Textarea(attrs={'rows': 10, 'cols': 80}),
        error_messages={'required': MSG_CONTENT_REQUIRED,
                        'min_length': MSG_CONTENT_SHORT,
                        'max_length': MSG_CONTENT_LONG})

    class Meta:
        model = Post
        fields = ('content', )
Пример #8
0
class AnswerForm(forms.Form):
    """Form for replying to a question."""
    content = StrippedCharField(
        label=_lazy('Content:'),
        min_length=5,
        max_length=10000,
        widget=forms.Textarea(attrs={'placeholder': REPLY_PLACEHOLDER}),
        error_messages={'required': MSG_CONTENT_REQUIRED,
                        'min_length': MSG_CONTENT_SHORT,
                        'max_length': MSG_CONTENT_LONG})

    class Meta:
        model = Answer
        fields = ('content',)
Пример #9
0
class MediaForm(forms.ModelForm):
    """Common abstractions for Image form."""
    locale = forms.ChoiceField(required=False,
                               label=_lazy(u'Locale'),
                               choices=[(k, LOCALES[k].native)
                                        for k in settings.SUMO_LANGUAGES],
                               initial=settings.WIKI_DEFAULT_LANGUAGE)
    title = StrippedCharField(required=False,
                              label=_lazy(u'Title'),
                              help_text=TITLE_HELP_TEXT % {'type': u'Image'},
                              min_length=5,
                              max_length=255,
                              error_messages={
                                  'required': MSG_TITLE_REQUIRED,
                                  'min_length': MSG_TITLE_SHORT,
                                  'max_length': MSG_TITLE_LONG
                              })
    description = StrippedCharField(required=False,
                                    label=_lazy(u'Description'),
                                    help_text=DESCRIPTION_HELP_TEXT,
                                    max_length=10000,
                                    widget=forms.Textarea(),
                                    error_messages={
                                        'required': MSG_DESCRIPTION_REQUIRED,
                                        'max_length': MSG_DESCRIPTION_LONG
                                    })

    def __init__(self, *args, **kwargs):
        self.is_ajax = kwargs.pop('is_ajax', True)
        super(MediaForm, self).__init__(*args, **kwargs)
        if not self.is_ajax:
            self.fields['locale'].required = True
            self.fields['title'].required = True
            self.fields['description'].required = True

    def save(self, update_user=None, is_draft=True, **kwargs):
        return save_form(self, update_user, is_draft=is_draft, **kwargs)
Пример #10
0
class MarketplaceRefundForm(BaseZendeskForm):
    transaction_id = StrippedCharField(
        label=_lazy(u'Transaction ID:'),
        widget=forms.TextInput(
            attrs={'placeholder': TRANSACTION_ID_PLACEHOLDER}),
        error_messages={'required': TRANSACTION_ID_REQUIRED})

    category = forms.ChoiceField(label=_lazy(u'Category:'),
                                 choices=REFUND_CATEGORY_CHOICES)

    @property
    def ticket_body(self):
        """Body of the ticket to submit to Zendesk."""
        return 'Transaction ID: {id}\nCategory: {category}\n{body}'.format(
            id=self.cleaned_data['transaction_id'],
            category=self.cleaned_data['category'],
            body=self.cleaned_data['body'])
Пример #11
0
class DocumentForm(forms.ModelForm):
    """Form to create/edit a document."""
    def __init__(self, *args, **kwargs):
        # Quasi-kwargs:
        can_archive = kwargs.pop('can_archive', False)
        can_edit_needs_change = kwargs.pop('can_edit_needs_change', False)
        initial_title = kwargs.pop('initial_title', '')

        super(DocumentForm, self).__init__(*args, **kwargs)

        title_field = self.fields['title']
        title_field.initial = initial_title

        slug_field = self.fields['slug']
        slug_field.initial = slugify(initial_title)

        topics_field = self.fields['topics']
        topics_field.choices = Topic.objects.values_list('id', 'title')

        products_field = self.fields['products']
        products_field.choices = Product.objects.values_list('id', 'title')

        related_documents_field = self.fields['related_documents']
        related_documents_field.choices = Document.objects.values_list('id', 'title')

        # If user hasn't permission to frob is_archived, remove the field. This
        # causes save() to skip it as well.
        if not can_archive:
            del self.fields['is_archived']

        # If user hasn't permission to mess with needs_change*, remove the
        # fields. This causes save() to skip it as well.
        if not can_edit_needs_change:
            del self.fields['needs_change']
            del self.fields['needs_change_comment']

    title = StrippedCharField(
        min_length=5, max_length=255,
        widget=forms.TextInput(),
        label=_lazy(u'Title:'),
        help_text=_lazy(u'Title of article'),
        error_messages={'required': TITLE_REQUIRED,
                        'min_length': TITLE_SHORT,
                        'max_length': TITLE_LONG})

    # We don't use forms.SlugField because it is too strict in
    # what it allows (English/Roman alpha-numeric characters and dashes).
    # Instead, we do custom validation in `clean_slug` below.
    slug = StrippedCharField(
        min_length=3, max_length=255,
        widget=forms.TextInput(),
        label=_lazy(u'Slug:'),
        help_text=_lazy(u'Article URL'),
        error_messages={'required': SLUG_REQUIRED,
                        'min_length': SLUG_SHORT,
                        'max_length': SLUG_LONG})

    products = forms.MultipleChoiceField(
        label=_lazy(u'Relevant to:'),
        required=False,
        widget=forms.CheckboxSelectMultiple())

    is_localizable = forms.BooleanField(
        initial=True,
        label=_lazy(u'Allow translations:'),
        required=False)

    is_archived = forms.BooleanField(
        label=_lazy(u'Obsolete:'),
        required=False)

    allow_discussion = forms.BooleanField(
        label=_lazy(u'Allow discussion on this article?'),
        initial=True,
        required=False)

    category = forms.ChoiceField(
        choices=CATEGORIES,
        # Required for non-translations, which is
        # enforced in Document.clean().
        required=False,
        label=_lazy(u'Category:'),
        help_text=_lazy(u'Type of article'))

    topics = forms.MultipleChoiceField(
        label=_lazy(u'Topics:'),
        required=False,
        widget=ProductTopicsAndSubtopicsWidget())

    related_documents = forms.MultipleChoiceField(
        label=_lazy(u'Related documents:'),
        required=False,
        widget=RelatedDocumentsWidget())

    locale = forms.CharField(widget=forms.HiddenInput())

    needs_change = forms.BooleanField(
        label=_lazy(u'Needs change:'),
        initial=False,
        required=False)

    needs_change_comment = forms.CharField(
        label=_lazy(u'Comment:'),
        widget=forms.Textarea(),
        required=False)

    def clean_slug(self):
        slug = self.cleaned_data['slug']
        # Blacklist /, ?, % and +,
        if not re.compile(r'^[^/^\+^\?%]+$').match(slug):
            raise forms.ValidationError(SLUG_INVALID)
        return slug

    def clean(self):
        c = super(DocumentForm, self).clean()
        locale = c.get('locale')

        # Products are required for en-US
        products = c.get('products')
        if (locale == settings.WIKI_DEFAULT_LANGUAGE and
                (not products or len(products) < 1)):
            raise forms.ValidationError(PRODUCT_REQUIRED)

        # Topics are required for en-US
        topics = c.get('topics')
        if (locale == settings.WIKI_DEFAULT_LANGUAGE and
                (not topics or len(topics) < 1)):
            raise forms.ValidationError(TOPIC_REQUIRED)

        return c

    class Meta:
        model = Document
        fields = ('title', 'slug', 'category', 'is_localizable', 'products',
                  'topics', 'locale', 'is_archived', 'allow_discussion',
                  'needs_change', 'needs_change_comment', 'related_documents')

    def save(self, parent_doc, **kwargs):
        """Persist the Document form, and return the saved Document."""
        doc = super(DocumentForm, self).save(commit=False, **kwargs)
        doc.parent = parent_doc

        # If document doesn't need change, clear out the comment.
        if not doc.needs_change:
            doc.needs_change_comment = ''

        # Create the share link if it doesn't exist and is in
        # a category it should show for.
        doc.save()
        if (doc.category in settings.IA_DEFAULT_CATEGORIES and
                not doc.share_link):
            # This operates under the constraints of passing in a list.
            add_short_links.delay([doc.pk])

        self.save_m2m()

        if parent_doc:
            # Products are not set on translations.
            doc.products.remove(*[p for p in doc.products.all()])

        return doc
Пример #12
0
class RevisionForm(forms.ModelForm):
    """Form to create new revisions."""
    keywords = StrippedCharField(required=False,
                                 label=_lazy(u'Keywords:'),
                                 help_text=_lazy(u'Affects search results'))

    summary = StrippedCharField(
        min_length=5, max_length=1000, widget=forms.Textarea(),
        label=_lazy(u'Search result summary:'),
        help_text=_lazy(u'Only displayed on search results page'),
        error_messages={'required': SUMMARY_REQUIRED,
                        'min_length': SUMMARY_SHORT,
                        'max_length': SUMMARY_LONG})

    content = StrippedCharField(
        min_length=5, max_length=100000,
        label=_lazy(u'Content:'),
        widget=forms.Textarea(),
        error_messages={'required': CONTENT_REQUIRED,
                        'min_length': CONTENT_SHORT,
                        'max_length': CONTENT_LONG})

    expires = forms.DateField(
        label=_lazy(u'Expiry date:'),
        required=False)

    comment = StrippedCharField(required=False, label=_lazy(u'Comment:'))

    class Meta(object):
        model = Revision
        fields = ('keywords', 'summary', 'content', 'comment', 'based_on',
                  'expires')

    def __init__(self, *args, **kwargs):
        super(RevisionForm, self).__init__(*args, **kwargs)
        self.fields['based_on'].widget = forms.HiddenInput()
        self.fields['comment'].widget = forms.TextInput(
            attrs={'maxlength': MAX_REVISION_COMMENT_LENGTH})

    def save(self, creator, document, based_on_id=None, base_rev=None,
             **kwargs):
        """Persist me, and return the saved Revision.

        Take several other necessary pieces of data that aren't from the
        form.

        """
        # Throws a TypeError if somebody passes in a commit kwarg:
        new_rev = super(RevisionForm, self).save(commit=False, **kwargs)

        new_rev.document = document
        new_rev.creator = creator

        if based_on_id:
            new_rev.based_on_id = based_on_id

        # If the document doesn't allow the revision creator to edit the
        # keywords, keep the old value.
        if base_rev and not document.allows(creator, 'edit_keywords'):
            new_rev.keywords = base_rev.keywords

        new_rev.save()
        return new_rev
Пример #13
0
    def __init__(self, product=None, category=None, *args, **kwargs):
        """Init the form.

        We are adding fields here and not declaratively because the
        form fields to include depend on the selected product/category.
        """
        super(EditQuestionForm, self).__init__(*args, **kwargs)

        #  Extra fields required by product/category selected
        extra_fields = []

        if product:
            extra_fields += product.get('extra_fields', [])
        if category:
            extra_fields += category.get('extra_fields', [])

        #  Add the fields to the form
        error_messages = {
            'required': MSG_TITLE_REQUIRED,
            'min_length': MSG_TITLE_SHORT,
            'max_length': MSG_TITLE_LONG
        }
        field = StrippedCharField(label=TITLE_LABEL,
                                  min_length=5,
                                  max_length=160,
                                  widget=forms.TextInput(),
                                  error_messages=error_messages)
        self.fields['title'] = field

        error_messages = {
            'required': MSG_CONTENT_REQUIRED,
            'min_length': MSG_CONTENT_SHORT,
            'max_length': MSG_CONTENT_LONG
        }
        field = StrippedCharField(label=CONTENT_LABEL,
                                  min_length=5,
                                  max_length=10000,
                                  widget=forms.Textarea(),
                                  error_messages=error_messages)
        self.fields['content'] = field

        if 'sites_affected' in extra_fields:
            field = StrippedCharField(label=SITE_AFFECTED_LABEL,
                                      initial='http://',
                                      required=False,
                                      max_length=255,
                                      widget=forms.TextInput())
            self.fields['sites_affected'] = field

        if 'crash_id' in extra_fields:
            field = StrippedCharField(label=CRASH_ID_LABEL,
                                      help_text=CRASH_ID_HELP,
                                      required=False,
                                      max_length=255,
                                      widget=forms.TextInput())
            self.fields['crash_id'] = field

        if 'frequency' in extra_fields:
            field = forms.ChoiceField(label=FREQUENCY_LABEL,
                                      choices=FREQUENCY_CHOICES,
                                      required=False)
            self.fields['frequency'] = field

        if 'started' in extra_fields:
            field = StrippedCharField(label=STARTED_LABEL,
                                      required=False,
                                      max_length=255,
                                      widget=forms.TextInput())
            self.fields['started'] = field

        if 'addon' in extra_fields:
            field = StrippedCharField(label=ADDON_LABEL,
                                      required=False,
                                      max_length=255,
                                      widget=forms.TextInput())
            self.fields['addon'] = field

        if 'troubleshooting' in extra_fields:
            widget = forms.Textarea(attrs={'class': 'troubleshooting'})
            field = StrippedCharField(label=TROUBLESHOOTING_LABEL,
                                      help_text=TROUBLESHOOTING_HELP,
                                      required=False,
                                      max_length=655360,
                                      widget=widget)
            self.fields['troubleshooting'] = field

        if 'ff_version' in extra_fields:
            self.fields['ff_version'] = StrippedCharField(
                label=FF_VERSION_LABEL, required=False)

        if 'device' in extra_fields:
            self.fields['device'] = StrippedCharField(label=DEVICE_LABEL,
                                                      required=False)

        if 'os' in extra_fields:
            self.fields['os'] = StrippedCharField(label=OS_LABEL,
                                                  required=False)

        if 'plugins' in extra_fields:
            widget = forms.Textarea(attrs={'class': 'plugins'})
            self.fields['plugins'] = StrippedCharField(label=PLUGINS_LABEL,
                                                       required=False,
                                                       widget=widget)