diff --git a/models/database.py b/models/database.py index 792a706e3ced6acf5f706b097e1f75a0d7d92512..4a3930200f58e2db1095de59f73e886472c563ef 100644 --- a/models/database.py +++ b/models/database.py @@ -326,6 +326,28 @@ class Protocol(DatabaseModel): tops_before.append(top) return tops_before + self.tops + tops_after + @staticmethod + def create_new_protocol(protocoltype, date, start_time=None): + if start_time is None: + start_time = protocoltype.usual_time + protocol = Protocol(protocoltype_id=protocoltype.id, + date=date, start_time=start_time) + db.session.add(protocol) + db.session.commit() + for local_top in protocol.create_localtops(): + db.session.add(local_top) + for default_meta in protocoltype.metas: + if default_meta.prior: + meta = Meta(protocol_id=protocol.id, name=default_meta.name, + internal=default_meta.internal, value=default_meta.value) + db.session.add(meta) + db.session.commit() + import tasks + tasks.push_tops_to_calendar(protocol) + return protocol + + + @event.listens_for(Protocol, "before_delete") def on_protocol_delete(mapper, connection, protocol): protocol.delete_orphan_todos() diff --git a/protoparser.py b/protoparser.py index 18ef97a8ffda5c368f45316e762eb44a8ba215aa..b72ce51cdf8aa31d4a4eff038362a061c40aaa5d 100644 --- a/protoparser.py +++ b/protoparser.py @@ -269,6 +269,7 @@ class Tag: elif self.name == "footnote": return '<sup id="#fnref{0}"><a href="#fn{0}">Fn</a></sup>'.format( footnote_hash(self.values[0])) + return "[{}: {}]".format(self.name, ";".join(self.values)) else: raise _not_implemented(self, render_type) @@ -294,7 +295,7 @@ class Tag: # v3: also match [] without semicolons inbetween, as there is not other use for that PATTERN = r"\[(?<content>[^\]]*)\]" - KNOWN_TAGS = ["todo", "url", "beschluss", "footnote"] + KNOWN_TAGS = ["todo", "url", "beschluss", "footnote", "sitzung"] class Empty(Element): diff --git a/server.py b/server.py index 0d1d7e2202ee656a6417da105773f969077a058d..91da22f82444c3d1bfae9799fffd3d2aceb1756e 100755 --- a/server.py +++ b/server.py @@ -490,20 +490,8 @@ def new_protocol(): if protocoltype is None or not protocoltype.has_modify_right(user): flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error") return redirect(request.args.get("next") or url_for("index")) - protocol = Protocol(protocoltype_id=protocoltype.id) - form.populate_obj(protocol) - if form.start_time.data is None: - protocol.start_time = protocoltype.usual_time - db.session.add(protocol) - db.session.commit() - for local_top in protocol.create_localtops(): - db.session.add(local_top) - for default_meta in protocoltype.metas: - if default_meta.prior: - meta = Meta(protocol_id=protocol.id, name=default_meta.name, internal=default_meta.internal, value=default_meta.value) - db.session.add(meta) - db.session.commit() - tasks.push_tops_to_calendar(protocol) + protocol = Protocol.create_new_protocol(protocoltype, + form.date.data, form.start_time.data) return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) type_id = request.args.get("protocoltype_id") if type_id is not None: @@ -516,7 +504,7 @@ def new_protocol(): def show_protocol(protocol): user = current_user() errors_table = ErrorsTable(protocol.errors) - if not protocol.protocoltype.has_public_view_right(user, check_networks=False): # yes, feature + if not protocol.protocoltype.has_public_view_right(user, check_networks=False): flash("Die fehlen die nötigen Zugriffsrechte.", "alert-error") return redirect(request.args.get("next") or url_for("login", next=request.url)) visible_documents = [ diff --git a/tasks.py b/tasks.py index bac430dcf4752ba9fdb2a581d6f545a2ccccef19..4ffd6e88d7ac3063fdbf3951be809eb3a8b5302d 100644 --- a/tasks.py +++ b/tasks.py @@ -12,7 +12,7 @@ from models.database import Document, Protocol, Error, Todo, Decision, TOP, Defa from models.errors import DateNotMatchingException from server import celery, app from shared import db, escape_tex, unhyphen, date_filter, datetime_filter, date_filter_long, date_filter_short, time_filter, class_filter, KNOWN_KEYS -from utils import mail_manager, encode_kwargs, decode_kwargs, add_line_numbers, set_etherpad_text, get_etherpad_text, footnote_hash +from utils import mail_manager, encode_kwargs, decode_kwargs, add_line_numbers, set_etherpad_text, get_etherpad_text, footnote_hash, parse_datetime_from_string from protoparser import parse, ParserException, Element, Content, Text, Tag, Remark, Fork, RenderType from wiki import WikiClient, WikiException from calendarpush import Client as CalendarClient, CalendarException @@ -379,6 +379,49 @@ def parse_protocol_async_inner(protocol, encoded_kwargs): footnote_tags = [tag for tag in tags if tag.name == "footnote"] public_footnote_tags = [tag for tag in footnote_tags if tag in public_elements] + # new Protocols + protocol_tags = [tag for tag in tags if tag.name == "sitzung"] + for protocol_tag in protocol_tags: + if len(protocol_tag.values) not in {1, 2}: + error = protocol.create_error("Parsing", + "Falsche Verwendung von [sitzung;…].", + "Der Tag \"sitzung\" benötigt immer ein Datum " + "und optional eine Uhrzeit, also ein bis zwei Argumente. " + "Stattdessen wurden {} übergeben, nämlich {}".format( + len(protocol_tag.values), + protocol_tag.values)) + db.session.add(error) + db.ession.commit() + return + else: + try: + protocol_date = parse_datetime_from_string( + protocol_tag.values[0]) + except ValueError as exc: + error = protocol.create_error("Parsing", "Invalides Datum", + "'{}' ist kein valides Datum.".format( + protocol_tag.values[0])) + db.session.add(error) + db.session.commit() + return + if len(protocol_tag.values) > 1: + try: + protocol_time = datetime.strptime(protocol_tag.values[1], "%H:%M") + except ValueError: + error = protocol.create_error("Parsing", "Invalide Uhrzeit", + "'{}' ist keine valide Uhrzeit.".format( + protocol_tag.values[1])) + db.session.add(error) + db.session.commit() + return + for protocol_tag in protocol_tags: + new_protocol_date = parse_datetime_from_string(protocol_tag.values[0]) + new_protocol_time = None + if len(protocol_tag.values) > 1: + new_protocol_time = datetime.strptime(protocol_tag.values[1], "%H:%M") + Protocol.create_new_protocol(protocol.protocoltype, + new_protocol_date, new_protocol_time) + # TOPs old_tops = list(protocol.tops) for top in old_tops: diff --git a/utils.py b/utils.py index f897a76f4f9f581997eba769dd477d73d3261ce9..95baf755c9a03172d0b8a9771a8f6860b0c0cadc 100644 --- a/utils.py +++ b/utils.py @@ -208,3 +208,18 @@ def fancy_join(values, sep1=" und ", sep2=", "): def footnote_hash(text, length=5): return str(sum(ord(c) * i for i, c in enumerate(text)) % 10**length) + +def parse_datetime_from_string(text): + text = text.strip() + for format in ("%d.%m.%Y", "%d.%m.%y", "%Y-%m-%d", + "%d. %B %Y", "%d. %b %Y", "%d. %B %y", "%d. %b %y"): + try: + return datetime.strptime(text, format) + except ValueError: + pass + for format in ("%d.%m.", "%d. %m.", "%d.%m", "%d.%m"): + try: + return datetime.strptime(text, format).replace(year=datetime.now().year) + except ValueError as exc: + print(exc) + raise ValueError("Date '{}' does not match any known format!".format(text))