better ordering for tags
[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 django.core.exceptions import ValidationError
8 from django.utils.translation import ugettext_lazy as _
9
10 from catalogue.constants import STAGES
11 from catalogue.models import Category
12 from catalogue.models.document import metadata_from_text
13 from librarian.document import Document
14
15
16 class DocumentTextSaveForm(forms.Form):
17     """
18     Form for saving document's text:
19
20         * parent_revision - revision which the modified text originated from.
21         * comment - user's verbose comment; will be used in commit.
22         * stage - change to this stage
23
24     """
25
26     parent_revision = forms.IntegerField(widget=forms.HiddenInput, required=False)
27     text = forms.CharField(widget=forms.HiddenInput)
28
29     author_name = forms.CharField(
30         required=True,
31         label=_(u"Author"),
32         help_text=_(u"Your name"),
33     )
34
35     author_email = forms.EmailField(
36         required=True,
37         label=_(u"Author's email"),
38         help_text=_(u"Your email address, so we can show a gravatar :)"),
39     )
40
41     comment = forms.CharField(
42         required=False,
43         widget=forms.Textarea,
44         label=_(u"Your comments"),
45         help_text=_(u"Describe changes you made."),
46     )
47
48     stage = forms.ChoiceField(
49         choices=STAGES,
50         required=False,
51         label=_(u"Stage"),
52         help_text=_(u"If completed a work stage, change to another one."),
53     )
54
55     def __init__(self, *args, **kwargs):
56         user = kwargs.pop('user')
57         super(DocumentTextSaveForm, self).__init__(*args, **kwargs)
58         if user and user.is_authenticated():
59             self.fields['author_name'].required = False
60             self.fields['author_email'].required = False
61
62     def clean_text(self):
63         text = self.cleaned_data['text']
64         try:
65             doc = Document.from_string(text)
66         except ValueError as e:
67             raise ValidationError(e.message)
68
69         from librarian import SSTNS, DCNS
70         root_elem = doc.edoc.getroot()
71         if len(root_elem) < 1 or root_elem[0].tag != SSTNS('metadata'):
72             raise ValidationError("The first tag in section should be metadata")
73         if len(root_elem) < 2 or root_elem[1].tag != SSTNS('header'):
74             raise ValidationError("The first tag after metadata should be header")
75         header = root_elem[1]
76         if not getattr(header, 'text', None) or not header.text.strip():
77             raise ValidationError(
78                 "The first header should contain the title in plain text (no links, emphasis etc.) and cannot be empty")
79
80         cover_url = doc.meta.get_one(DCNS('relation.coverimage.url'))
81         if cover_url:
82             ext = cover_url.rsplit('.', 1)[-1].lower()
83             if ext not in ('jpg', 'jpeg', 'png', 'gif', 'svg'):
84                 raise ValidationError('Invalid cover image format, should be an image file (jpg, png, gif, svg). '
85                                       'Change it in Metadata.')
86         metadata = metadata_from_text(text)
87         for category in Category.objects.all():
88             values = metadata.get(category.dc_tag)
89             if not category.multiple:
90                 values = [values]
91             if not values:
92                 values = []
93             for value in values:
94                 if not category.tag_set.filter(dc_value=value):
95                     raise ValidationError('Invalid value for dc:%s: %s' % (category.dc_tag, value))
96         return text
97
98
99 class DocumentTextRevertForm(forms.Form):
100     """
101     Form for reverting document's text:
102
103         * revision - revision to revert to.
104         * comment - user's verbose comment; will be used in commit.
105
106     """
107
108     revision = forms.IntegerField(widget=forms.HiddenInput)
109
110     author_name = forms.CharField(
111         required=False,
112         label=_(u"Author"),
113         help_text=_(u"Your name"),
114     )
115
116     author_email = forms.EmailField(
117         required=False,
118         label=_(u"Author's email"),
119         help_text=_(u"Your email address, so we can show a gravatar :)"),
120     )
121
122     comment = forms.CharField(
123         required=False,
124         widget=forms.Textarea,
125         label=_(u"Your comments"),
126         help_text=_(u"Describe the reason for reverting."),
127     )
128
129
130 class DocumentTextPublishForm(forms.Form):
131     revision = forms.IntegerField(widget=forms.HiddenInput)