Commit 02d94273 authored by Robin Sonnabend's avatar Robin Sonnabend
Browse files

Add tag [sitzung;<date>[;<time>]]

This creates a new protocol of the current type on the given date and
optional time.

/close #155
parent efa48233
...@@ -326,6 +326,28 @@ class Protocol(DatabaseModel): ...@@ -326,6 +326,28 @@ class Protocol(DatabaseModel):
tops_before.append(top) tops_before.append(top)
return tops_before + self.tops + tops_after 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") @event.listens_for(Protocol, "before_delete")
def on_protocol_delete(mapper, connection, protocol): def on_protocol_delete(mapper, connection, protocol):
protocol.delete_orphan_todos() protocol.delete_orphan_todos()
......
...@@ -269,6 +269,7 @@ class Tag: ...@@ -269,6 +269,7 @@ class Tag:
elif self.name == "footnote": elif self.name == "footnote":
return '<sup id="#fnref{0}"><a href="#fn{0}">Fn</a></sup>'.format( return '<sup id="#fnref{0}"><a href="#fn{0}">Fn</a></sup>'.format(
footnote_hash(self.values[0])) footnote_hash(self.values[0]))
return "[{}: {}]".format(self.name, ";".join(self.values))
else: else:
raise _not_implemented(self, render_type) raise _not_implemented(self, render_type)
...@@ -294,7 +295,7 @@ class Tag: ...@@ -294,7 +295,7 @@ class Tag:
# v3: also match [] without semicolons inbetween, as there is not other use for that # v3: also match [] without semicolons inbetween, as there is not other use for that
PATTERN = r"\[(?<content>[^\]]*)\]" PATTERN = r"\[(?<content>[^\]]*)\]"
KNOWN_TAGS = ["todo", "url", "beschluss", "footnote"] KNOWN_TAGS = ["todo", "url", "beschluss", "footnote", "sitzung"]
class Empty(Element): class Empty(Element):
......
...@@ -490,20 +490,8 @@ def new_protocol(): ...@@ -490,20 +490,8 @@ def new_protocol():
if protocoltype is None or not protocoltype.has_modify_right(user): if protocoltype is None or not protocoltype.has_modify_right(user):
flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error") flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error")
return redirect(request.args.get("next") or url_for("index")) return redirect(request.args.get("next") or url_for("index"))
protocol = Protocol(protocoltype_id=protocoltype.id) protocol = Protocol.create_new_protocol(protocoltype,
form.populate_obj(protocol) form.date.data, form.start_time.data)
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)
return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
type_id = request.args.get("protocoltype_id") type_id = request.args.get("protocoltype_id")
if type_id is not None: if type_id is not None:
...@@ -516,7 +504,7 @@ def new_protocol(): ...@@ -516,7 +504,7 @@ def new_protocol():
def show_protocol(protocol): def show_protocol(protocol):
user = current_user() user = current_user()
errors_table = ErrorsTable(protocol.errors) 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") flash("Die fehlen die nötigen Zugriffsrechte.", "alert-error")
return redirect(request.args.get("next") or url_for("login", next=request.url)) return redirect(request.args.get("next") or url_for("login", next=request.url))
visible_documents = [ visible_documents = [
......
...@@ -12,7 +12,7 @@ from models.database import Document, Protocol, Error, Todo, Decision, TOP, Defa ...@@ -12,7 +12,7 @@ from models.database import Document, Protocol, Error, Todo, Decision, TOP, Defa
from models.errors import DateNotMatchingException from models.errors import DateNotMatchingException
from server import celery, app 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 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 protoparser import parse, ParserException, Element, Content, Text, Tag, Remark, Fork, RenderType
from wiki import WikiClient, WikiException from wiki import WikiClient, WikiException
from calendarpush import Client as CalendarClient, CalendarException from calendarpush import Client as CalendarClient, CalendarException
...@@ -379,6 +379,49 @@ def parse_protocol_async_inner(protocol, encoded_kwargs): ...@@ -379,6 +379,49 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
footnote_tags = [tag for tag in tags if tag.name == "footnote"] 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] 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 # TOPs
old_tops = list(protocol.tops) old_tops = list(protocol.tops)
for top in old_tops: for top in old_tops:
......
...@@ -208,3 +208,18 @@ def fancy_join(values, sep1=" und ", sep2=", "): ...@@ -208,3 +208,18 @@ def fancy_join(values, sep1=" und ", sep2=", "):
def footnote_hash(text, length=5): def footnote_hash(text, length=5):
return str(sum(ord(c) * i for i, c in enumerate(text)) % 10**length) 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))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment