diff --git a/views/forms.py b/views/forms.py index 7ec3a3f63c0b1b677ce025370710b5d36ee9cc4e..843cae1b4d949b60fbcab5b41d704f8fe325722a 100644 --- a/views/forms.py +++ b/views/forms.py @@ -1,5 +1,7 @@ from flask_wtf import FlaskForm -from wtforms import StringField, PasswordField, BooleanField, HiddenField, IntegerField, SelectField, FileField, DateTimeField, TextAreaField, Field, widgets, FormField +from wtforms import ( + StringField, PasswordField, BooleanField, IntegerField, SelectField, + FileField, DateTimeField, TextAreaField, Field, FormField, widgets) from wtforms.fields.html5 import DateField from wtforms.validators import InputRequired, Optional @@ -11,6 +13,7 @@ from shared import current_user import config + def get_protocoltype_choices(protocoltypes, add_all=True): choices = [ (protocoltype.id, protocoltype.short_name) @@ -21,6 +24,7 @@ def get_protocoltype_choices(protocoltypes, add_all=True): choices.insert(0, (-1, "Alle Typen")) return choices + def get_category_choices(categories, add_all=True): choices = [ (category.id, category.name) @@ -31,12 +35,14 @@ def get_category_choices(categories, add_all=True): 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() @@ -46,19 +52,21 @@ def get_calendar_choices(protocoltype=None): choices = list(zip(calendars, calendars)) else: if (protocoltype is not None - and protocoltype.calendar is not None - and protocoltype.calendar != ""): + 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_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) @@ -71,6 +79,7 @@ def get_latex_template_choices(): choices.insert(0, ("", "Standardvorlage")) return choices + def get_group_choices(): user = current_user() groups = sorted(user.groups) @@ -78,12 +87,14 @@ def get_group_choices(): 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() @@ -109,30 +120,53 @@ class IPNetworkField(Field): except ValueError as exc: print(exc) self.data = None - raise ValueError(self.gettext("Not a valid IP Network: {}".format(str(exc)))) + 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.")]) + 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") + 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") + non_reproducible_pad_links = BooleanField( + "nicht nachvollziehbare Etherpad-Links") private_mail = StringField("Interner Verteiler") public_mail = StringField("Öffentlicher Verteiler") wiki_category = StringField("Wiki-Kategorie") @@ -156,44 +190,65 @@ class ProtocolTypeForm(FlaskForm): 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("Nummer", validators=[InputRequired("Du musst eine Nummer angeben.")]) + 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.")]) + 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") + 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) + 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) + self.protocoltype_id.choices = get_protocoltype_choices( + protocoltypes, add_all=False) + class NewProtocolFileUploadForm(FlaskForm): file = FileField("Datei") @@ -202,31 +257,46 @@ class NewProtocolFileUploadForm(FlaskForm): def __init__(self, protocoltypes, **kwargs): super().__init__(**kwargs) - self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes, add_all=False) + 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()]) + 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("Sortierung", validators=[InputRequired("Du musst eine Sortierung in der Reihenfolge angebene.")]) + 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) @@ -235,6 +305,7 @@ class SearchForm(FlaskForm): super().__init__(**kwargs) self.protocoltype_id.choices = get_protocoltype_choices(protocoltypes) + class DecisionSearchForm(SearchForm): decisioncategory_id = SelectField("Kategorie", choices=[], coerce=int) @@ -242,52 +313,104 @@ class DecisionSearchForm(SearchForm): 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) + 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) + 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()]) - + 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.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()]) + 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.")]) + 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.")]) + 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.")]) + 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.")]) + name = StringField( + "Name", + validators=[InputRequired("Bitte gib den Namen der Kategorie an.")]) + class MergeTodosForm(FlaskForm): todo1 = IntegerField("todo 1", validators=[InputRequired()]) diff --git a/views/tables.py b/views/tables.py index 8b59ea0fc5de52d255fb5e6d3d5bec63da03771e..50168d3eb521330bfc6b1ef402eab62d16454a3e 100644 --- a/views/tables.py +++ b/views/tables.py @@ -1,10 +1,9 @@ -# coding: utf-8 from flask import Markup, url_for, request -from models.database import Protocol, ProtocolType, DefaultTOP, TOP, Todo, Decision, Meta, DefaultMeta -from shared import date_filter, datetime_filter, date_filter_short, current_user, check_login +from shared import date_filter, datetime_filter, current_user import config + class Table: def __init__(self, title, values, newlink=None, newtext=None): self.title = title @@ -13,31 +12,53 @@ class Table: self.newtext = newtext or "Neu" def rows(self): - return [row for row in [self.row(value) for value in self.values] if row is not None] + return [ + row for row in [self.row(value) for value in self.values] + if row is not None] def classes(self): return [None for header in self.headers()] @staticmethod - def link(target, text, confirm=None): - confirmation = "" + def link(target, text, confirm=None, css_class=None): + attributes = [ + "href=\"{}\"".format(target) + ] if confirm: - confirmation = " onclick=\"return confirm('{}');\"".format(confirm) - return Markup("<a href=\"{}\"{}>{}</a>".format(target, confirmation, text)) + attributes.append( + "onclick=\"return confirm('{}');\"".format(confirm)) + if css_class: + attributes.append("class=\"{}\"".format(css_class)) + return Markup("<a {}>{}</a>".format(" ".join(attributes), text)) @staticmethod - def button(target, icon, style, confirm=None): - confirmation = "" - if confirm: - confirmation = " onclick=\"return confirm('{}');\"".format(confirm) + def glyphicon(name, text=None): + if text is None: + text = "" + else: + text = " {}".format(text) return Markup( - '''<a href="{target}" class="btn btn-{style}" {confirmation}> - <span class="glyphicon glyphicon-{icon}"></span> - </a>'''.format(target=target, style=style, confirmation=confirmation, icon=icon)) - + "<span class=\"glyphicon glyphicon-{}\"></span>{}".format( + name, text)) + + @staticmethod + def button(target, icon, style, confirm=None): + return Table.link( + target=target, + text=Table.glyphicon(icon), + css_class="btn btn-{}".format(style)) + + @staticmethod + def button_group(buttons, size="xs"): + return Markup("".join([ + Markup("<div class=\"btn-group btn-group-{}\">").format(size), + "".join(buttons), + Markup("</div>"), + ])) + @staticmethod def mail(target): - return Markup("<a href=\"mailto:{}\">{}</a>".format(target, target)) + return Table.link("mailto:{}".format(target), target) @staticmethod def bool(value): @@ -46,11 +67,11 @@ class Table: @staticmethod def concat(values): return Markup(", ".join(values)) - #if len(values) <= 1: - # return "".join(values) - #else: - # return "{} and {}".format(", ".join(values[:-1]), values[-1]) - + + @staticmethod + def concat_lines(values): + return Markup("<br>".join(values)) + class SingleValueTable: def __init__(self, title, value, newlink=None, newtext=None): @@ -62,16 +83,17 @@ class SingleValueTable: def rows(self): return [self.row()] + class ProtocolsTable(Table): def __init__(self, protocols, search_results=None): - super().__init__("Protokolle", protocols, newlink=url_for("new_protocol")) + super().__init__( + "Protokolle", protocols, newlink=url_for("new_protocol")) self.search_results = search_results def headers(self): - user = current_user() result = ["Sitzung", "Sitzung", "Datum"] - state_part = ["Status", "Status",""] - search_part = ["Suchergebnis",""] + state_part = ["Status", "Status", ""] + search_part = ["Suchergebnis", ""] if self.search_results is None: result.extend(state_part) else: @@ -80,49 +102,58 @@ class ProtocolsTable(Table): def classes(self): if self.search_results is None: - result = ["hidden-sm hidden-md hidden-lg", "hidden-xs", "hidden-xs", "hidden-sm hidden-md hidden-lg", "hidden-xs", ""] + result = [ + "hidden-sm hidden-md hidden-lg", + "hidden-xs", "hidden-xs", + "hidden-sm hidden-md hidden-lg", + "hidden-xs", "" + ] else: - result = ["hidden-sm hidden-md hidden-lg", "hidden-xs", "hidden-xs", "", "hidden-xs","hidden-xs"] + result = [ + "hidden-sm hidden-md hidden-lg", + "hidden-xs", "hidden-xs", + "", "hidden-xs", "hidden-xs"] return result def row(self, protocol): user = current_user() protocol_link = url_for("show_protocol", protocol_id=protocol.id) result = [ - Markup("<br>").join([Table.link(protocol_link, protocol.protocoltype.name), date_filter(protocol.date)]), + Table.concat_lines([ + Table.link(protocol_link, protocol.protocoltype.name), + date_filter(protocol.date)]), Table.link(protocol_link, protocol.protocoltype.name), date_filter(protocol.date), ] if self.search_results is None: - result.append(Markup('<span class="glyphicon glyphicon-{state}"></span>'.format(state=protocol.get_state_glyph()))) - result.append(Markup('<span class="glyphicon glyphicon-{glyph}"></span> {state}'.format(state=protocol.get_state_name(),glyph=protocol.get_state_glyph()))) + result.append(Table.glyphicon(protocol.get_state_glyph())) + result.append(Table.glyphicon( + protocol.get_state_glyph(), protocol.get_state_name())) elif protocol in self.search_results: result.append(Markup(self.search_results[protocol])) - result.append(Markup('<span class="glyphicon glyphicon-{state}"></span>'.format(state=protocol.get_state_glyph()))) - - login_part1="" - login_part2="" + result.append(Table.glyphicon(protocol.get_state_glyph())) + + buttons = [] if protocol.has_public_view_right(user): user_right = protocol.has_private_view_right(user) document = protocol.get_compiled_document(user_right) if document is not None: - login_part1 = Table.button( + buttons.append(Table.button( url_for("download_document", document_id=document.id), - icon="download", style="success") + icon="download", style="success")) if protocol.protocoltype.has_admin_right(user): - login_part2 = Table.button( + buttons.append(Table.button( url_for("delete_protocol", protocol_id=protocol.id), icon="trash", style="danger", - confirm="Bist du dir sicher, dass du das Protokoll {} löschen möchtest?") - - result.append(Markup( - '<div class="btn-group btn-group-xs"> {} </div>'.format( - "".join((login_part1, login_part2))))) + confirm="Bist du dir sicher, dass du das Protokoll {} " + "löschen möchtest?")) + result.append(Table.button_group(buttons)) return result + class ProtocolTypesTable(Table): def __init__(self, types): super().__init__("Protokolltypen", types, newlink=url_for("new_type")) @@ -144,37 +175,51 @@ class ProtocolTypesTable(Table): user = current_user() has_private_view_right = protocoltype.has_private_view_right(user) has_modify_right = protocoltype.has_modify_right(user) - protocoltype_link = url_for("show_type", protocoltype_id=protocoltype.id) - protocol_link = (url_for("show_protocol", protocol_id=protocol.id) + protocoltype_link = url_for( + "show_type", protocoltype_id=protocoltype.id) + protocol_link = ( + url_for("show_protocol", protocol_id=protocol.id) if protocol is not None else "") - new_protocol_link = url_for("new_protocol", protocoltype_id=protocoltype.id) - mobile_name = "{} ({})".format(protocoltype.name, protocoltype.short_name) + new_protocol_link = url_for( + "new_protocol", protocoltype_id=protocoltype.id) + mobile_name = "{} ({})".format( + protocoltype.name, protocoltype.short_name) mobile_links = [] if protocol is not None: - mobile_links.append(Table.link(protocol_link, protocol.get_short_identifier())) + mobile_links.append(Table.link( + protocol_link, protocol.get_short_identifier())) if has_modify_right: - mobile_links.append(Table.link(new_protocol_link, "Neues Protokoll")) + mobile_links.append( + Table.link(new_protocol_link, "Neues Protokoll")) mobile_part = [ - Table.link(protocoltype_link, mobile_name) if has_private_view_right else mobile_name, + Table.link(protocoltype_link, mobile_name) + if has_private_view_right else mobile_name, Markup("<br>".join(mobile_links)) ] desktop_part = [ - Table.link(protocoltype_link, protocoltype.short_name) if has_private_view_right else protocoltype.short_name, + Table.link(protocoltype_link, protocoltype.short_name) + if has_private_view_right else protocoltype.short_name, protocoltype.name, - Table.link(protocol_link, protocol.get_short_identifier()) if protocol is not None else "Noch kein Protokoll", - Table.link(new_protocol_link, "Neues Protokoll") if has_modify_right else "" - "" # TODO: add link for modify, delete + Table.link(protocol_link, protocol.get_short_identifier()) + if protocol is not None else "Noch kein Protokoll", + Table.link(new_protocol_link, "Neues Protokoll") + if has_modify_right else "" + "" # TODO: add link for modify, delete ] return mobile_part + desktop_part + class ProtocolTypeTable(SingleValueTable): def __init__(self, protocoltype): - super().__init__(protocoltype.name, protocoltype, newlink=url_for("edit_type", protocoltype_id=protocoltype.id)) + super().__init__( + protocoltype.name, protocoltype, + newlink=url_for("edit_type", protocoltype_id=protocoltype.id)) def headers(self): - general_headers = ["Name", "Abkürzung", "Organisation", "Beginn", - "Öffentlich", "Verwaltungsgruppe", "Bearbeitungsgruppe", "Interne Gruppe", - "Öffentliche Gruppe"] + general_headers = [ + "Name", "Abkürzung", "Organisation", "Beginn", + "Öffentlich", "Verwaltungsgruppe", "Bearbeitungsgruppe", + "Interne Gruppe", "Öffentliche Gruppe"] etherpad_headers = ["Nicht-reproduzierbare Etherpadlinks"] if not config.ETHERPAD_ACTIVE: etherpad_headers = [] @@ -193,13 +238,17 @@ class ProtocolTypeTable(SingleValueTable): network_headers = ["Netzwerke einschränken", "Erlaubte Netzwerke"] action_headers = ["Aktion"] feed_headers = [] - latex_template_headers = ["LaTeX Vorlage"] if getattr(config, "LATEX_TEMPLATES", None) is not None else [] + latex_template_headers = ["LaTeX Vorlage"] if getattr( + config, "LATEX_TEMPLATES", None) is not None else [] if self.value.has_public_anonymous_view_right(): - feed_headers = [Markup("<img height=\"18px\" src=\"{}\" /> Feed".format( - url_for("static", filename="images/feed-icon.svg")))] - return (general_headers + etherpad_headers + mail_headers + feed_headers = [ + Markup("<img height=\"18px\" src=\"{}\" /> Feed".format( + url_for("static", filename="images/feed-icon.svg")))] + return ( + general_headers + etherpad_headers + mail_headers + printing_headers + wiki_headers + calendar_headers - + network_headers + latex_template_headers + feed_headers + action_headers) + + network_headers + latex_template_headers + feed_headers + + action_headers) def row(self): user = current_user() @@ -207,7 +256,8 @@ class ProtocolTypeTable(SingleValueTable): self.value.name, self.value.short_name, self.value.organization, - self.value.usual_time.strftime("%H:%M") if self.value.usual_time is not None else "", # todo: remove if, this field is required + self.value.usual_time.strftime("%H:%M") + if self.value.usual_time is not None else "", Table.bool(self.value.is_public), self.value.publish_group, self.value.modify_group, @@ -229,49 +279,77 @@ class ProtocolTypeTable(SingleValueTable): if not config.PRINTING_ACTIVE: printing_part = [] wiki_part = [ - (Table.bool(self.value.use_wiki) + ((", " + ("Öffentlich" if self.value.wiki_only_public else "Intern")) if self.value.use_wiki else "")) + (Table.bool(self.value.use_wiki) + + ((", " + + ("Öffentlich" + if self.value.wiki_only_public + else "Intern") + ) if self.value.use_wiki else "")) ] if self.value.use_wiki: wiki_part.append(self.value.wiki_category) if not config.WIKI_ACTIVE: wiki_part = [] - calendar_part = [self.value.calendar if self.value.calendar is not None else ""] + calendar_part = [ + self.value.calendar + if self.value.calendar is not None else ""] if not config.CALENDAR_ACTIVE: calendar_part = [] network_part = [Table.bool(self.value.restrict_networks)] if self.value.allowed_networks is not None: - network_part.append(", ".join(map(str.strip, self.value.allowed_networks.split(",")))) + network_part.append( + ", ".join(map( + str.strip, self.value.allowed_networks.split(",")))) else: network_part.append("") _latex_templates = getattr(config, "LATEX_TEMPLATES", None) if _latex_templates is not None: - latex_template_part = [_latex_templates[self.value.latex_template]['name'] if self.value.latex_template is not (None or "") else "Standardvorlage"] + latex_template_part = [ + _latex_templates[self.value.latex_template]['name'] + if self.value.latex_template is not (None or "") + else "Standardvorlage"] else: latex_template_part = [] feed_part = [] if self.value.has_public_anonymous_view_right(): feed_part = [Markup(", ".join([ - Table.link(url_for("feed_protocols_rss", + Table.link(url_for( + "feed_protocols_rss", protocoltype_id=self.value.id), "Protokolle (RSS)"), - Table.link(url_for("feed_protocols_atom", + Table.link(url_for( + "feed_protocols_atom", protocoltype_id=self.value.id), "Protokolle (Atom)"), - Table.link(url_for("feed_appointments_rss", + Table.link(url_for( + "feed_appointments_rss", protocoltype_id=self.value.id), "Sitzungen (RSS)"), - Table.link(url_for("feed_appointments_atom", + Table.link(url_for( + "feed_appointments_atom", protocoltype_id=self.value.id), "Sitzungen (Atom)"), - Table.link(url_for("feed_appointments_ical", + Table.link(url_for( + "feed_appointments_ical", protocoltype_id=self.value.id), "Sitzungen (iCal)"), ]))] - action_part = [Table.link(url_for("delete_type", protocoltype_id=self.value.id), "Löschen", confirm="Bist du dir sicher, dass du den Protokolltype {} löschen möchtest?".format(self.value.name))] + action_part = [ + Table.link( + url_for("delete_type", protocoltype_id=self.value.id), + "Löschen", + confirm="Bist du dir sicher, dass du den Protokolltype " + "{} löschen möchtest?".format(self.value.name)) + ] if not self.value.has_admin_right(user): action_part = [""] - return (general_part + etherpad_part + mail_part + printing_part - + wiki_part + calendar_part + network_part + latex_template_part + feed_part - + action_part) + return ( + general_part + etherpad_part + mail_part + printing_part + + wiki_part + calendar_part + network_part + latex_template_part + + feed_part + action_part) + class DefaultTOPsTable(Table): def __init__(self, tops, protocoltype=None): - super().__init__("Standard-TOPs", tops, newlink=url_for("new_default_top", protocoltype_id=protocoltype.id) if protocoltype is not None else None) + super().__init__( + "Standard-TOPs", tops, + newlink=url_for("new_default_top", protocoltype_id=protocoltype.id) + if protocoltype is not None else None) self.protocoltype = protocoltype def headers(self): @@ -282,31 +360,54 @@ class DefaultTOPsTable(Table): top.name, top.number, Table.concat([ - Table.link(url_for("move_default_top", defaulttop_id=top.id, diff=1), "Runter"), - Table.link(url_for("move_default_top", defaulttop_id=top.id, diff=-1), "Hoch"), - Table.link(url_for("edit_default_top", protocoltype_id=self.protocoltype.id, defaulttop_id=top.id), "Ändern"), - Table.link(url_for("delete_default_top", defaulttop_id=top.id), "Löschen", confirm="Bist du dir sicher, dass du den Standard-TOP {} löschen willst?".format(top.name)) + Table.link( + url_for("move_default_top", defaulttop_id=top.id, diff=1), + "Runter"), + Table.link( + url_for("move_default_top", defaulttop_id=top.id, diff=-1), + "Hoch"), + Table.link( + url_for( + "edit_default_top", + protocoltype_id=self.protocoltype.id, + defaulttop_id=top.id), + "Ändern"), + Table.link( + url_for("delete_default_top", defaulttop_id=top.id), + "Löschen", + confirm="Bist du dir sicher, dass du den Standard-TOP " + "{} löschen willst?".format(top.name)) ]) ] + class MeetingRemindersTable(Table): def __init__(self, reminders, protocoltype=None): - super().__init__("Einladungsmails", reminders, newlink=url_for("new_reminder", protocoltype_id=protocoltype.id) if protocoltype is not None else None) + super().__init__( + "Einladungsmails", reminders, + newlink=url_for("new_reminder", protocoltype_id=protocoltype.id) + if protocoltype is not None else None) self.protocoltype = protocoltype def headers(self): return ["Zeit", "Einladen", "Zusätzlicher Mailinhalt", ""] def row(self, reminder): - user = current_user() general_part = [ "{} Tage".format(reminder.days_before), self.get_send_summary(reminder), reminder.additional_text or "" ] action_links = [ - Table.link(url_for("edit_reminder", meetingreminder_id=reminder.id), "Ändern"), - Table.link(url_for("delete_reminder", meetingreminder_id=reminder.id), "Löschen", confirm="Bist du dir sicher, dass du die Einladungsmail {} Tage vor der Sitzung löschen willst?".format(reminder.days_before)) + Table.link( + url_for("edit_reminder", meetingreminder_id=reminder.id), + "Ändern"), + Table.link( + url_for("delete_reminder", meetingreminder_id=reminder.id), + "Löschen", + confirm="Bist du dir sicher, dass du die Einladungsmail {} " + "Tage vor der Sitzung löschen willst?".format( + reminder.days_before)) ] action_part = [Table.concat(action_links)] return general_part + action_part @@ -319,26 +420,35 @@ class MeetingRemindersTable(Table): parts.append("Intern") return " und ".join(parts) + class ErrorsTable(Table): def __init__(self, errors): super().__init__("Fehler", errors) def headers(self): - return ["Protokoll", "Aktion", "Fehler", "Zeitpunkt", "Beschreibung", ""] + return [ + "Protokoll", "Aktion", "Fehler", "Zeitpunkt", "Beschreibung", ""] def classes(self): return [None, None, None, None, "hidden-xs", "hidden-xs"] def row(self, error): return [ - Table.link(url_for("show_protocol", protocol_id=error.protocol.id), error.protocol.get_short_identifier()), + Table.link( + url_for("show_protocol", protocol_id=error.protocol.id), + error.protocol.get_short_identifier()), error.action, Table.link(url_for("show_error", error_id=error.id), error.name), datetime_filter(error.datetime), error.get_short_description(), - Table.link(url_for("delete_error", error_id=error.id, next=request.path), "Löschen", confirm="Bist du dir sicher, dass du den Fehler löschen möchtest?") + Table.link( + url_for("delete_error", error_id=error.id, next=request.path), + "Löschen", + confirm="Bist du dir sicher, dass du den Fehler löschen " + "möchtest?") ] + class ErrorTable(SingleValueTable): def __init__(self, error): super().__init__(error.action, error) @@ -348,12 +458,15 @@ class ErrorTable(SingleValueTable): def row(self): return [ - Table.link(url_for("show_protocol", protocol_id=self.value.protocol.id), self.value.protocol.get_short_identifier()), + Table.link( + url_for("show_protocol", protocol_id=self.value.protocol.id), + self.value.protocol.get_short_identifier()), self.value.action, self.value.name, datetime_filter(self.value.datetime) ] + class TodosTable(Table): def __init__(self, todos): super().__init__("Todos", todos, newlink=url_for("new_todo")) @@ -362,22 +475,34 @@ class TodosTable(Table): return ["Todo", "ID", "Status", "Sitzung", "Name", "Aufgabe", ""] def classes(self): - return ["hidden-sm hidden-md hidden-lg", "hidden-xs", "hidden-xs", "hidden-xs", "hidden-xs", None, "hidden-xs"] + return [ + "hidden-sm hidden-md hidden-lg", + "hidden-xs", "hidden-xs", "hidden-xs", "hidden-xs", + None, "hidden-xs"] def row(self, todo): user = current_user() protocol = todo.get_first_protocol() - mobile_parts = [Table.link(url_for("show_todo", todo_id=todo.id), todo.get_state())] + mobile_parts = [Table.link( + url_for("show_todo", todo_id=todo.id), + todo.get_state())] if protocol is not None: - mobile_parts.append(Table.link(url_for("show_protocol", protocol_id=protocol.id), todo.protocoltype.short_name)) + mobile_parts.append(Table.link( + url_for("show_protocol", protocol_id=protocol.id), + todo.protocoltype.short_name)) mobile_parts.append(todo.who) row = [ Markup("<br>").join(mobile_parts), Table.link(url_for("show_todo", todo_id=todo.id), todo.get_id()), todo.get_state(), - Table.link(url_for("show_protocol", protocol_id=protocol.id), protocol.get_short_identifier()) - if protocol is not None - else Table.link(url_for("list_protocols", protocoltype_id=todo.protocoltype.id), todo.protocoltype.short_name), + Table.link( + url_for("show_protocol", protocol_id=protocol.id), + protocol.get_short_identifier()) + if protocol is not None + else Table.link( + url_for( + "list_protocols", protocoltype_id=todo.protocoltype.id), + todo.protocoltype.short_name), todo.who, todo.description, ] @@ -390,6 +515,7 @@ class TodosTable(Table): row.append("") return row + class TodoTable(SingleValueTable): def __init__(self, todo): super().__init__("Todo", todo) @@ -399,26 +525,32 @@ class TodoTable(SingleValueTable): def row(self): user = current_user() - protocol = self.value.get_first_protocol() row = [ self.value.get_id(), self.value.get_state_plain(), Table.concat([ - Table.link(url_for("show_protocol", protocol_id=protocol.id), protocol.get_short_identifier()) - for protocol in self.value.protocols + Table.link( + url_for("show_protocol", protocol_id=protocol.id), + protocol.get_short_identifier()) + for protocol in self.value.protocols ]), self.value.who, self.value.description ] if self.value.protocoltype.has_modify_right(user): row.append(Table.concat([ - Table.link(url_for("edit_todo", todo_id=self.value.id), "Ändern"), - Table.link(url_for("delete_todo", todo_id=self.value.id), "Löschen", confirm="Bist du dir sicher, dass du das Todo löschen willst?") + Table.link( + url_for("edit_todo", todo_id=self.value.id), "Ändern"), + Table.link( + url_for("delete_todo", todo_id=self.value.id), "Löschen", + confirm="Bist du dir sicher, dass du das Todo löschen " + "willst?") ])) else: row.append("") return row + class DecisionsTable(Table): def __init__(self, decisions): super().__init__("Beschlüsse", decisions) @@ -438,21 +570,28 @@ class DecisionsTable(Table): def row(self, decision): user = current_user() content_part = [ - Table.link(url_for("show_protocol", protocol_id=decision.protocol.id), decision.protocol.get_short_identifier()), + Table.link( + url_for("show_protocol", protocol_id=decision.protocol.id), + decision.protocol.get_short_identifier()), decision.content ] category_part = [decision.get_categories_str()] if not self.category_present: category_part = [] action_part = [ - Table.link(url_for("print_decision", decisiondocument_id=decision.document.id), "Drucken") - if config.PRINTING_ACTIVE + Table.link( + url_for( + "print_decision", + decisiondocument_id=decision.document.id), + "Drucken") + if (config.PRINTING_ACTIVE and decision.protocol.protocoltype.has_modify_right(user) - and decision.document is not None - else "" + and decision.document is not None) + else "" ] return content_part + category_part + action_part + class DocumentsTable(Table): def __init__(self, documents, protocol): super().__init__("Anhang", documents) @@ -464,7 +603,7 @@ class DocumentsTable(Table): visibility_headers = [] if self.protocol.has_private_view_right(user): visibility_headers = ["Sichtbarkeit"] - action_headers=[""] + action_headers = [""] return general_headers + visibility_headers + action_headers def classes(self): @@ -480,24 +619,39 @@ class DocumentsTable(Table): user = current_user() links = [] if document.protocol.has_modify_right(user): - links.append(Table.link(url_for("edit_document", document_id=document.id), "Bearbeiten")) + links.append(Table.link( + url_for("edit_document", document_id=document.id), + "Bearbeiten")) if config.PRINTING_ACTIVE and document.protocol.has_modify_right(user): - links.append(Table.link(url_for("print_document", document_id=document.id), "Drucken")) + links.append(Table.link( + url_for("print_document", document_id=document.id), + "Drucken")) if document.protocol.protocoltype.has_admin_right(user): - links.append(Table.link(url_for("delete_document", document_id=document.id), "Löschen", confirm="Bist du dir sicher, dass du das Dokument {} löschen willst?".format(document.name))) + links.append(Table.link( + url_for("delete_document", document_id=document.id), + "Löschen", + confirm="Bist du dir sicher, dass du das Dokument {} löschen " + "willst?".format(document.name))) general_part = [ document.id, - Table.link(url_for("download_document", document_id=document.id), document.name), + Table.link( + url_for("download_document", document_id=document.id), + document.name), ] visibility_part = [] if document.protocol.has_private_view_right(user): - visibility_part = ["Intern" if document.is_private else "Öffentlich"] + visibility_part = [ + "Intern" + if document.is_private + else "Öffentlich"] action_part = [Table.concat(links)] return general_part + visibility_part + action_part + class TodoMailsTable(Table): def __init__(self, todomails): - super().__init__("Todo-Mail-Zuordnungen", todomails, url_for("new_todomail")) + super().__init__( + "Todo-Mail-Zuordnungen", todomails, url_for("new_todomail")) def headers(self): return ["Name", "Mail", ""] @@ -507,11 +661,19 @@ class TodoMailsTable(Table): todomail.name, todomail.mail, Table.concat([ - Table.link(url_for("edit_todomail", todomail_id=todomail.id), "Ändern"), - Table.link(url_for("delete_todomail", todomail_id=todomail.id), "Löschen", confirm="Bist du dir sicher, dass du die Todomailzuordnung {} zu {} löschen willst?".format(todomail.name, todomail.mail)) + Table.link( + url_for("edit_todomail", todomail_id=todomail.id), + "Ändern"), + Table.link( + url_for("delete_todomail", todomail_id=todomail.id), + "Löschen", + confirm="Bist du dir sicher, dass du die " + "Todomailzuordnung {} zu {} löschen " + "willst?".format(todomail.name, todomail.mail)) ]) ] + class DefaultMetasTable(Table): def __init__(self, metas, protocoltype): super().__init__( @@ -524,7 +686,6 @@ class DefaultMetasTable(Table): return ["Name", "Key", "Standardwert", "Intern", "Vorher", ""] def row(self, meta): - user = current_user() general_part = [ meta.name, meta.key, @@ -533,17 +694,23 @@ class DefaultMetasTable(Table): Table.bool(meta.prior) ] links = [ - Table.link(url_for("edit_defaultmeta", defaultmeta_id=meta.id), "Ändern"), - Table.link(url_for("delete_defaultmeta", defaultmeta_id=meta.id), "Löschen", confirm="Bist du dir sicher, dass du das Metadatenfeld {} löschen willst?".format(meta.name)) + Table.link( + url_for("edit_defaultmeta", defaultmeta_id=meta.id), "Ändern"), + Table.link( + url_for("delete_defaultmeta", defaultmeta_id=meta.id), + "Löschen", + confirm="Bist du dir sicher, dass du das Metadatenfeld {} " + "löschen willst?".format(meta.name)) ] link_part = [Table.concat(links)] return general_part + link_part + class DecisionCategoriesTable(Table): def __init__(self, categories, protocoltype): super().__init__( "Beschlusskategorien", - categories, + categories, url_for("new_decisioncategory", protocoltype_id=protocoltype.id) ) @@ -551,13 +718,22 @@ class DecisionCategoriesTable(Table): return ["Name", ""] def row(self, category): - user = current_user() general_part = [category.name] action_part = [ Table.concat([ - Table.link(url_for("edit_decisioncategory", decisioncategory_id=category.id), "Ändern"), - Table.link(url_for("delete_decisioncategory", decisioncategory_id=category.id), "Löschen", confirm="Bist du dir sicher, dass du die Beschlusskategorie {} löschen willst?".format(category.name)) + Table.link( + url_for( + "edit_decisioncategory", + decisioncategory_id=category.id), + "Ändern"), + Table.link( + url_for( + "delete_decisioncategory", + decisioncategory_id=category.id), + "Löschen", + confirm="Bist du dir sicher, dass du die " + "Beschlusskategorie {} löschen " + "willst?".format(category.name)) ]) ] return general_part + action_part -