class ReviewerNotesForm(happyforms.ModelForm): approvalnotes = forms.CharField( widget=TranslationTextarea(attrs={'rows': 4}), required=False) class Meta: model = Version fields = ('approvalnotes', )
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')
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)
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
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')
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
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')