3626b6d3a375fa9a8355993d01e9521a149a1ebe
[redakcja.git] / apps / wiki / forms.py
1 # -*- coding: utf-8 -*-
2 #
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.
5 #
6 from django import forms
7 from wiki.models import Book, Chunk
8 from django.utils.translation import ugettext_lazy as _
9
10 from dvcs.models import Tag
11 from wiki.constants import MASTERS
12
13 class DocumentTagForm(forms.Form):
14     """
15         Form for tagging revisions.
16     """
17
18     id = forms.CharField(widget=forms.HiddenInput)
19     tag = forms.ModelChoiceField(queryset=Tag.objects.all())
20     revision = forms.IntegerField(widget=forms.HiddenInput)
21
22
23 class DocumentPubmarkForm(forms.Form):
24     """
25         Form for marking revisions for publishing.
26     """
27
28     id = forms.CharField(widget=forms.HiddenInput)
29     publishable = forms.BooleanField(required=False, initial=True,
30             label=_('Publishable'))
31     revision = forms.IntegerField(widget=forms.HiddenInput)
32
33
34 class DocumentCreateForm(forms.ModelForm):
35     """
36         Form used for creating new documents.
37     """
38     file = forms.FileField(required=False)
39     text = forms.CharField(required=False, widget=forms.Textarea)
40
41     class Meta:
42         model = Book
43         exclude = ['gallery', 'parent', 'parent_number']
44         prepopulated_fields = {'slug': ['title']}
45
46     def clean(self):
47         super(DocumentCreateForm, self).clean()
48         file = self.cleaned_data['file']
49
50         if file is not None:
51             try:
52                 self.cleaned_data['text'] = file.read().decode('utf-8')
53             except UnicodeDecodeError:
54                 raise forms.ValidationError("Text file must be UTF-8 encoded.")
55
56         if not self.cleaned_data["text"]:
57             raise forms.ValidationError("You must either enter text or upload a file")
58
59         return self.cleaned_data
60
61
62 class DocumentsUploadForm(forms.Form):
63     """
64         Form used for uploading new documents.
65     """
66     file = forms.FileField(required=True, label=_('ZIP file'))
67
68     def clean(self):
69         file = self.cleaned_data['file']
70
71         import zipfile
72         try:
73             z = self.cleaned_data['zip'] = zipfile.ZipFile(file)
74         except zipfile.BadZipfile:
75             raise forms.ValidationError("Should be a ZIP file.")
76         if z.testzip():
77             raise forms.ValidationError("ZIP file corrupt.")
78
79         return self.cleaned_data
80
81
82 class DocumentTextSaveForm(forms.Form):
83     """
84     Form for saving document's text:
85
86         * parent_revision - revision which the modified text originated from.
87         * comment - user's verbose comment; will be used in commit.
88         * stage_completed - mark this change as end of given stage.
89
90     """
91
92     parent_revision = forms.IntegerField(widget=forms.HiddenInput)
93     text = forms.CharField(widget=forms.HiddenInput)
94
95     author_name = forms.CharField(
96         required=False,
97         label=_(u"Author"),
98         help_text=_(u"Your name"),
99     )
100
101     author_email = forms.EmailField(
102         required=False,
103         label=_(u"Author's email"),
104         help_text=_(u"Your email address, so we can show a gravatar :)"),
105     )
106
107     comment = forms.CharField(
108         required=True,
109         widget=forms.Textarea,
110         label=_(u"Your comments"),
111         help_text=_(u"Describe changes you made."),
112     )
113
114     stage_completed = forms.ModelChoiceField(
115         queryset=Tag.objects.all(),
116         required=False,
117         label=_(u"Completed"),
118         help_text=_(u"If you completed a life cycle stage, select it."),
119     )
120
121
122 class DocumentTextRevertForm(forms.Form):
123     """
124     Form for reverting document's text:
125
126         * revision - revision to revert to.
127         * comment - user's verbose comment; will be used in commit.
128
129     """
130
131     revision = forms.IntegerField(widget=forms.HiddenInput)
132
133     author_name = forms.CharField(
134         required=False,
135         label=_(u"Author"),
136         help_text=_(u"Your name"),
137     )
138
139     author_email = forms.EmailField(
140         required=False,
141         label=_(u"Author's email"),
142         help_text=_(u"Your email address, so we can show a gravatar :)"),
143     )
144
145     comment = forms.CharField(
146         required=True,
147         widget=forms.Textarea,
148         label=_(u"Your comments"),
149         help_text=_(u"Describe the reason for reverting."),
150     )
151
152
153 class ChunkForm(forms.ModelForm):
154     """
155         Form used for editing a chunk.
156     """
157
158     class Meta:
159         model = Chunk
160         exclude = ['number']
161
162     def clean_slug(self):
163         slug = self.cleaned_data['slug']
164         try:
165             chunk = Chunk.objects.get(book=self.instance.book, slug=slug)
166         except Chunk.DoesNotExist:
167             return slug
168         if chunk == self.instance:
169             return slug
170         raise forms.ValidationError(_('Chunk with this slug already exists'))
171
172
173 class ChunkAddForm(ChunkForm):
174     """
175         Form used for adding a chunk to a document.
176     """
177
178     def clean_slug(self):
179         slug = self.cleaned_data['slug']
180         try:
181             user = Chunk.objects.get(book=self.instance.book, slug=slug)
182         except Chunk.DoesNotExist:
183             return slug
184         raise forms.ValidationError(_('Chunk with this slug already exists'))
185
186
187
188
189 class BookAppendForm(forms.Form):
190     """
191         Form for appending a book to another book.
192         It means moving all chunks from book A to book B and deleting A.
193     """
194
195     append_to = forms.ModelChoiceField(queryset=Book.objects.all(),
196         label=_("Append to"))
197
198
199 class BookForm(forms.ModelForm):
200     """
201         Form used for editing a Book.
202     """
203
204     class Meta:
205         model = Book
206
207
208 class ChooseMasterForm(forms.Form):
209     """
210         Form used for fixing the chunks in a book.
211     """
212
213     master = forms.ChoiceField(choices=((m, m) for m in MASTERS))