Ejemplo n.º 1
0
class ReviewerNotesForm(happyforms.ModelForm):
    approvalnotes = forms.CharField(
        widget=TranslationTextarea(attrs={'rows': 4}), required=False)

    class Meta:
        model = Version
        fields = ('approvalnotes', )
Ejemplo n.º 2
0
class VersionForm(WithSourceMixin, happyforms.ModelForm):
    releasenotes = TransField(widget=TransTextarea(), required=False)
    approvalnotes = forms.CharField(
        widget=TranslationTextarea(attrs={'rows': 4}), required=False)
    source = forms.FileField(required=False, widget=SourceFileInput)

    class Meta:
        model = Version
        fields = ('releasenotes', 'approvalnotes', 'source')
Ejemplo n.º 3
0
class VersionForm(WithSourceMixin, forms.ModelForm):
    releasenotes = TransField(widget=TransTextarea(), required=False)
    approvalnotes = forms.CharField(
        widget=TranslationTextarea(attrs={'rows': 4}), required=False)
    source = forms.FileField(required=False, widget=SourceFileInput)
    clear_pending_info_request = forms.BooleanField(required=False)

    class Meta:
        model = Version
        fields = (
            'releasenotes',
            'clear_pending_info_request',
            'approvalnotes',
            'source',
        )

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super(VersionForm, self).__init__(*args, **kwargs)
        # Fetch latest reviewer comment if the addon has a pending info
        # request,  so that the template in which the form is used can display
        # that comment.
        if self.instance and self.instance.addon.pending_info_request:
            try:
                self.pending_info_request_comment = (
                    ActivityLog.objects.for_addons(self.instance.addon).filter(
                        action=amo.LOG.REQUEST_INFORMATION.id).latest('pk')
                ).details['comments']
            except (ActivityLog.DoesNotExist, KeyError):
                self.pending_info_request_comment = ''

    def save(self, *args, **kwargs):
        super(VersionForm, self).save(*args, **kwargs)
        # Clear pending info request on the addon if requested, adding an entry
        # in the Activity Log to indicate that.
        if self.cleaned_data.get('clear_pending_info_request'):
            AddonReviewerFlags.objects.update_or_create(
                addon=self.instance.addon,
                defaults={'pending_info_request': None})
            log_and_notify(amo.LOG.DEVELOPER_CLEAR_INFO_REQUEST, None,
                           self.request.user, self.instance)
Ejemplo n.º 4
0
class LicenseForm(AMOModelForm):
    builtin = forms.TypedChoiceField(
        choices=[], coerce=int,
        widget=LicenseRadioSelect(attrs={'class': 'license'}))
    name = forms.CharField(widget=TranslationTextInput(),
                           label=_(u'What is your license\'s name?'),
                           required=False, initial=_('Custom License'))
    text = forms.CharField(widget=TranslationTextarea(), required=False,
                           label=_(u'Provide the text of your license.'))

    def __init__(self, *args, **kwargs):
        self.version = kwargs.pop('version', None)
        if self.version:
            kwargs['instance'], kwargs['initial'] = self.version.license, None
            # Clear out initial data if it's a builtin license.
            if getattr(kwargs['instance'], 'builtin', None):
                kwargs['initial'] = {'builtin': kwargs['instance'].builtin}
                kwargs['instance'] = None
            self.cc_licenses = kwargs.pop(
                'cc', self.version.addon.type == amo.ADDON_STATICTHEME)
        else:
            self.cc_licenses = kwargs.pop(
                'cc', False)

        super(LicenseForm, self).__init__(*args, **kwargs)
        licenses = License.objects.builtins(
            cc=self.cc_licenses).filter(on_form=True)
        cs = [(x.builtin, x) for x in licenses]
        if not self.cc_licenses:
            # creative commons licenses don't have an 'other' option.
            cs.append((License.OTHER, ugettext('Other')))
        self.fields['builtin'].choices = cs
        if (self.version and
                self.version.channel == amo.RELEASE_CHANNEL_UNLISTED):
            self.fields['builtin'].required = False

    class Meta:
        model = License
        fields = ('builtin', 'name', 'text')

    def clean_name(self):
        name = self.cleaned_data['name']
        return name.strip() or ugettext('Custom License')

    def clean(self):
        data = self.cleaned_data
        if self.errors:
            return data
        elif data['builtin'] == License.OTHER and not data['text']:
            raise forms.ValidationError(
                ugettext('License text is required when choosing Other.'))
        return data

    def get_context(self):
        """Returns a view context dict having keys license_form,
        and license_other_val.
        """
        return {
            'version': self.version,
            'license_form': self.version and self,
            'license_other_val': License.OTHER
        }

    def save(self, *args, **kw):
        """Save all form data.

        This will only create a new license if it's not one of the builtin
        ones.

        Keyword arguments

        **log=True**
            Set to False if you do not want to log this action for display
            on the developer dashboard.
        """
        log = kw.pop('log', True)
        changed = self.changed_data

        builtin = self.cleaned_data['builtin']
        if builtin == '':  # No license chosen, it must be an unlisted add-on.
            return
        if builtin != License.OTHER:
            # We're dealing with a builtin license, there is no modifications
            # allowed to it, just return it.
            license = License.objects.get(builtin=builtin)
        else:
            # We're not dealing with a builtin license, so save it to the
            # database.
            license = super(LicenseForm, self).save(*args, **kw)

        if self.version:
            if changed or license != self.version.license:
                self.version.update(license=license)
                if log:
                    ActivityLog.create(amo.LOG.CHANGE_LICENSE, license,
                                       self.version.addon)
        return license
Ejemplo n.º 5
0
class CollectionForm(happyforms.ModelForm):

    name = forms.CharField(label=_(u'Give your collection a name.'),
                           widget=TranslationTextInput)
    slug = forms.CharField(label=_(u'URL:'))
    description = forms.CharField(
        label=_(u'Describe your collection (no links allowed).'),
        widget=TranslationTextarea(attrs={'rows': 3}),
        max_length=200,
        required=False)
    listed = forms.ChoiceField(label=_(u'Privacy:'),
                               widget=forms.RadioSelect,
                               choices=privacy_choices,
                               initial=True)

    icon = forms.FileField(label=_(u'Icon'), required=False)

    # This is just a honeypot field for bots to get caught
    # L10n: bots is short for robots
    your_name = forms.CharField(
        label=_(u"Please don't fill out this field, it's used to catch bots"),
        required=False)

    def __init__(self, *args, **kw):
        super(CollectionForm, self).__init__(*args, **kw)
        # You can't edit the slugs for the special types.
        if (self.instance
                and self.instance.type in amo.COLLECTION_SPECIAL_SLUGS):
            del self.fields['slug']

    def clean(self):
        # Check the honeypot here instead of 'clean_your_name' so the
        # error message appears at the top of the form in the __all__ section
        if self.cleaned_data['your_name']:
            statsd.incr('collections.honeypotted')
            log.info('Bot trapped in honeypot at collections.create')
            raise forms.ValidationError(
                "You've been flagged as spam, sorry about that.")
        return super(CollectionForm, self).clean()

    def clean_name(self):
        name = self.cleaned_data['name']
        if DeniedName.blocked(name):
            raise forms.ValidationError(ugettext('This name cannot be used.'))
        return name

    def clean_description(self):
        description = self.cleaned_data['description']
        normalized = clean_nl(description)
        if has_links(normalized):
            # There's some links, we don't want them.
            raise forms.ValidationError(ugettext('No links are allowed.'))
        return description

    def clean_slug(self):
        slug = slugify(self.cleaned_data['slug'])
        slug_validator(slug)
        if self.instance and self.instance.slug == slug:
            return slug

        author = self.initial['author']
        if author.collections.filter(slug=slug).count():
            raise forms.ValidationError(
                ugettext('This url is already in use by another collection'))

        return slug

    def clean_icon(self):
        icon = self.cleaned_data['icon']
        if not icon:
            return
        if icon.content_type not in ('image/png', 'image/jpeg'):
            raise forms.ValidationError(
                ugettext('Icons must be either PNG or JPG.'))

        if icon.size > settings.MAX_ICON_UPLOAD_SIZE:
            size_in_mb = settings.MAX_ICON_UPLOAD_SIZE / 1024 / 1024 - 1
            raise forms.ValidationError(
                ugettext('Please use images smaller than %dMB.') % size_in_mb)
        return icon

    def save(self, default_locale=None):
        c = super(CollectionForm, self).save(commit=False)
        c.author = self.initial['author']
        c.application = self.initial['application']
        icon = self.cleaned_data.get('icon')

        if default_locale:
            c.default_locale = default_locale

        if icon:
            c.icontype = 'image/png'

        c.save()

        if icon:
            dirname = c.get_img_dir()

            destination = os.path.join(dirname, '%d.png' % c.id)
            tmp_destination = os.path.join(dirname,
                                           '%d.png__unconverted' % c.id)
            with storage.open(tmp_destination, 'w') as fh:
                for chunk in icon.chunks():
                    fh.write(chunk)
            tasks.resize_icon.delay(tmp_destination,
                                    destination,
                                    set_modified_on=[c])

        return c

    class Meta:
        model = Collection
        fields = ('name', 'slug', 'description', 'listed')
Ejemplo n.º 6
0
class LicenseForm(AMOModelForm):
    builtin = forms.TypedChoiceField(
        choices=[], coerce=int,
        widget=LicenseRadioSelect(attrs={'class': 'license'}))
    name = forms.CharField(widget=TranslationTextInput(),
                           label=_lazy(u"What is your license's name?"),
                           required=False, initial=_lazy('Custom License'))
    text = forms.CharField(widget=TranslationTextarea(), required=False,
                           label=_lazy(u'Provide the text of your license.'))

    def __init__(self, *args, **kw):
        addon = kw.pop('addon', None)
        self.version = None
        if addon:
            self.version = addon.latest_version
            if self.version:
                kw['instance'], kw['initial'] = self.version.license, None
                # Clear out initial data if it's a builtin license.
                if getattr(kw['instance'], 'builtin', None):
                    kw['initial'] = {'builtin': kw['instance'].builtin}
                    kw['instance'] = None

        super(LicenseForm, self).__init__(*args, **kw)

        cs = [(x.builtin, x)
              for x in License.objects.builtins().filter(on_form=True)]
        cs.append((License.OTHER, _('Other')))
        self.fields['builtin'].choices = cs
        if addon and not addon.is_listed:
            self.fields['builtin'].required = False

    class Meta:
        model = License
        fields = ('builtin', 'name', 'text')

    def clean_name(self):
        name = self.cleaned_data['name']
        return name.strip() or _('Custom License')

    def clean(self):
        data = self.cleaned_data
        if self.errors:
            return data
        elif data['builtin'] == License.OTHER and not data['text']:
            raise forms.ValidationError(
                _('License text is required when choosing Other.'))
        return data

    def get_context(self):
        """Returns a view context dict having keys license_urls, license_form,
        and license_other_val.
        """
        license_urls = dict(License.objects.builtins()
                            .values_list('builtin', 'url'))
        return dict(license_urls=license_urls, version=self.version,
                    license_form=self.version and self,
                    license_other_val=License.OTHER)

    def save(self, *args, **kw):
        """Save all form data.

        This will only create a new license if it's not one of the builtin
        ones.

        Keyword arguments

        **log=True**
            Set to False if you do not want to log this action for display
            on the developer dashboard.
        """
        log = kw.pop('log', True)
        changed = self.changed_data

        builtin = self.cleaned_data['builtin']
        if builtin == '':  # No license chosen, it must be an unlisted add-on.
            return
        if builtin != License.OTHER:
            license = License.objects.get(builtin=builtin)
        else:
            # Save the custom license:
            license = super(LicenseForm, self).save(*args, **kw)

        if self.version:
            if changed or license != self.version.license:
                self.version.update(license=license)
                if log:
                    amo.log(amo.LOG.CHANGE_LICENSE, license,
                            self.version.addon)
        return license
Ejemplo n.º 7
0
class CollectionForm(forms.ModelForm):

    name = forms.CharField(label=_(u'Give your collection a name.'),
                           widget=TranslationTextInput)
    slug = forms.CharField(label=_(u'URL:'))
    description = forms.CharField(
        label=_(u'Describe your collection (no links allowed).'),
        widget=TranslationTextarea(attrs={'rows': 3}),
        max_length=200,
        required=False)
    listed = forms.ChoiceField(label=_(u'Privacy:'),
                               widget=forms.RadioSelect,
                               choices=privacy_choices,
                               initial=True)

    # This is just a honeypot field for bots to get caught
    # L10n: bots is short for robots
    your_name = forms.CharField(
        label=_(u"Please don't fill out this field, it's used to catch bots"),
        required=False)

    def __init__(self, *args, **kw):
        super(CollectionForm, self).__init__(*args, **kw)
        # You can't edit the slugs for the special types.
        if (self.instance
                and self.instance.type in amo.COLLECTION_SPECIAL_SLUGS):
            del self.fields['slug']

    def clean(self):
        # Check the honeypot here instead of 'clean_your_name' so the
        # error message appears at the top of the form in the __all__ section
        if self.cleaned_data['your_name']:
            statsd.incr('collections.honeypotted')
            log.info('Bot trapped in honeypot at collections.create')
            raise forms.ValidationError(
                "You've been flagged as spam, sorry about that.")
        return super(CollectionForm, self).clean()

    def clean_name(self):
        name = self.cleaned_data['name']
        if DeniedName.blocked(name):
            raise forms.ValidationError(ugettext('This name cannot be used.'))
        return name

    def clean_description(self):
        description = self.cleaned_data['description']
        normalized = clean_nl(description)
        if has_links(normalized):
            # There's some links, we don't want them.
            raise forms.ValidationError(ugettext('No links are allowed.'))
        return description

    def clean_slug(self):
        slug = slugify(self.cleaned_data['slug'])
        slug_validator(slug)
        if self.instance and self.instance.slug == slug:
            return slug

        author = self.initial['author']
        if author.collections.filter(slug=slug).count():
            raise forms.ValidationError(
                ugettext('This url is already in use by another collection'))

        return slug

    def save(self, default_locale=None):
        collection = super(CollectionForm, self).save(commit=False)
        collection.author = self.initial['author']
        collection.application = self.initial['application']

        if default_locale:
            collection.default_locale = default_locale

        collection.save()

        return collection

    class Meta:
        model = Collection
        fields = ('name', 'slug', 'description', 'listed')