Пример #1
0
    class _Form(TranslationFormMixin, happyforms.ModelForm):
        the_reason = TransField(widget=TransTextarea(),
                                required=fields_required,
                                label=the_reason_label)
        the_future = TransField(widget=TransTextarea(),
                                required=fields_required,
                                label=the_future_label)

        class Meta:
            model = Addon
            fields = ('the_reason', 'the_future')
Пример #2
0
class AddonFormBasicUnlisted(AkismetSpamCheckFormMixin, AddonFormBase):
    name = TransField(max_length=50)
    slug = forms.CharField(max_length=30)
    summary = TransField(widget=TransTextarea(attrs={'rows': 4}),
                         max_length=250)

    fields_to_akismet_comment_check = ['name', 'summary']

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary')
Пример #3
0
class AddonFormBasic(AddonFormBase):
    name = TransField(max_length=50)
    slug = forms.CharField(max_length=30)
    summary = TransField(widget=TransTextarea(attrs={'rows': 4}),
                         max_length=250)
    tags = forms.CharField(required=False)
    contributions = HttpHttpsOnlyURLField(required=False, max_length=255)
    is_experimental = forms.BooleanField(required=False)
    requires_payment = forms.BooleanField(required=False)

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'tags', 'is_experimental',
                  'requires_payment', 'contributions')

    def __init__(self, *args, **kw):
        super(AddonFormBasic, self).__init__(*args, **kw)

        if self.fields.get('tags'):
            self.fields['tags'].initial = ', '.join(
                self.get_tags(self.instance))

    def clean_slug(self):
        return clean_addon_slug(self.cleaned_data['slug'], self.instance)

    def clean_contributions(self):
        if self.cleaned_data['contributions']:
            hostname = urlsplit(self.cleaned_data['contributions']).hostname
            if not hostname.endswith(amo.VALID_CONTRIBUTION_DOMAINS):
                raise forms.ValidationError(
                    ugettext('URL domain must be one of [%s], or a subdomain.')
                    % ', '.join(amo.VALID_CONTRIBUTION_DOMAINS))
        return self.cleaned_data['contributions']

    def save(self, addon, commit=False):
        if self.fields.get('tags'):
            tags_new = self.cleaned_data['tags']
            tags_old = [slugify(t, spaces=True) for t in self.get_tags(addon)]

            # Add new tags.
            for t in set(tags_new) - set(tags_old):
                Tag(tag_text=t).save_tag(addon)

            # Remove old tags.
            for t in set(tags_old) - set(tags_new):
                Tag(tag_text=t).remove_tag(addon)

        # We ignore `commit`, since we need it to be `False` so we can save
        # the ManyToMany fields on our own.
        addonform = super(AddonFormBasic, self).save(commit=False)
        addonform.save()

        return addonform
Пример #4
0
class DescribeFormUnlisted(AkismetSpamCheckFormMixin, AddonFormBase):
    name = TransField(max_length=50)
    slug = forms.CharField(max_length=30)
    summary = TransField(widget=TransTextarea(attrs={'rows': 4}),
                         max_length=250)
    description = TransField(widget=TransTextarea(attrs={'rows': 4}),
                             required=False)

    fields_to_akismet_comment_check = ['name', 'summary', 'description']

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'description')
Пример #5
0
class AddonFormSupport(AddonFormBase):
    support_url = TransField.adapt(HttpHttpsOnlyURLField)(required=False)
    support_email = TransField.adapt(forms.EmailField)(required=False)

    class Meta:
        model = Addon
        fields = ('support_email', 'support_url')

    def __init__(self, *args, **kw):
        super(AddonFormSupport, self).__init__(*args, **kw)

    def save(self, addon, commit=True):
        return super(AddonFormSupport, self).save(commit)
Пример #6
0
class Step3Form(AddonFormBasic):
    description = TransField(widget=TransTextarea, required=False)
    tags = None

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'description')
Пример #7
0
class AddonFormDetails(AddonFormBase):
    default_locale = forms.TypedChoiceField(choices=LOCALES)
    homepage = TransField.adapt(HttpHttpsOnlyURLField)(required=False)

    class Meta:
        model = Addon
        fields = ('description', 'default_locale', 'homepage')

    def clean(self):
        # Make sure we have the required translations in the new locale.
        required = 'name', 'summary', 'description'
        data = self.cleaned_data
        if not self.errors and 'default_locale' in self.changed_data:
            fields = dict((k, getattr(self.instance, k + '_id'))
                          for k in required)
            locale = self.cleaned_data['default_locale']
            ids = filter(None, fields.values())
            qs = (Translation.objects.filter(locale=locale, id__in=ids,
                                             localized_string__isnull=False)
                  .values_list('id', flat=True))
            missing = [k for k, v in fields.items() if v not in qs]
            # They might be setting description right now.
            if 'description' in missing and locale in data['description']:
                missing.remove('description')
            if missing:
                raise forms.ValidationError(ugettext(
                    'Before changing your default locale you must have a '
                    'name, summary, and description in that locale. '
                    'You are missing %s.') % ', '.join(map(repr, missing)))
        return data
Пример #8
0
class Step3Form(AddonFormBasic):
    description = TransField(widget=TransTextarea, required=False)

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'tags', 'description', 'homepage',
                  'support_email', 'support_url')
Пример #9
0
class AddonFormTechnical(AddonFormBase):
    developer_comments = TransField(widget=TransTextarea, required=False)

    class Meta:
        model = Addon
        fields = ('developer_comments', 'view_source', 'external_software',
                  'auto_repackage', 'public_stats')
Пример #10
0
class PreviewForm(happyforms.ModelForm):
    caption = TransField(widget=TransTextarea, required=False)
    file_upload = forms.FileField(required=False)
    upload_hash = forms.CharField(required=False)

    def save(self, addon, commit=True):
        if self.cleaned_data:
            self.instance.addon = addon
            if self.cleaned_data.get('DELETE'):
                # Existing preview.
                if self.instance.id:
                    self.instance.delete()
                # User has no desire to save this preview.
                return

            super(PreviewForm, self).save(commit=commit)
            if self.cleaned_data['upload_hash']:
                upload_hash = self.cleaned_data['upload_hash']
                upload_path = os.path.join(settings.TMP_PATH, 'preview',
                                           upload_hash)
                tasks.resize_preview.delay(upload_path, self.instance,
                                           set_modified_on=[self.instance])

    class Meta:
        model = Preview
        fields = ('caption', 'file_upload', 'upload_hash', 'id', 'position')
Пример #11
0
class AddonFormBasic(AddonFormBase):
    name = TransField(max_length=50)
    slug = forms.CharField(max_length=30)
    summary = TransField(widget=TransTextarea(attrs={'rows': 4}),
                         max_length=250)
    tags = forms.CharField(required=False)

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'tags')

    def __init__(self, *args, **kw):
        super(AddonFormBasic, self).__init__(*args, **kw)

        if self.fields.get('tags'):
            self.fields['tags'].initial = ', '.join(
                self.get_tags(self.instance))

        # Do not simply append validators, as validators will persist between
        # instances.
        def validate_name(name):
            return clean_addon_name(name, self.instance)

        name_validators = list(self.fields['name'].validators)
        name_validators.append(validate_name)
        self.fields['name'].validators = name_validators

    def save(self, addon, commit=False):

        if self.fields.get('tags'):
            tags_new = self.cleaned_data['tags']
            tags_old = [slugify(t, spaces=True) for t in self.get_tags(addon)]

            # Add new tags.
            for t in set(tags_new) - set(tags_old):
                Tag(tag_text=t).save_tag(addon)

            # Remove old tags.
            for t in set(tags_old) - set(tags_new):
                Tag(tag_text=t).remove_tag(addon)

        # We ignore `commit`, since we need it to be `False` so we can save
        # the ManyToMany fields on our own.
        addonform = super(AddonFormBasic, self).save(commit=False)
        addonform.save()

        return addonform
Пример #12
0
class PolicyForm(TranslationFormMixin, AMOModelForm):
    """Form for editing the add-ons EULA and privacy policy."""
    has_eula = forms.BooleanField(
        required=False,
        label=_lazy(u'This add-on has an End-User License Agreement'))
    eula = TransField(widget=TransTextarea(),
                      required=False,
                      label=_lazy(u"Please specify your add-on's "
                                  "End-User License Agreement:"))
    has_priv = forms.BooleanField(
        required=False,
        label=_lazy(u"This add-on has a Privacy Policy"),
        label_suffix='')
    privacy_policy = TransField(
        widget=TransTextarea(),
        required=False,
        label=_lazy(u"Please specify your add-on's Privacy Policy:"))

    def __init__(self, *args, **kw):
        self.addon = kw.pop('addon', None)
        if not self.addon:
            raise ValueError('addon keyword arg cannot be None')
        kw['instance'] = self.addon
        kw['initial'] = dict(has_priv=self._has_field('privacy_policy'),
                             has_eula=self._has_field('eula'))
        super(PolicyForm, self).__init__(*args, **kw)

    def _has_field(self, name):
        # If there's a eula in any language, this addon has a eula.
        n = getattr(self.addon, u'%s_id' % name)
        return any(map(bool, Translation.objects.filter(id=n)))

    class Meta:
        model = Addon
        fields = ('eula', 'privacy_policy')

    def save(self, commit=True):
        ob = super(PolicyForm, self).save(commit)
        for k, field in (('has_eula', 'eula'), ('has_priv', 'privacy_policy')):
            if not self.cleaned_data[k]:
                delete_translation(self.instance, field)

        if 'privacy_policy' in self.changed_data:
            ActivityLog.create(amo.LOG.CHANGE_POLICY, self.addon,
                               self.instance)

        return ob
Пример #13
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')
Пример #14
0
class AddonFormBasic(AddonFormBase):
    name = TransField(max_length=50)
    slug = forms.CharField(max_length=30)
    summary = TransField(widget=TransTextarea(attrs={'rows': 4}),
                         max_length=250)
    tags = forms.CharField(required=False)
    is_experimental = forms.BooleanField(required=False)

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'tags', 'is_experimental')

    def __init__(self, *args, **kw):
        super(AddonFormBasic, self).__init__(*args, **kw)

        if self.fields.get('tags'):
            self.fields['tags'].initial = ', '.join(
                self.get_tags(self.instance))

    def clean_name(self):
        return clean_addon_name(self.cleaned_data['name'], self.instance)

    def clean_slug(self):
        return clean_addon_slug(self.cleaned_data['slug'], self.instance)

    def save(self, addon, commit=False):
        if self.fields.get('tags'):
            tags_new = self.cleaned_data['tags']
            tags_old = [slugify(t, spaces=True) for t in self.get_tags(addon)]

            # Add new tags.
            for t in set(tags_new) - set(tags_old):
                Tag(tag_text=t).save_tag(addon)

            # Remove old tags.
            for t in set(tags_old) - set(tags_new):
                Tag(tag_text=t).remove_tag(addon)

        # We ignore `commit`, since we need it to be `False` so we can save
        # the ManyToMany fields on our own.
        addonform = super(AddonFormBasic, self).save(commit=False)
        addonform.save()

        return addonform
Пример #15
0
class DescribeForm(AddonFormBase):
    name = TransField(max_length=50)
    slug = forms.CharField(max_length=30)
    summary = TransField(widget=TransTextarea(attrs={'rows': 4}),
                         max_length=250)
    is_experimental = forms.BooleanField(required=False)
    support_url = TransField.adapt(HttpHttpsOnlyURLField)(required=False)
    support_email = TransField.adapt(forms.EmailField)(required=False)
    has_priv = forms.BooleanField(
        required=False,
        label=_lazy(u"This add-on has a Privacy Policy"),
        label_suffix='')
    privacy_policy = TransField(
        widget=TransTextarea(),
        required=False,
        label=_lazy(u"Please specify your add-on's Privacy Policy:"))

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'is_experimental', 'support_url',
                  'support_email', 'privacy_policy')

    def __init__(self, *args, **kw):
        kw['initial'] = {
            'has_priv': self._has_field('privacy_policy', kw['instance'])
        }
        super(DescribeForm, self).__init__(*args, **kw)

    def clean_name(self):
        return clean_addon_name(self.cleaned_data['name'], self.instance)

    def _has_field(self, name, instance=None):
        # If there's a policy in any language, this addon has a policy.
        n = getattr(instance or self.instance, u'%s_id' % name)
        return any(map(bool, Translation.objects.filter(id=n)))

    def save(self, commit=True):
        obj = super(DescribeForm, self).save(commit)
        if not self.cleaned_data['has_priv']:
            delete_translation(self.instance, 'privacy_policy')

        return obj
Пример #16
0
class DescribeForm(AkismetSpamCheckFormMixin, AddonFormBase):
    name = TransField(max_length=50)
    slug = forms.CharField(max_length=30)
    summary = TransField(widget=TransTextarea(attrs={'rows': 4}),
                         max_length=250)
    description = TransField(widget=TransTextarea(attrs={'rows': 6}),
                             min_length=10)
    is_experimental = forms.BooleanField(required=False)
    requires_payment = forms.BooleanField(required=False)
    support_url = TransField.adapt(HttpHttpsOnlyURLField)(required=False)
    support_email = TransField.adapt(forms.EmailField)(required=False)
    has_priv = forms.BooleanField(required=False,
                                  label=_(u'This add-on has a Privacy Policy'),
                                  label_suffix='')
    privacy_policy = TransField(
        widget=TransTextarea(),
        required=False,
        label=_(u'Please specify your add-on\'s Privacy Policy:'))

    fields_to_akismet_comment_check = ['name', 'summary', 'description']

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'summary', 'description', 'is_experimental',
                  'support_url', 'support_email', 'privacy_policy',
                  'requires_payment')

    def __init__(self, *args, **kw):
        kw['initial'] = {
            'has_priv': self._has_field('privacy_policy', kw['instance'])
        }
        super(DescribeForm, self).__init__(*args, **kw)
        content_waffle = waffle.switch_is_active('content-optimization')
        if not content_waffle or self.instance.type != amo.ADDON_EXTENSION:
            description = self.fields['description']
            description.min_length = None
            description.widget.attrs.pop('minlength', None)
            description.validators = [
                validator for validator in description.validators
                if not isinstance(validator, MinLengthValidator)
            ]
            description.required = False

    def _has_field(self, name, instance=None):
        # If there's a policy in any language, this addon has a policy.
        n = getattr(instance or self.instance, u'%s_id' % name)
        return any(map(bool, Translation.objects.filter(id=n)))

    def save(self, commit=True):
        obj = super(DescribeForm, self).save(commit)
        if not self.cleaned_data['has_priv']:
            delete_translation(self.instance, 'privacy_policy')

        return obj
Пример #17
0
class ContribForm(TranslationFormMixin, happyforms.ModelForm):
    RECIPIENTS = (('dev', _(u'The developers of this add-on')),
                  ('moz', _(u'The Mozilla Foundation')),
                  ('org', _(u'An organization of my choice')))

    recipient = forms.ChoiceField(
        choices=RECIPIENTS,
        widget=forms.RadioSelect(attrs={'class': 'recipient'}))
    thankyou_note = TransField(widget=TransTextarea(), required=False)

    class Meta:
        model = Addon
        fields = ('paypal_id', 'suggested_amount', 'annoying',
                  'enable_thankyou', 'thankyou_note')
        widgets = {
            'annoying': forms.RadioSelect(),
            'suggested_amount': forms.TextInput(attrs={'class': 'short'}),
            'paypal_id': forms.TextInput(attrs={'size': '50'})
        }

    @staticmethod
    def initial(addon):
        if addon.charity:
            recip = 'moz' if addon.charity_id == amo.FOUNDATION_ORG else 'org'
        else:
            recip = 'dev'
        return {
            'recipient': recip,
            'annoying': addon.annoying or amo.CONTRIB_PASSIVE
        }

    def clean(self):
        data = self.cleaned_data
        try:
            if not self.errors and data['recipient'] == 'dev':
                check_paypal_id(data['paypal_id'])
        except forms.ValidationError, e:
            self.errors['paypal_id'] = self.error_class(e.messages)
        # thankyou_note is a dict since it's a Translation.
        if not (data.get('enable_thankyou')
                and any(data.get('thankyou_note').values())):
            data['thankyou_note'] = {}
            data['enable_thankyou'] = False
        return data
Пример #18
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)
Пример #19
0
class AdditionalDetailsForm(AddonFormBase):
    default_locale = forms.TypedChoiceField(choices=LOCALES)
    homepage = TransField.adapt(HttpHttpsOnlyURLField)(required=False)
    tags = forms.CharField(required=False)
    contributions = HttpHttpsOnlyURLField(required=False, max_length=255)

    class Meta:
        model = Addon
        fields = ('default_locale', 'homepage', 'tags', 'contributions')

    def __init__(self, *args, **kw):
        super(AdditionalDetailsForm, self).__init__(*args, **kw)

        if self.fields.get('tags'):
            self.fields['tags'].initial = ', '.join(
                self.get_tags(self.instance))

    def clean_contributions(self):
        if self.cleaned_data['contributions']:
            hostname = urlsplit(self.cleaned_data['contributions']).hostname
            if not hostname.endswith(amo.VALID_CONTRIBUTION_DOMAINS):
                raise forms.ValidationError(ugettext(
                    'URL domain must be one of [%s], or a subdomain.'
                ) % ', '.join(amo.VALID_CONTRIBUTION_DOMAINS))
        return self.cleaned_data['contributions']

    def clean(self):
        # Make sure we have the required translations in the new locale.
        required = 'name', 'summary', 'description'
        if not self.errors and 'default_locale' in self.changed_data:
            fields = dict((k, getattr(self.instance, k + '_id'))
                          for k in required)
            locale = self.cleaned_data['default_locale']
            ids = filter(None, fields.values())
            qs = (Translation.objects.filter(locale=locale, id__in=ids,
                                             localized_string__isnull=False)
                  .values_list('id', flat=True))
            missing = [k for k, v in fields.items() if v not in qs]
            if missing:
                raise forms.ValidationError(ugettext(
                    'Before changing your default locale you must have a '
                    'name, summary, and description in that locale. '
                    'You are missing %s.') % ', '.join(map(repr, missing)))
        return super(AdditionalDetailsForm, self).clean()

    def save(self, addon, commit=False):
        if self.fields.get('tags'):
            tags_new = self.cleaned_data['tags']
            tags_old = [slugify(t, spaces=True) for t in self.get_tags(addon)]

            # Add new tags.
            for t in set(tags_new) - set(tags_old):
                Tag(tag_text=t).save_tag(addon)

            # Remove old tags.
            for t in set(tags_old) - set(tags_new):
                Tag(tag_text=t).remove_tag(addon)

        # We ignore `commit`, since we need it to be `False` so we can save
        # the ManyToMany fields on our own.
        addonform = super(AdditionalDetailsForm, self).save(commit=False)
        addonform.save()

        return addonform
Пример #20
0
class EditThemeForm(AddonFormBase):
    name = TransField(max_length=50, label=_('Give Your Theme a Name.'))
    slug = forms.CharField(max_length=30)
    category = forms.ModelChoiceField(queryset=Category.objects.all(),
                                      widget=forms.widgets.RadioSelect)
    description = TransField(
        widget=TransTextarea(attrs={'rows': 4}),
        max_length=500, required=False, label=_('Describe your Theme.'))
    tags = forms.CharField(required=False)
    accentcolor = ColorField(
        required=False,
        widget=forms.TextInput(attrs={'class': 'color-picker'}),
    )
    textcolor = ColorField(
        required=False,
        widget=forms.TextInput(attrs={'class': 'color-picker'}),
    )
    license = forms.TypedChoiceField(
        choices=amo.PERSONA_LICENSES_CHOICES, coerce=int, empty_value=None,
        widget=forms.HiddenInput,
        error_messages={'required': _(u'A license must be selected.')})

    # Theme re-upload.
    header = forms.FileField(required=False)
    header_hash = forms.CharField(widget=forms.HiddenInput, required=False)

    class Meta:
        model = Addon
        fields = ('name', 'slug', 'description', 'tags')

    def __init__(self, *args, **kw):
        self.request = kw.pop('request')

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

        addon = Addon.objects.no_cache().get(id=self.instance.id)
        persona = addon.persona

        # Allow theme artists to localize Name and Description.
        for trans in Translation.objects.filter(id=self.initial['name']):
            self.initial['name_' + trans.locale.lower()] = trans
        for trans in Translation.objects.filter(
                id=self.initial['description']):
            self.initial['description_' + trans.locale.lower()] = trans

        self.old_tags = self.get_tags(addon)
        self.initial['tags'] = ', '.join(self.old_tags)
        if persona.accentcolor:
            self.initial['accentcolor'] = '#' + persona.accentcolor
        if persona.textcolor:
            self.initial['textcolor'] = '#' + persona.textcolor
        self.initial['license'] = persona.license

        cats = sorted(Category.objects.filter(type=amo.ADDON_PERSONA,
                                              weight__gte=0),
                      key=lambda x: x.name)
        self.fields['category'].choices = [(c.id, c.name) for c in cats]
        try:
            self.initial['category'] = addon.categories.values_list(
                'id', flat=True)[0]
        except IndexError:
            pass

        for field in ('header', ):
            self.fields[field].widget.attrs = {
                'data-upload-url': reverse('devhub.personas.reupload_persona',
                                           args=[addon.slug,
                                                 'persona_%s' % field]),
                'data-allowed-types': amo.SUPPORTED_IMAGE_TYPES
            }

    def clean_slug(self):
        return clean_addon_slug(self.cleaned_data['slug'], self.instance)

    def save(self):
        addon = self.instance
        persona = addon.persona
        data = self.cleaned_data

        # Update Persona-specific data.
        persona_data = {
            'license': int(data['license']),
            'accentcolor': data['accentcolor'].lstrip('#'),
            'textcolor': data['textcolor'].lstrip('#'),
            'author': self.request.user.username,
            'display_username': self.request.user.name
        }
        changed = False
        for k, v in persona_data.iteritems():
            if v != getattr(persona, k):
                changed = True
                setattr(persona, k, v)
        if changed:
            persona.save()

        if self.changed_data:
            ActivityLog.create(amo.LOG.EDIT_PROPERTIES, addon)
        self.instance.modified = datetime.now()

        # Update Addon-specific data.
        changed = (
            set(self.old_tags) != data['tags'] or  # Check if tags changed.
            self.initial['slug'] != data['slug'] or  # Check if slug changed.
            transfield_changed('description', self.initial, data) or
            transfield_changed('name', self.initial, data))
        if changed:
            # Only save if addon data changed.
            super(EditThemeForm, self).save()

        # Update tags.
        tags_new = data['tags']
        tags_old = [slugify(t, spaces=True) for t in self.old_tags]
        # Add new tags.
        for t in set(tags_new) - set(tags_old):
            Tag(tag_text=t).save_tag(addon)
        # Remove old tags.
        for t in set(tags_old) - set(tags_new):
            Tag(tag_text=t).remove_tag(addon)

        # Update category.
        if data['category'].id != self.initial['category']:
            addon_cat = addon.addoncategory_set.all()[0]
            addon_cat.category = data['category']
            addon_cat.save()

        # Theme reupload.
        if not addon.is_pending():
            if data['header_hash']:
                save_theme_reupload.delay(data['header_hash'], addon.pk)

        return data
Пример #21
0
class AppFormBasic(AddonFormBasic):
    """Form to override name length for apps."""
    name = TransField(max_length=128)
Пример #22
0
class DescribeFormContentOptimization(CombinedNameSummaryCleanMixin,
                                      DescribeForm):
    name = TransField(min_length=2)
    summary = TransField(min_length=2)
Пример #23
0
class AddonFormDetailsUnlisted(AddonFormBase):
    homepage = TransField.adapt(HttpHttpsOnlyURLField)(required=False)

    class Meta:
        model = Addon
        fields = ('description', 'homepage')
Пример #24
0
class DescribeFormUnlistedContentOptimization(CombinedNameSummaryCleanMixin,
                                              DescribeFormUnlisted):
    name = TransField(max_length=68, min_length=2)
    summary = TransField(max_length=68, min_length=2)