class CodebookNewCodeForm(forms.Form): codebook = forms.ModelChoiceField(queryset=Codebook.objects.all()) label = forms.CharField() language = forms.ModelChoiceField(queryset=Language.objects.all()) parent = forms.ModelChoiceField(queryset=Code.objects.all(), required=False) def __init__(self, options=None, codebook=None): super(CodebookNewCodeForm, self).__init__(options) if codebook: self.fields["codebook"].initial = codebook self.fields["codebook"].widget = HiddenInput() self.fields['parent'].queryset = ( self.fields['parent'].queryset.filter( id__in=codebook.get_code_ids())) def save(self): code = Code.create(label=self.cleaned_data['label'], language=self.cleaned_data['language']) self.cleaned_data['codebook'].add_code(code, self.cleaned_data.get('parent')) class Meta: model = CodebookCode fields = ('codebook', 'code', 'parent')
class AddUserFormWithPassword(UserForm): def __init__(self, request, *args, **kwargs): super(AddUserFormWithPassword, self).__init__(request, False, *args, **kwargs) password = forms.CharField(label="Password", widget=forms.PasswordInput) password2 = forms.CharField(label="Repeat password", widget=forms.PasswordInput) def clean_password(self): pwd1 = self.data['password'] pwd2 = self.data['password2'] if pwd1 != pwd2: raise forms.ValidationError("Passwords do not match") return pwd1 class Meta: model = User fields = ('username', 'first_name', 'last_name', 'email', 'password', 'password2')
class SplitArticleForm(forms.Form): add_to_new_set = forms.CharField(required=False) add_to_sets = forms.ModelMultipleChoiceField( queryset=ArticleSet.objects.none(), widget=widgets.JQueryMultipleSelect, required=False) remove_from_sets = forms.ModelMultipleChoiceField( queryset=ArticleSet.objects.none(), widget=widgets.JQueryMultipleSelect, required=False) remove_from_all_sets = forms.BooleanField( initial=True, required=False, help_text="Remove all instances of the original article in this project" ) add_splitted_to_sets = forms.ModelMultipleChoiceField( queryset=ArticleSet.objects.none(), widget=widgets.JQueryMultipleSelect, required=False) add_splitted_to_new_set = forms.CharField(required=False) add_splitted_to_all = forms.BooleanField( initial=False, required=False, help_text= "Add new (splitted) articles to all sets containing the original article" ) def __init__(self, project, article, *args, **kwargs): if not isinstance(project, Project): raise ValueError("First argument of constructor must be a Project") if not isinstance(article, Article): raise ValueError( "Second argument of constructor must be a Article") super(SplitArticleForm, self).__init__(*args, **kwargs) self.fields["add_splitted_to_sets"].queryset = project.all_articlesets( ) self.fields["remove_from_sets"].queryset = project.all_articlesets( ).filter(articles=article) self.fields["add_to_sets"].queryset = project.all_articlesets()
class AddMultipleUsersForm(AddUserForm): csv = fields.CSVField(label="CSV", columns={ 'username' : fields.UserField(), 'email' : forms.EmailField(), 'last_name' : forms.CharField(), 'first_name' : forms.CharField(), }) delimiter = forms.CharField(initial=',', help_text="This field indicates how this CSV is splitted.") def __init__(self, request, *args, **kwargs): super(AddMultipleUsersForm, self).__init__(request, *args, **kwargs) for field in ("username", "email", "last_name", "first_name"): del self.fields[field] def full_clean(self, *args, **kwargs): self.fields['csv'].set_delimiter(self.data.get('delimiter', ',')) return super(AddMultipleUsersForm, self).full_clean(*args, **kwargs)
class CodingSchemaFieldForm(forms.ModelForm): label = forms.CharField() default = forms.CharField(required=False) def __init__(self, schema, *args, **kwargs): super(CodingSchemaFieldForm, self).__init__(*args, **kwargs) self.fields['codebook'].required = False self.fields['codebook'].queryset = schema.project.get_codebooks() def _to_bool(self, val): if val is None: return if str(val).lower() in ("true", "1", "yes"): return True elif str(val).lower() in ("false", "0", "no"): return False def clean_codebook(self): db_type = CodingSchemaFieldType.objects.get(name__iexact="Codebook") if 'fieldtype' not in self.cleaned_data: raise ValidationError("Fieldtype must be set in order to check this field") elif self.cleaned_data['fieldtype'] == db_type: if not self.cleaned_data['codebook']: raise ValidationError("Codebook must be set when fieldtype is '{}'".format(db_type)) elif self.cleaned_data['codebook']: raise ValidationError("Codebook must not be set when fieldtype is '{}'".format(self.cleaned_data['fieldtype'])) return self.cleaned_data['codebook'] def clean_default(self): # Differentiate between '' and None value = self.cleaned_data['default'] if 'fieldtype' not in self.cleaned_data: raise ValidationError("Fieldtype must be set in order to check this field") if self.data['default'] is None: return # Fieldtype is set fieldtype = self.cleaned_data['fieldtype'] if fieldtype.serialiserclass == BooleanSerialiser: value = self._to_bool(value) if value is None: raise ValidationError( ("When fieldtype is of type {}, default needs " + "to be empty, true or false.").format(fieldtype)) serialiser = fieldtype.serialiserclass(CodingSchemaField(**self.cleaned_data)) try: return serialiser.serialise(value) except: if fieldtype.serialiserclass == CodebookSerialiser: try: value = int(value) except ValueError: raise ValidationError("This value needs to be a code_id.") # possible_values doesn't return a queryset, so we need to iterate :( if value in (code.id for code in serialiser.possible_values): return value raise ValidationError("'{}' is not a valid value.".format(value)) # Can't catch specific error possible_values = serialiser.possible_values if possible_values is not None: raise ValidationError( "'{}' is not a valid value. Options: {}".format( self.cleaned_data['default'], possible_values ) ) raise ValidationError("'{}' is not a valid value".format(value)) return value class Meta: model = CodingSchemaField
class UploadScriptForm(forms.Form): file = forms.FileField(help_text="Supported archives: zip") encoding = forms.ChoiceField(choices=((1, "ISO-8859-15"), (2, "UTF-8"), (3, "LATIN-1")), initial=1, help_text="Try to change this value when character"+ " issues arise.") exi_set = forms.ModelChoiceField(queryset=ArticleSet.objects.all(), label="Existing set", required=False) new_set = forms.CharField(max_length=100, required=False) script = forms.ChoiceField(choices=[(sc, sc) for sc in article_upload.__all__]) def __init__(self, project, *args, **kwargs): super(UploadScriptForm, self).__init__(*args, **kwargs) exi = self.fields['exi_set'] exi.queryset = exi.queryset.filter(project=project) self.project = project def _get_zip_files(self, fo): zip = zipfile.ZipFile(fo) for fi in zip.infolist(): if fi.filename.split('.')[-1].lower in ALLOWED_EXTENSIONS: yield fi.filename, zip.read(fi) else: logger.debug("%s not in ALLOWED_EXTENSIONS, skipping.." % fi.filename) def clean_new_set(self): if not (self.cleaned_data['new_set'] or self.cleaned_data['exi_set']): raise forms.ValidationError("Either choose an existing set from the list above or\ fill in this field to create a new set.") new_set = ArticleSet.objects.filter(project=self.project, name=self.cleaned_data['new_set']) if len(new_set) != 0: raise forms.ValidationError("Set already exists!") return self.cleaned_data['new_set'] def clean_file(self): data = self.cleaned_data['file'] ext = unicode(data).split('.')[-1] if ext.lower() not in ALLOWED_EXTENSIONS + ['zip']: raise forms.ValidationError("%s is not a supported format" % ext) # Extract all txt-files from archive if ext.lower() == 'zip': try: return list(self._get_zip_files(data)) except zipfile.BadZipfile: raise forms.ValidationError("%s is not a zipfile" % data) # Read txt file elif ext.lower() in ALLOWED_EXTENSIONS: return [(unicode(data), data.read())] def clean_encoding(self): ident = self.cleaned_data['encoding'] enc = dict(self.fields['encoding'].choices).get(int(ident)) if 'file' not in self.cleaned_data: # Fail silently, as 'file' will fail anyway return enc # Test encoding for fn, bytes in self.cleaned_data['file']: try: bytes.decode(enc) except UnicodeDecodeError: raise ValidationError("Couldn't decode '%s' with '%s'" % (fn, enc)) return enc