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
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': _(u'A license must be selected.')}) header = forms.FileField(required=False) header_hash = forms.CharField(widget=forms.HiddenInput) # Native color picker doesn't allow real time tracking of user input # and empty values, thus force the JavaScript color picker for now. # See bugs 1005206 and 1003575. accentcolor = ColorField( required=False, widget=forms.TextInput(attrs={'class': 'color-picker'}), ) textcolor = ColorField( required=False, widget=forms.TextInput(attrs={'class': 'color-picker'}), ) 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' 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.user p.author = user.username p.display_username = user.name p.save() # Save header and preview images. save_theme.delay(data['header_hash'], addon.pk) # 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