Coverage for portality/view/forms.py: 47%
72 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-19 17:05 +0100
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-19 17:05 +0100
1'''
2All the various simple forms that we need in the system
4FIXME: probably we need to think more about how we organise forms - maybe a module with different files for different
5features, and a bit of refactoring on the organisation of the formcontext stuff to be consistent
6'''
7import re
9from wtforms import Form, validators
10from wtforms import StringField, TextAreaField, HiddenField
12from portality import regex, models
13from portality.forms.validate import OptionalIf, MaxLen
16##########################################################################
17## Editor Group Forms
18##########################################################################
20class UniqueGroupName(object):
21 def __init__(self, *args, **kwargs):
22 pass
24 def __call__(self, form, field):
25 exists_id = models.EditorGroup.group_exists_by_name(field.data)
26 if exists_id is None:
27 # if there is no group of the same name, we are fine
28 return
30 # if there is a group of the same name, we need to check whether it's the
31 # same group as we are currently editing
32 id_field = form._fields.get("group_id")
33 if id_field is None or id_field.data == "" or id_field.data is None:
34 # if there is no id field then this is a new group, and so the name clashes
35 # with an existing group
36 raise validators.ValidationError("The group's name must be unique among the Editor Groups")
38 # if we get to here, the id_field exists, so we need to check whether it matches
39 # the group with the same id
40 if id_field.data != exists_id:
41 raise validators.ValidationError("The group's name must be unique among the Editor Groups")
44class NotRole(object):
45 def __init__(self, role, *args, **kwargs):
46 self.role = role
48 def __call__(self, form, field):
49 accounts = [a.strip() for a in field.data.split(",") if a.strip() != ""]
50 if len(accounts) == 0:
51 return
52 fails = []
53 for a in accounts:
54 acc = models.Account.pull(a)
55 if acc is None: # If the account has been deleted we can't pull
56 continue
57 elif acc.has_role(self.role) and not acc.is_super:
58 fails.append(acc.id)
59 if len(fails) == 0:
60 return
61 have_or_has = "have" if len(fails) > 1 else "has"
62 msg = ", ".join(fails) + " " + have_or_has + " role " + self.role + " so cannot be assigned to an Editor Group"
63 raise validators.ValidationError(msg)
66class MustHaveRole(object):
67 """
68 ~~MustHaveRole:Validator~~
69 """
70 def __init__(self, role, *args, **kwargs):
71 self.role = role
73 def __call__(self, form, field):
74 accounts = [a.strip() for a in field.data.split(",") if a.strip() != ""]
75 if len(accounts) == 0:
76 return
77 fails = []
78 for a in accounts:
79 acc = models.Account.pull(a)
80 if acc is None: # If the account has been deleted we can't pull
81 continue
82 if not acc.has_role(self.role):
83 fails.append(acc.id)
84 if len(fails) == 0:
85 return
86 do_or_does = "do" if len(fails) > 1 else "does"
87 msg = ", ".join(fails) + " " + do_or_does + " not have role " + self.role + " so cannot be assigned as a Managing Editor"
88 raise validators.ValidationError(msg)
91class EditorGroupForm(Form):
92 """
93 ~~EditorGroup:Form~~
94 """
95 group_id = HiddenField("Group ID", [validators.Optional()])
96 name = StringField("Group Name", [validators.DataRequired(), UniqueGroupName()])
97 maned = StringField("Managing Editor", [validators.Optional(), MustHaveRole("admin")])
98 editor = StringField("Editor", [validators.DataRequired(), NotRole("publisher")])
99 associates = StringField("Associate Editors", [validators.Optional(), NotRole("publisher")])
101##########################################################################
102## Continuations Forms
103##########################################################################
105ISSN_ERROR = 'An ISSN or EISSN should be 7 or 8 digits long, separated by a dash, e.g. 1234-5678. If it is 7 digits long, it must end with the letter X (e.g. 1234-567X).'
108class MakeContinuation(Form):
110 title = StringField('Journal Title', [validators.DataRequired()])
112 pissn = StringField('Journal ISSN (print version)',
113 [OptionalIf('eissn'), validators.Regexp(regex=regex.ISSN_COMPILED, message=ISSN_ERROR)],
114 description='Only provide the print ISSN if your journal has one, otherwise leave this field blank. Write the ISSN with the hyphen "-" e.g. 1234-4321.',
115 )
116 eissn = StringField('Journal ISSN (online version)',
117 [OptionalIf('pissn'), validators.Regexp(regex=regex.ISSN_COMPILED, message=ISSN_ERROR)],
118 description='Cannot be the same as the P-ISSN. Write the EISSN with the hyphen "-" e.g. 1234-4321.',
119 )
121 type = HiddenField()
123##########################################################################
124## Contact Forms
125##########################################################################
128class ContactUs(Form):
130 recaptcha_value = HiddenField()
132 email = StringField('Your Email', [validators.DataRequired(), validators.Email()])
134 subject = StringField("Subject", [validators.Optional()])
136 message = TextAreaField("Message", [validators.DataRequired(), MaxLen(1000)], description="1000 characters max - <span id='wordcount'></span>")