Example #1
0
class EditThemeForm(AddonFormBase):
    name = TransField(max_length=50, label=_lazy('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=_lazy('Describe your Theme.'))
    tags = forms.CharField(required=False)
    accentcolor = ColorField(required=False)
    textcolor = ColorField(required=False)
    license = forms.TypedChoiceField(
        choices=amo.PERSONA_LICENSES_CHOICES,
        coerce=int,
        empty_value=None,
        widget=forms.HiddenInput,
        error_messages={'required': _lazy(u'A license must be selected.')})

    # Theme re-upload.
    header = forms.FileField(required=False)
    header_hash = forms.CharField(widget=forms.HiddenInput, required=False)
    footer = forms.FileField(required=False)
    footer_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

        # Do not simply append validators, as validators will persist between
        # instances.
        self.fields['name'].validators = list(self.fields['name'].validators)
        self.fields['name'].validators.append(lambda x: clean_name(x, addon))

        # 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', 'footer'):
            self.fields[field].widget.attrs = {
                'data-upload-url':
                reverse('devhub.personas.reupload_persona',
                        args=[addon.slug, 'persona_%s' % field]),
                'data-allowed-types':
                'image/jpeg|image/png'
            }

    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.amo_user.username,
            'display_username': self.request.amo_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:
            amo.log(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'] or data['footer_hash']:
                save_theme_reupload.delay(data['header_hash'],
                                          data['footer_hash'], addon)

        return data
Example #2
0
class ThemeForm(ThemeFormBase):
    name = forms.CharField(max_length=50)
    slug = forms.CharField(max_length=30)
    category = forms.ModelChoiceField(queryset=Category.objects.all(),
                                      widget=forms.widgets.RadioSelect)
    description = forms.CharField(widget=forms.Textarea(attrs={'rows': 4}),
                                  max_length=500,
                                  required=False)
    tags = forms.CharField(required=False)

    license = forms.TypedChoiceField(
        choices=amo.PERSONA_LICENSES_CHOICES,
        coerce=int,
        empty_value=None,
        widget=forms.HiddenInput,
        error_messages={'required': _lazy(u'A license must be selected.')})
    header = forms.FileField(required=False)
    header_hash = forms.CharField(widget=forms.HiddenInput)
    footer = forms.FileField(required=False)
    footer_hash = forms.CharField(widget=forms.HiddenInput)
    accentcolor = ColorField(required=False)
    textcolor = ColorField(required=False)
    agreed = forms.BooleanField()
    # This lets us POST the data URIs of the unsaved previews so we can still
    # show them if there were form errors. It's really clever.
    unsaved_data = forms.CharField(required=False, widget=forms.HiddenInput)

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

    def save(self, commit=False):
        data = self.cleaned_data
        addon = Addon.objects.create(slug=data.get('slug'),
                                     status=amo.STATUS_PENDING,
                                     type=amo.ADDON_PERSONA)
        addon.name = {'en-US': data['name']}
        if data.get('description'):
            addon.description = data['description']
        addon._current_version = Version.objects.create(addon=addon,
                                                        version='0')
        addon.save()

        # Create Persona instance.
        p = Persona()
        p.persona_id = 0
        p.addon = addon
        p.header = 'header.png'
        p.footer = 'footer.png'
        if data['accentcolor']:
            p.accentcolor = data['accentcolor'].lstrip('#')
        if data['textcolor']:
            p.textcolor = data['textcolor'].lstrip('#')
        p.license = data['license']
        p.submit = datetime.now()
        user = self.request.amo_user
        p.author = user.username
        p.display_username = user.name
        p.save()

        # Save header, footer, and preview images.
        save_theme.delay(data['header_hash'], data['footer_hash'], addon)

        # Save user info.
        addon.addonuser_set.create(user=user, role=amo.AUTHOR_ROLE_OWNER)

        # Save tags.
        for t in data['tags']:
            Tag(tag_text=t).save_tag(addon)

        # Save categories.
        AddonCategory(addon=addon, category=data['category']).save()

        return addon
Example #3
0
class NewPersonaForm(AddonFormBase):
    name = forms.CharField(max_length=50)
    category = forms.ModelChoiceField(queryset=Category.objects.all(),
                                      widget=forms.widgets.RadioSelect)
    summary = forms.CharField(widget=forms.Textarea(attrs={'rows': 4}),
                              max_length=250,
                              required=False)
    tags = forms.CharField(required=False)

    license = forms.TypedChoiceField(
        choices=amo.PERSONA_LICENSES_IDS,
        coerce=int,
        empty_value=None,
        widget=forms.HiddenInput,
        error_messages={'required': _lazy(u'A license must be selected.')})
    header = forms.FileField(required=False)
    header_hash = forms.CharField(widget=forms.HiddenInput)
    footer = forms.FileField(required=False)
    footer_hash = forms.CharField(widget=forms.HiddenInput)
    accentcolor = ColorField(required=False)
    textcolor = ColorField(required=False)
    # This lets us POST the data URIs of the unsaved previews so we can still
    # show them if there were form errors. It's really clever.
    unsaved_data = forms.CharField(required=False, widget=forms.HiddenInput)

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

    def __init__(self, *args, **kwargs):
        super(NewPersonaForm, self).__init__(*args, **kwargs)
        cats = Category.objects.filter(application=amo.FIREFOX.id,
                                       type=amo.ADDON_PERSONA,
                                       weight__gte=0)
        cats = sorted(cats, key=lambda x: x.name)
        self.fields['category'].choices = [(c.id, c.name) for c in cats]
        self.fields['header'].widget.attrs['data-upload-url'] = reverse(
            'devhub.personas.upload_persona', args=['persona_header'])
        self.fields['footer'].widget.attrs['data-upload-url'] = reverse(
            'devhub.personas.upload_persona', args=['persona_footer'])

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

    def clean_tags(self):
        return clean_tags(self.request, self.cleaned_data['tags'])

    def save(self, commit=False):
        from .tasks import create_persona_preview_image, save_persona_image
        # We ignore `commit`, since we need it to be `False` so we can save
        # the ManyToMany fields on our own.
        addon = super(NewPersonaForm, self).save(commit=False)
        addon.status = amo.STATUS_UNREVIEWED
        addon.type = amo.ADDON_PERSONA
        addon.save()
        addon._current_version = Version.objects.create(addon=addon,
                                                        version='0')
        addon.save()
        amo.log(amo.LOG.CREATE_ADDON, addon)
        log.debug('New persona %r uploaded' % addon)

        data = self.cleaned_data

        header = data['header_hash']
        footer = data['footer_hash']

        header = os.path.join(settings.TMP_PATH, 'persona_header', header)
        footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer)
        dst = os.path.join(settings.PERSONAS_PATH, str(addon.id))

        # Save header, footer, and preview images.
        save_persona_image(src=header, dst=dst, img_basename='header.jpg')
        save_persona_image(src=footer, dst=dst, img_basename='footer.jpg')
        create_persona_preview_image(src=header,
                                     dst=dst,
                                     img_basename='preview.jpg',
                                     set_modified_on=[addon])

        # Save user info.
        user = self.request.amo_user
        AddonUser(addon=addon, user=user).save()

        p = Persona()
        p.persona_id = 0
        p.addon = addon
        p.header = 'header'
        p.footer = 'footer'
        if data['accentcolor']:
            p.accentcolor = data['accentcolor'].lstrip('#')
        if data['textcolor']:
            p.textcolor = data['textcolor'].lstrip('#')
        p.license_id = data['license']
        p.submit = datetime.now()
        p.author = user.name
        p.display_username = user.username
        p.save()

        # Save tags.
        for t in data['tags']:
            Tag(tag_text=t).save_tag(addon)

        # Save categories.
        tb_c = Category.objects.get(application=amo.THUNDERBIRD.id,
                                    name__id=data['category'].name_id)
        AddonCategory(addon=addon, category=data['category']).save()
        AddonCategory(addon=addon, category=tb_c).save()

        return addon
Example #4
0
class EditThemeForm(AddonFormBase):
    name = forms.CharField(max_length=50)
    slug = forms.CharField(max_length=30)
    category = forms.ModelChoiceField(queryset=Category.objects.all(),
                                      widget=forms.widgets.RadioSelect)
    summary = forms.CharField(widget=forms.Textarea(attrs={'rows': 4}),
                              max_length=250,
                              required=False)
    tags = forms.CharField(required=False)
    accentcolor = ColorField(required=False)
    textcolor = ColorField(required=False)
    license = forms.TypedChoiceField(
        choices=amo.PERSONA_LICENSES_CHOICES,
        coerce=int,
        empty_value=None,
        widget=forms.HiddenInput,
        error_messages={'required': _lazy(u'A license must be selected.')})

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

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

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

        addon = self.instance
        persona = addon.persona

        # Do not simply append validators, as validators will persist between
        # instances.
        self.fields['name'].validators = list(self.fields['name'].validators)
        self.fields['name'].validators.append(lambda x: clean_name(x, addon))

        # TODO: Allow theme artists to localize Name and Summary (bug 855617).
        self.initial['name'] = Translation.objects.get(locale='en-US',
                                                       id=self.initial['name'])

        self.initial['tags'] = ', '.join(self.get_tags(addon))
        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

    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('#'),
            'display_username': self.request.amo_user.username
        }
        changed = False
        for k, v in persona_data.iteritems():
            if v != getattr(persona, k):
                changed = True
                setattr(persona, k, v)
        if changed:
            persona.save()

        # Update name, slug, and summary.
        if self.changed_data:
            amo.log(amo.LOG.EDIT_PROPERTIES, addon)

        self.instance.modified = datetime.now()

        # Save the Addon object.
        super(EditThemeForm, self).save()

        tags_new = 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)

        # Update category.
        try:
            old_cat = (addon.addoncategory_set.exclude(
                category_id=data['category'].id))[0]
        except IndexError:
            # The category has remained unchanged.
            pass
        else:
            old_cat.category = data['category']
            old_cat.save()

        return data
Example #5
0
class ThemeForm(ThemeFormBase):
    name = forms.CharField(max_length=50)
    slug = forms.CharField(max_length=30)
    category = forms.ModelChoiceField(queryset=Category.objects.all(),
                                      widget=forms.widgets.RadioSelect)
    summary = forms.CharField(widget=forms.Textarea(attrs={'rows': 4}),
                              max_length=250,
                              required=False)
    tags = forms.CharField(required=False)

    license = forms.TypedChoiceField(
        choices=amo.PERSONA_LICENSES_CHOICES,
        coerce=int,
        empty_value=None,
        widget=forms.HiddenInput,
        error_messages={'required': _lazy(u'A license must be selected.')})
    header = forms.FileField(required=False)
    header_hash = forms.CharField(widget=forms.HiddenInput)
    footer = forms.FileField(required=False)
    footer_hash = forms.CharField(widget=forms.HiddenInput)
    accentcolor = ColorField(required=False)
    textcolor = ColorField(required=False)
    agreed = forms.BooleanField()
    # This lets us POST the data URIs of the unsaved previews so we can still
    # show them if there were form errors. It's really clever.
    unsaved_data = forms.CharField(required=False, widget=forms.HiddenInput)

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

    def save(self, commit=False):
        from addons.tasks import (create_persona_preview_images,
                                  save_persona_image)
        data = self.cleaned_data
        addon = Addon.objects.create(slug=data.get('slug'),
                                     status=amo.STATUS_PENDING,
                                     type=amo.ADDON_PERSONA)
        addon.name = {'en-US': data['name']}
        if data.get('summary'):
            addon.description = {'en-US': data['summary']}
        addon._current_version = Version.objects.create(addon=addon,
                                                        version='0')
        addon.save()

        # Save header, footer, and preview images.
        try:
            header = data['header_hash']
            footer = data['footer_hash']
            header = os.path.join(settings.TMP_PATH, 'persona_header', header)
            footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer)
            dst_root = os.path.join(settings.ADDONS_PATH, str(addon.id))

            save_persona_image.delay(src=header,
                                     full_dst=os.path.join(
                                         dst_root, 'header.png'))
            save_persona_image.delay(src=footer,
                                     full_dst=os.path.join(
                                         dst_root, 'footer.png'))
            create_persona_preview_images.delay(
                src=header,
                full_dst=[
                    os.path.join(dst_root, 'preview.png'),
                    os.path.join(dst_root, 'icon.png')
                ],
                set_modified_on=[addon])
        except IOError:
            addon.delete()
            raise

        # Save user info.
        user = self.request.amo_user
        AddonUser(addon=addon, user=user).save()

        # Create Persona instance.
        p = Persona()
        p.persona_id = 0
        p.addon = addon
        p.header = 'header.png'
        p.footer = 'footer.png'
        if data['accentcolor']:
            p.accentcolor = data['accentcolor'].lstrip('#')
        if data['textcolor']:
            p.textcolor = data['textcolor'].lstrip('#')
        p.license = data['license']
        p.submit = datetime.now()
        p.author = user.name
        p.display_username = user.username
        p.save()

        # Save tags.
        for t in data['tags']:
            Tag(tag_text=t).save_tag(addon)

        # Save categories.
        AddonCategory(addon=addon, category=data['category']).save()

        return addon
Example #6
0
class NewThemeForm(AddonFormBase):
    name = forms.CharField(max_length=50)
    category = forms.ModelChoiceField(
        queryset=Category.objects.all(),
        widget=forms.widgets.RadioSelect,
        label=_lazy('Select the category that best describes your Theme.'))
    slug = forms.CharField(max_length=30, widget=forms.TextInput)
    summary = forms.CharField(widget=forms.widgets.Textarea(attrs={'rows': 4}),
                              label=_lazy('Describe your Theme.'),
                              max_length=250,
                              required=False)
    license = forms.TypedChoiceField(
        choices=amo.PERSONA_LICENSES_IDS,
        coerce=int,
        empty_value=None,
        widget=forms.HiddenInput,
        error_messages={'required': _lazy(u'A license must be selected.')})
    header = forms.FileField(required=False)
    header_hash = forms.CharField(widget=forms.HiddenInput)
    footer = forms.FileField(required=False)
    footer_hash = forms.CharField(widget=forms.HiddenInput)
    accentcolor = ColorField(required=False)
    textcolor = ColorField(required=False)
    # This lets us POST the data URIs of the unsaved previews so we can still
    # show them if there were form errors. It's really clever.
    unsaved_data = forms.CharField(required=False, widget=forms.HiddenInput)

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

    def __init__(self, *args, **kwargs):
        super(NewThemeForm, self).__init__(*args, **kwargs)
        cats = Category.objects.filter(application=amo.FIREFOX.id,
                                       type=amo.ADDON_PERSONA,
                                       weight__gte=0)
        cats = sorted(cats, key=lambda x: x.name)
        self.fields['category'].choices = [(c.id, c.name) for c in cats]

        widgetAttrs = self.fields['header'].widget.attrs
        widgetAttrs['data-upload-url'] = reverse('submit.theme.upload',
                                                 args=['persona_header'])
        widgetAttrs['data-allowed-types'] = 'image/jpeg|image/png'

        widgetAttrs = self.fields['footer'].widget.attrs
        widgetAttrs['data-upload-url'] = reverse('submit.theme.upload',
                                                 args=['persona_footer'])
        widgetAttrs['data-allowed-types'] = 'image/jpeg|image/png'

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

    def save(self, commit=False):
        from addons.tasks import (create_persona_preview_image,
                                  save_persona_image)
        data = self.cleaned_data
        addon = Addon.objects.create(id=None,
                                     name=data['name'],
                                     slug=data['slug'],
                                     description=data['summary'],
                                     status=amo.STATUS_PENDING,
                                     type=amo.ADDON_PERSONA)
        addon._current_version = Version.objects.create(addon=addon,
                                                        version='0')
        addon.save()

        # Save header, footer, and preview images.
        try:
            header = data['header_hash']
            footer = data['footer_hash']
            header = os.path.join(settings.TMP_PATH, 'persona_header', header)
            footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer)
            dst = os.path.join(settings.PERSONAS_PATH, str(addon.id))
            save_persona_image(src=header, dst=dst, img_basename='header.jpg')
            save_persona_image(src=footer, dst=dst, img_basename='footer.jpg')
            create_persona_preview_image(src=header,
                                         dst=dst,
                                         img_basename='preview.jpg',
                                         set_modified_on=[addon])
        except IOError:
            addon.delete()
            raise IOError

        # Save user info.
        user = self.request.amo_user
        AddonUser(addon=addon, user=user).save()

        # Create Persona instance.
        p = Persona()
        p.persona_id = 0
        p.addon = addon
        p.header = 'header'
        p.footer = 'footer'
        if data['accentcolor']:
            p.accentcolor = data['accentcolor'].lstrip('#')
        if data['textcolor']:
            p.textcolor = data['textcolor'].lstrip('#')
        p.license_id = data['license']
        p.submit = datetime.now()
        p.author = user.name
        p.display_username = user.username
        p.save()

        # Save categories.
        tb_c, created = Category.objects.get_or_create(
            application_id=amo.THUNDERBIRD.id,
            name__id=data['category'].name.id,
            type=amo.ADDON_PERSONA)
        AddonCategory(addon=addon, category=data['category']).save()
        AddonCategory(addon=addon, category=tb_c).save()

        return addon