from flask_wtf import FlaskForm from wtforms import ( StringField, PasswordField, BooleanField, IntegerField, SelectField, FileField, DateTimeField, TextAreaField, Field, FormField, DateField, widgets) from wtforms.validators import InputRequired, Optional import ipaddress from models.database import TodoState from validators import CheckTodoDateByState from shared import current_user from shared import config def get_protocoltype_choices(protocoltypes, add_all=True): choices = [ (protocoltype.id, protocoltype.short_name) for protocoltype in sorted(protocoltypes, key=lambda t: t.short_name) ] if add_all: 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")) return choices def get_todostate_choices(): return [ (state, state.get_name()) for state in TodoState ] def get_calendar_choices(protocoltype=None): from calendarpush import Client as CalendarClient calendars = CalendarClient().get_calendars() choices = [] if calendars is not None: calendars = sorted(calendars) choices = list(zip(calendars, calendars)) else: if (protocoltype is not None and protocoltype.calendar is not None and protocoltype.calendar != ""): choices.append((protocoltype.calendar, protocoltype.calendar)) choices.insert(0, ("", "Kein Kalender")) return choices def get_printer_choices(): choices = [] if config.PRINTING_ACTIVE and config.PRINTING_PRINTERS is not None: choices = list(zip(config.PRINTING_PRINTERS, config.PRINTING_PRINTERS)) choices.insert(0, ("", "Nicht drucken")) return choices def get_latex_template_choices(): choices = [] _latex_templates = getattr(config, "LATEX_TEMPLATES", None) if _latex_templates is not None: choices = [ (key, values['name']) for key, values in _latex_templates.items() ] choices.insert(0, ("", "Standardvorlage")) return choices def get_group_choices(): user = current_user() groups = sorted(user.all_groups) choices = list(zip(groups, groups)) choices.insert(0, ("", "Keine Gruppe")) return choices def coerce_todostate(key): if isinstance(key, str): class_part, key_part = key.split(".") key = TodoState[key_part] return key 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)) class FocusedStringField(StringField): def __call__(self, **kwargs): kwargs['autofocus'] = True return super().__call__(**kwargs) class LoginForm(FlaskForm): username = FocusedStringField( "Benutzer", validators=[InputRequired("Bitte gib deinen Benutzernamen ein.")]) password = PasswordField( "Passwort", validators=[InputRequired("Bitte gib dein Passwort ein.")]) permanent = BooleanField("Eingeloggt bleiben?") 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.") ]) usual_time = DateTimeField( "Üblicher Beginn", validators=[ InputRequired("Bitte gib die Zeit an, zu der die Sitzung beginnt.") ], format="%H:%M") is_public = BooleanField("Öffentlich sichtbar") publish_group = SelectField("Verwaltungsgruppe", choices=[]) modify_group = SelectField("Bearbeitungsgruppe", choices=[]) private_group = SelectField("Interne Gruppe", choices=[]) public_group = SelectField("Öffentliche Gruppe", choices=[]) non_reproducible_pad_links = BooleanField( "nicht nachvollziehbare Etherpad-Links") private_mail = StringField("Interner Verteiler") public_mail = StringField("Öffentlicher Verteiler") wiki_category = StringField("Wiki-Kategorie") use_wiki = BooleanField("Wiki benutzen") wiki_only_public = BooleanField("Wiki ist öffentlich") printer = SelectField("Drucker", choices=[]) calendar = SelectField("Kalender", choices=[]) restrict_networks = BooleanField("Netzwerke einschränken") allowed_networks = IPNetworkField("Erlaubte Netzwerke") latex_template = SelectField("LaTeX Vorlage", choices=[]) def __init__(self, **kwargs): super().__init__(**kwargs) protocoltype = kwargs["obj"] if "obj" in kwargs else None self.calendar.choices = get_calendar_choices(protocoltype=protocoltype) self.printer.choices = get_printer_choices() self.latex_template.choices = get_latex_template_choices() group_choices = get_group_choices() self.publish_group.choices = group_choices self.modify_group.choices = group_choices self.private_group.choices = group_choices self.public_group.choices = group_choices class DefaultTopForm(FlaskForm): name = StringField( "Name", validators=[InputRequired("Du musst einen Namen angeben.")]) number = IntegerField( "Priorität", validators=[InputRequired("Du musst eine Priorität angeben.")]) description = TextAreaField("Standardinhalt") 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") additional_text = TextAreaField("Zusätzlicher Mailinhalt") class NewProtocolForm(FlaskForm): protocoltype_id = SelectField("Typ", choices=[], coerce=int) date = DateField( "Datum", validators=[InputRequired("Du musst ein Datum angeben.")]) start_time = DateTimeField( "Uhrzeit (HH:MM, optional)", validators=[Optional()], format="%H:%M") def __init__(self, protocoltypes, **kwargs): super().__init__(**kwargs) self.protocoltype_id.choices = get_protocoltype_choices( protocoltypes, add_all=False) class DocumentEditForm(FlaskForm): name = StringField("Dateiname") is_private = BooleanField("Intern") class DocumentUploadForm(FlaskForm): document = FileField("Datei") is_private = BooleanField("Intern") class KnownProtocolSourceUploadForm(FlaskForm): source = FileField("Quellcode") class NewProtocolSourceUploadForm(FlaskForm): source = FileField("Quellcode") protocoltype_id = SelectField("Typ", choices=[], coerce=int) def __init__(self, protocoltypes, **kwargs): super().__init__(**kwargs) self.protocoltype_id.choices = get_protocoltype_choices( protocoltypes, add_all=False) class NewProtocolFileUploadForm(FlaskForm): file = FileField("Datei") protocoltype_id = SelectField("Typ", choices=[], coerce=int) private = BooleanField("Intern") def __init__(self, protocoltypes, **kwargs): super().__init__(**kwargs) self.protocoltype_id.choices = get_protocoltype_choices( protocoltypes, add_all=False) def generate_protocol_form(protocol): class ProtocolMetasForm(FlaskForm): pass for meta in protocol.metas: setattr(ProtocolMetasForm, meta.name, StringField(meta.name)) class ProtocolForm(FlaskForm): date = DateField( "Datum", validators=[ InputRequired("Bitte gib das Datum des Protkolls an.") ]) start_time = DateTimeField( "Beginn (%H:%M)", format="%H:%M", validators=[Optional()]) end_time = DateTimeField( "Ende (%H:%M)", format="%H:%M", validators=[Optional()]) metas = FormField(ProtocolMetasForm) done = BooleanField("Fertig") public = BooleanField("Veröffentlicht") return ProtocolForm class TopForm(FlaskForm): name = StringField( "TOP", validators=[InputRequired("Du musst den Namen des TOPs angeben.")]) number = IntegerField( "Priorität", validators=[InputRequired("Du musst eine Priorität angeben.")]) description = TextAreaField("Beschreibung") class LocalTopForm(FlaskForm): description = TextAreaField("Beschreibung") class SearchForm(FlaskForm): search = StringField("Suchbegriff") protocoltype_id = SelectField("Typ", choices=[], coerce=int) def __init__(self, protocoltypes, **kwargs): super().__init__(**kwargs) self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes) 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) class ProtocolSearchForm(SearchForm): state_open = SelectField( "Offen", choices=[(-1, "Alle"), (0, "Geplant"), (1, "Fertig")], coerce=int) class TodoSearchForm(SearchForm): state_open = SelectField( "Offen", choices=[(-1, "Alle"), (0, "Offen"), (1, "Erledigt")], coerce=int) 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.") ]) state = SelectField( "Status", choices=[], coerce=coerce_todostate, validators=[CheckTodoDateByState()]) date = DateField("Datum", validators=[Optional()]) def __init__(self, protocoltypes, **kwargs): super().__init__(**kwargs) self.protocoltype_id.choices = get_protocoltype_choices( protocoltypes, add_all=False) self.state.choices = get_todostate_choices() class TodoForm(FlaskForm): who = StringField("Person") description = StringField( "Aufgabe", validators=[InputRequired("Bitte gib an, was erledigt werden soll.")]) state = SelectField( "Status", choices=[], coerce=coerce_todostate, validators=[CheckTodoDateByState()]) date = DateField("Datum", validators=[Optional()]) def __init__(self, **kwargs): super().__init__(**kwargs) self.state.choices = get_todostate_choices() 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.")]) class MetaForm(FlaskForm): name = StringField( "Name", validators=[InputRequired("Bitte gib den Namen der Metadaten an.")]) value = StringField("Wert") internal = BooleanField("Intern") 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.")]) value = StringField("Standardwert") internal = BooleanField("Intern") prior = BooleanField("Planungsrelevant") class DecisionCategoryForm(FlaskForm): name = StringField( "Name", validators=[InputRequired("Bitte gib den Namen der Kategorie an.")]) 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