1 # -*- coding: utf-8 -*-
 
   3 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 
   4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 
   6 from catalogue.models import User
 
   7 from django.db.models import Count
 
   8 from django import forms
 
   9 from django.utils.translation import ugettext_lazy as _
 
  11 from catalogue.constants import MASTERS
 
  12 from catalogue.models import Book, Chunk, Image
 
  14 class DocumentCreateForm(forms.ModelForm):
 
  16         Form used for creating new documents.
 
  18     file = forms.FileField(required=False)
 
  19     text = forms.CharField(required=False, widget=forms.Textarea)
 
  23         exclude = ['parent', 'parent_number', 'project']
 
  25     def __init__(self, *args, **kwargs):
 
  26         super(DocumentCreateForm, self).__init__(*args, **kwargs)
 
  27         self.fields['slug'].widget.attrs={'class': 'autoslug'}
 
  28         self.fields['gallery'].widget.attrs={'class': 'autoslug'}
 
  29         self.fields['title'].widget.attrs={'class': 'autoslug-source'}
 
  32         super(DocumentCreateForm, self).clean()
 
  33         file = self.cleaned_data['file']
 
  37                 self.cleaned_data['text'] = file.read().decode('utf-8')
 
  38             except UnicodeDecodeError:
 
  39                 raise forms.ValidationError(_("Text file must be UTF-8 encoded."))
 
  41         if not self.cleaned_data["text"]:
 
  42             self._errors["file"] = self.error_class([_("You must either enter text or upload a file")])
 
  44         return self.cleaned_data
 
  47 class DocumentsUploadForm(forms.Form):
 
  49         Form used for uploading new documents.
 
  51     file = forms.FileField(required=True, label=_('ZIP file'))
 
  52     dirs = forms.BooleanField(label=_('Directories are documents in chunks'),
 
  53             widget = forms.CheckboxInput(attrs={'disabled':'disabled'}))
 
  56         file = self.cleaned_data['file']
 
  60             z = self.cleaned_data['zip'] = zipfile.ZipFile(file)
 
  61         except zipfile.BadZipfile:
 
  62             raise forms.ValidationError("Should be a ZIP file.")
 
  64             raise forms.ValidationError("ZIP file corrupt.")
 
  66         return self.cleaned_data
 
  69 class ChunkForm(forms.ModelForm):
 
  71         Form used for editing a chunk.
 
  73     user = forms.ModelChoiceField(queryset=
 
  74         User.objects.annotate(count=Count('chunk')).
 
  75         order_by('last_name', 'first_name'), required=False,
 
  76         label=_('Assigned to')) 
 
  80         fields = ['title', 'slug', 'gallery_start', 'user', 'stage']
 
  83     def __init__(self, *args, **kwargs):
 
  84         super(ChunkForm, self).__init__(*args, **kwargs)
 
  85         self.fields['gallery_start'].widget.attrs={'class': 'number-input'}
 
  86         self.fields['slug'].widget.attrs={'class': 'autoslug'}
 
  87         self.fields['title'].widget.attrs={'class': 'autoslug-source'}
 
  90         slug = self.cleaned_data['slug']
 
  92             chunk = Chunk.objects.get(book=self.instance.book, slug=slug)
 
  93         except Chunk.DoesNotExist:
 
  95         if chunk == self.instance:
 
  97         raise forms.ValidationError(_('Chunk with this slug already exists'))
 
 100 class ChunkAddForm(ChunkForm):
 
 102         Form used for adding a chunk to a document.
 
 105     def clean_slug(self):
 
 106         slug = self.cleaned_data['slug']
 
 108             user = Chunk.objects.get(book=self.instance.book, slug=slug)
 
 109         except Chunk.DoesNotExist:
 
 111         raise forms.ValidationError(_('Chunk with this slug already exists'))
 
 114 class BookAppendForm(forms.Form):
 
 116         Form for appending a book to another book.
 
 117         It means moving all chunks from book A to book B and deleting A.
 
 119     append_to = forms.ModelChoiceField(queryset=Book.objects.all(),
 
 120             label=_("Append to"))
 
 122     def __init__(self, book, *args, **kwargs):
 
 123         ret =  super(BookAppendForm, self).__init__(*args, **kwargs)
 
 124         self.fields['append_to'].queryset = Book.objects.exclude(pk=book.pk)
 
 128 class BookForm(forms.ModelForm):
 
 129     """Form used for editing a Book."""
 
 133         exclude = ['project']
 
 135     def __init__(self, *args, **kwargs):
 
 136         ret = super(BookForm, self).__init__(*args, **kwargs)
 
 137         self.fields['slug'].widget.attrs.update({"class": "autoslug"})
 
 138         self.fields['title'].widget.attrs.update({"class": "autoslug-source"})
 
 141     def save(self, **kwargs):
 
 142         orig_instance = Book.objects.get(pk=self.instance.pk)
 
 143         old_gallery = orig_instance.gallery
 
 144         new_gallery = self.cleaned_data['gallery']
 
 145         if new_gallery != old_gallery:
 
 148             from django.conf import settings
 
 149             shutil.move(orig_instance.gallery_path(),
 
 150                         os.path.join(settings.MEDIA_ROOT, settings.IMAGE_DIR, new_gallery))
 
 151         super(BookForm, self).save(**kwargs)
 
 154 class ReadonlyBookForm(BookForm):
 
 155     """Form used for not editing a Book."""
 
 157     def __init__(self, *args, **kwargs):
 
 158         ret = super(ReadonlyBookForm, self).__init__(*args, **kwargs)
 
 159         for field in self.fields.values():
 
 160             field.widget.attrs.update({"disabled": "disabled"})
 
 164 class ChooseMasterForm(forms.Form):
 
 166         Form used for fixing the chunks in a book.
 
 169     master = forms.ChoiceField(choices=((m, m) for m in MASTERS))
 
 172 class ImageForm(forms.ModelForm):
 
 173     """Form used for editing an Image."""
 
 174     user = forms.ModelChoiceField(queryset=
 
 175         User.objects.annotate(count=Count('chunk')).
 
 176         order_by('-count', 'last_name', 'first_name'), required=False,
 
 177         label=_('Assigned to')) 
 
 181         fields = ['title', 'slug', 'user', 'stage']
 
 183     def __init__(self, *args, **kwargs):
 
 184         super(ImageForm, self).__init__(*args, **kwargs)
 
 185         self.fields['slug'].widget.attrs={'class': 'autoslug'}
 
 186         self.fields['title'].widget.attrs={'class': 'autoslug-source'}
 
 189 class ReadonlyImageForm(ImageForm):
 
 190     """Form used for not editing an Image."""
 
 192     def __init__(self, *args, **kwargs):
 
 193         ret = super(ReadonlyImageForm, self).__init__(*args, **kwargs)
 
 194         for field in self.fields.values():
 
 195             field.widget.attrs.update({"disabled": "disabled"})