forms.py 10.7 KB
Newer Older
1
from flask_wtf import FlaskForm
2
from wtforms import StringField, PasswordField, BooleanField, DateField, HiddenField, IntegerField, SelectField, FileField, DateTimeField, TextAreaField, Field, widgets
Robin Sonnabend's avatar
Robin Sonnabend committed
3
from wtforms.validators import InputRequired, Optional
4

5
6
import ipaddress

7
8
from models.database import TodoState
from validators import CheckTodoDateByState
Robin Sonnabend's avatar
Robin Sonnabend committed
9
from calendarpush import Client as CalendarClient
10
from shared import current_user
11

Robin Sonnabend's avatar
Robin Sonnabend committed
12
13
import config

Robin Sonnabend's avatar
Robin Sonnabend committed
14
def get_protocoltype_choices(protocoltypes, add_all=True):
15
16
17
18
19
    choices = [
        (protocoltype.id, protocoltype.short_name)
        for protocoltype
        in sorted(protocoltypes, key=lambda t: t.short_name)
    ]
Robin Sonnabend's avatar
Robin Sonnabend committed
20
    if add_all:
21
22
23
24
25
26
27
28
29
30
31
        choices.insert(0, (-1, "Alle Typen"))
    return choices

def get_category_choices(categories, add_all=True):
    choices = [
        (category.id, category.name)
        for category
        in sorted(categories, key=lambda c: c.name)
    ]
    if add_all:
        choices.insert(0, (-1, "Alle Kategorien"))
Robin Sonnabend's avatar
Robin Sonnabend committed
32
33
    return choices

34
35
def get_todostate_choices():
    return [
36
        (state, state.get_name())
37
38
39
        for state in TodoState
    ]

Robin Sonnabend's avatar
Robin Sonnabend committed
40
def get_calendar_choices(protocoltype=None):
41
    calendars = CalendarClient().get_calendars()
42
43
44
45
    choices = []
    if calendars is not None:
        calendars = sorted(calendars)
        choices = list(zip(calendars, calendars))
Robin Sonnabend's avatar
Robin Sonnabend committed
46
47
48
49
50
    else:
        if (protocoltype is not None
        and protocoltype.calendar is not None
        and protocoltype.calendar != ""):
            choices.append((protocoltype.calendar, protocoltype.calendar))
51
52
53
54
    choices.insert(0, ("", "Kein Kalender"))
    return choices

def get_printer_choices():
55
56
57
    choices = []
    if config.PRINTING_PRINTERS is not None:
        choices = list(zip(config.PRINTING_PRINTERS, config.PRINTING_PRINTERS))
58
59
60
61
62
    choices.insert(0, ("", "Nicht drucken"))
    return choices

def get_group_choices():
    user = current_user()
Robin Sonnabend's avatar
Robin Sonnabend committed
63
64
    groups = sorted(user.groups)
    choices = list(zip(groups, groups))
65
66
    choices.insert(0, ("", "Keine Gruppe"))
    return choices
Robin Sonnabend's avatar
Robin Sonnabend committed
67

68
69
70
71
72
73
def coerce_todostate(key):
    if isinstance(key, str):
        class_part, key_part = key.split(".")
        key = TodoState[key_part]
    return key

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
class IPNetworkField(Field):
    widget = widgets.TextInput()

    def __init__(self, label=None, validators=None, **kwargs):
        super().__init__(label, validators, **kwargs)

    def _value(self):
        if self.raw_data:
            return " ".join(self.raw_data)
        else:
            return self.data and str(self.data) or ""

    def process_formdata(self, valuelist):
        if valuelist:
            data_str = valuelist[0]
            result_parts = []
            try:
                for part in data_str.split(","):
                    part = part.strip()
                    if len(part) > 0:
                        network = ipaddress.ip_network(part)
                        result_parts.append(network)
            except ValueError as exc:
                print(exc)
                self.data = None
                raise ValueError(self.gettext("Not a valid IP Network: {}".format(str(exc))))
            self.data = ",".join(map(str, result_parts))

102
class LoginForm(FlaskForm):
Robin Sonnabend's avatar
Robin Sonnabend committed
103
104
105
106
107
108
109
    username = StringField("Benutzer", validators=[InputRequired("Bitte gib deinen Benutzernamen ein.")])
    password = PasswordField("Passwort", validators=[InputRequired("Bitte gib dein Passwort ein.")])

class ProtocolTypeForm(FlaskForm):
    name = StringField("Name", validators=[InputRequired("Du musst einen Namen angeben.")])
    short_name = StringField("Abkürzung", validators=[InputRequired("Du musst eine Abkürzung angebene.")])
    organization = StringField("Organisation", validators=[InputRequired("Du musst eine zugehörige Organisation angeben.")])
Robin Sonnabend's avatar
Robin Sonnabend committed
110
    usual_time = DateTimeField("Üblicher Beginn", validators=[InputRequired("Bitte gib die Zeit an, zu der die Sitzung beginnt.")], format="%H:%M")
Robin Sonnabend's avatar
Robin Sonnabend committed
111
    is_public = BooleanField("Öffentlich sichtbar")
112
    modify_group = SelectField("Bearbeitungsgruppe", choices=[])
113
114
    private_group = SelectField("Interne Gruppe", choices=[])
    public_group = SelectField("Öffentliche Gruppe", choices=[])
115
    non_reproducible_pad_links = BooleanField("nicht nachvollziehbare Etherpad-Links")
Robin Sonnabend's avatar
Robin Sonnabend committed
116
117
    private_mail = StringField("Interner Verteiler")
    public_mail = StringField("Öffentlicher Verteiler")
Robin Sonnabend's avatar
Robin Sonnabend committed
118
119
120
    wiki_category = StringField("Wiki-Kategorie")
    use_wiki = BooleanField("Wiki benutzen")
    wiki_only_public = BooleanField("Wiki ist öffentlich")
121
    printer = SelectField("Drucker", choices=[])
122
    calendar = SelectField("Kalender", choices=[])
123
124
    restrict_networks = BooleanField("Netzwerke einschränken")
    allowed_networks = IPNetworkField("Erlaubte Netzwerke")
125
126

    def __init__(self, **kwargs):
127
        super().__init__(**kwargs)
Robin Sonnabend's avatar
Robin Sonnabend committed
128
129
        protocoltype = kwargs["obj"] if "obj" in kwargs else None
        self.calendar.choices = get_calendar_choices(protocoltype=protocoltype)
130
131
        self.printer.choices = get_printer_choices()
        group_choices = get_group_choices()
132
        self.modify_group.choices = group_choices
133
134
        self.private_group.choices = group_choices
        self.public_group.choices = group_choices
Robin Sonnabend's avatar
Robin Sonnabend committed
135
136
137
138

class DefaultTopForm(FlaskForm):
    name = StringField("Name", validators=[InputRequired("Du musst einen Namen angeben.")])
    number = IntegerField("Nummer", validators=[InputRequired("Du musst eine Nummer angeben.")])
139
140
141
142
143

class MeetingReminderForm(FlaskForm):
    days_before = IntegerField("Tage vor Sitzung", validators=[InputRequired("Du musst eine Dauer angeben.")])
    send_public = BooleanField("Öffentlich einladen")
    send_private = BooleanField("Intern einladen")
Robin Sonnabend's avatar
Robin Sonnabend committed
144
    additional_text = TextAreaField("Zusätzlicher Mailinhalt")
Robin Sonnabend's avatar
Robin Sonnabend committed
145
146

class NewProtocolForm(FlaskForm):
147
    protocoltype_id = SelectField("Typ", choices=[], coerce=int)
148
    date = DateField("Datum (dd.mm.yyyy)", validators=[InputRequired("Du musst ein Datum angeben.")], format="%d.%m.%Y")
Robin Sonnabend's avatar
Robin Sonnabend committed
149
150
151

    def __init__(self, protocoltypes, **kwargs):
        super().__init__(**kwargs)
152
        self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes, add_all=False)
153
154

class DocumentUploadForm(FlaskForm):
Robin Sonnabend's avatar
Robin Sonnabend committed
155
    document = FileField("Datei")
156
    private = BooleanField("Intern")
Robin Sonnabend's avatar
Robin Sonnabend committed
157
158
159
160
161
162

class KnownProtocolSourceUploadForm(FlaskForm):
    source = FileField("Quellcode")

class NewProtocolSourceUploadForm(FlaskForm):
    source = FileField("Quellcode")
163
    protocoltype_id = SelectField("Typ", choices=[], coerce=int)
Robin Sonnabend's avatar
Robin Sonnabend committed
164
165
166

    def __init__(self, protocoltypes, **kwargs):
        super().__init__(**kwargs)
167
        self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes, add_all=False)
Robin Sonnabend's avatar
Robin Sonnabend committed
168

169
170
class NewProtocolFileUploadForm(FlaskForm):
    file = FileField("Datei")
171
    protocoltype_id = SelectField("Typ", choices=[], coerce=int)
172
173
174
175
    private = BooleanField("Intern")

    def __init__(self, protocoltypes, **kwargs):
        super().__init__(**kwargs)
176
        self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes, add_all=False)
177

Robin Sonnabend's avatar
Robin Sonnabend committed
178
class ProtocolForm(FlaskForm):
179
    date = DateField("Datum (dd.mm.yyyy)", validators=[InputRequired("Bitte gib das Datum des Protkolls an.")], format="%d.%m.%Y")
Robin Sonnabend's avatar
Robin Sonnabend committed
180
181
    start_time = DateTimeField("Beginn", format="%H:%M", validators=[Optional()])
    end_time = DateTimeField("Ende", format="%H:%M", validators=[Optional()])
Robin Sonnabend's avatar
Robin Sonnabend committed
182
    location = StringField("Ort")
183
    author = StringField("Protokoll")
Robin Sonnabend's avatar
Robin Sonnabend committed
184
185
    participants = StringField("Anwesende")
    done = BooleanField("Fertig")
186
    public = BooleanField("Veröffentlicht")
Robin Sonnabend's avatar
Robin Sonnabend committed
187

Robin Sonnabend's avatar
Robin Sonnabend committed
188
189
190
class TopForm(FlaskForm):
    name = StringField("TOP", validators=[InputRequired("Du musst den Namen des TOPs angeben.")])
    number = IntegerField("Sortierung", validators=[InputRequired("Du musst eine Sortierung in der Reihenfolge angebene.")])
191
    description = TextAreaField("Beschreibung")
Robin Sonnabend's avatar
Robin Sonnabend committed
192

Robin Sonnabend's avatar
Robin Sonnabend committed
193
194
class SearchForm(FlaskForm):
    search = StringField("Suchbegriff")
195
    protocoltype_id = SelectField("Typ", choices=[], coerce=int)
Robin Sonnabend's avatar
Robin Sonnabend committed
196
197
198

    def __init__(self, protocoltypes, **kwargs):
        super().__init__(**kwargs)
199
        self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes)
Robin Sonnabend's avatar
Robin Sonnabend committed
200

201
202
203
204
205
206
207
class DecisionSearchForm(SearchForm):
    decisioncategory_id = SelectField("Kategorie", choices=[], coerce=int)

    def __init__(self, protocoltypes, categories, **kwargs):
        super().__init__(protocoltypes=protocoltypes, **kwargs)
        self.decisioncategory_id.choices = get_category_choices(categories)

Robin Sonnabend's avatar
Robin Sonnabend committed
208
209
210
class ProtocolSearchForm(SearchForm):
    open = SelectField("Offen", choices=[(-1, "Alle"), (0, "Geplant"), (1, "Fertig")], coerce=int)

Robin Sonnabend's avatar
Robin Sonnabend committed
211
212
213
214
class NewTodoForm(FlaskForm):
    protocoltype_id = SelectField("Typ", choices=[], coerce=int)
    who = StringField("Person", validators=[InputRequired("Bitte gib an, wer das Todo erledigen soll.")])
    description = StringField("Aufgabe", validators=[InputRequired("Bitte gib an, was erledigt werden soll.")])
215
    state = SelectField("Status", choices=[], coerce=coerce_todostate, validators=[CheckTodoDateByState()])
216
    date = DateField("Datum (dd.mm.yyyy)", format="%d.%m.%Y", validators=[Optional()])
Robin Sonnabend's avatar
Robin Sonnabend committed
217
218
219
220
    
    def __init__(self, protocoltypes, **kwargs):
        super().__init__(**kwargs)
        self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes, add_all=False)
221
        self.state.choices = get_todostate_choices()
Robin Sonnabend's avatar
Robin Sonnabend committed
222
223

class TodoForm(FlaskForm):
Robin Sonnabend's avatar
Robin Sonnabend committed
224
    who = StringField("Person")
Robin Sonnabend's avatar
Robin Sonnabend committed
225
    description = StringField("Aufgabe", validators=[InputRequired("Bitte gib an, was erledigt werden soll.")])
226
    state = SelectField("Status", choices=[], coerce=coerce_todostate, validators=[CheckTodoDateByState()])
227
    date = DateField("Datum (dd.mm.yyyy)", format="%d.%m.%Y", validators=[Optional()])
228

229
230
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
231
        self.state.choices = get_todostate_choices()
Robin Sonnabend's avatar
Robin Sonnabend committed
232
233
234
235

class TodoMailForm(FlaskForm):
    name = StringField("Name", validators=[InputRequired("Du musst den Namen angeben, der zugeordnet werden soll.")])
    mail = StringField("Mail", validators=[InputRequired("Du musst die Mailadresse angeben, die zugeordnet werden soll.")])
Robin Sonnabend's avatar
Robin Sonnabend committed
236
237
238
239
240
241
242
243

class MetaForm(FlaskForm):
    name = StringField("Name", validators=[InputRequired("Bitte gib den Namen der Metadaten an.")])
    value = StringField("Wert")

class DefaultMetaForm(FlaskForm):
    key = StringField("Key", validators=[InputRequired("Bitte gib den Protokoll-Syntax-Schlüssel der Metadaten an.")])
    name = StringField("Name", validators=[InputRequired("Bitte gib den Namen der Metadaten an.")])
244

245
246
247
class DecisionCategoryForm(FlaskForm):
    name = StringField("Name", validators=[InputRequired("Bitte gib den Namen der Kategorie an.")])

248
249
250
251
252
253
254
class MergeTodosForm(FlaskForm):
    todo1 = IntegerField("todo 1", validators=[InputRequired()])
    todo2 = IntegerField("todo 2", validators=[InputRequired()])

    def __init__(self, todo=None):
        if todo is not None:
            self.todo1.data = todo.id