def print_js_classes(proto_path, dest):
    with open(proto_path, "rb") as proto_file:
        global_scope = protoparser.parse(proto_file.read())
        for c in global_scope.service.commands:
            print_js_class(dest, global_scope.service, c, c.response_arg)
        for e in global_scope.service.events:
            print_js_class(dest, global_scope.service, e, e.response_arg)
Example #2
0
def print_js_classes(proto_path, dest):
    with open(proto_path, "rb") as proto_file:
        global_scope = protoparser.parse(proto_file.read())
        for c in global_scope.service.commands:
            print_js_class(dest, global_scope.service, c, c.response_arg)
        for e in global_scope.service.events:
            print_js_class(dest, global_scope.service, e, e.response_arg)
Example #3
0
def get_scope_services(proto_paths, dest):
    services = {}
    for path in proto_paths:
        with open(path, "rb") as fp:
            g_scope = protoparser.parse(fp.read())
            service = services.setdefault(g_scope.service.name, {})
            service[g_scope.service.version] = ServiceDoc(g_scope, path, dest)
    return services
def print_msg_defs(proto_path, dest):
    with open(proto_path, "rb") as proto_file:
        global_scope = protoparser.parse(proto_file.read())
        for c in global_scope.service.commands:
            print_msg_def(dest, global_scope.service, "commands", c, c.request_arg)
            print_msg_def(dest, global_scope.service, "responses", c, c.response_arg)
        for e in global_scope.service.events:
            print_msg_def(dest, global_scope.service, "events", e, e.response_arg)
def get_scope_services(proto_paths, dest):
    services = {}
    for path in proto_paths:
        with open(path, "rb") as fp:
            g_scope = protoparser.parse(fp.read())
            service = services.setdefault(g_scope.service.name, {})
            service[g_scope.service.version] = ServiceDoc(g_scope, path, dest)
    return services
Example #6
0
def print_msg_defs(proto_path, dest):
    with open(proto_path, "rb") as proto_file:
        global_scope = protoparser.parse(proto_file.read())
        for c in global_scope.service.commands:
            print_msg_def(dest, global_scope.service, "commands", c,
                          c.request_arg)
            print_msg_def(dest, global_scope.service, "responses", c,
                          c.response_arg)
        for e in global_scope.service.events:
            print_msg_def(dest, global_scope.service, "events", e,
                          e.response_arg)
Example #7
0
def parse_protocol_async_inner(protocol):
    old_errors = list(protocol.errors)
    for error in old_errors:
        protocol.errors.remove(error)
    db.session.commit()
    if protocol.source is None or len(protocol.source.strip()) == 0:
        return _make_error(protocol, "Parsing", "Protocol source is empty", "")
    if protocol.source == config.EMPTY_ETHERPAD:
        return _make_error(
            protocol, "Parsing", "The etherpad is unmodified and does not "
            "contain a protocol.", protocol.source)
    tree = None
    try:
        tree = parse(protocol.source)
    except ParserException as exc:
        context = ""
        if exc.linenumber is not None:
            source_lines = protocol.source.splitlines()
            start_index = max(0, exc.linenumber - config.ERROR_CONTEXT_LINES)
            end_index = min(
                len(source_lines) - 1,
                exc.linenumber + config.ERROR_CONTEXT_LINES)
            context = "\n".join(source_lines[start_index:end_index])
        if exc.tree is not None:
            context += "\n\nParsed syntax tree was:\n" + str(exc.tree.dump())
        return _make_error(protocol, "Parsing", str(exc), context)
    remarks = {
        element.name: element
        for element in tree.children if isinstance(element, Remark)
    }
    required_fields = copy(KNOWN_KEYS)
    for default_meta in protocol.protocoltype.metas:
        required_fields.append(default_meta.key)
    if not config.PARSER_LAZY:
        missing_fields = [
            field for field in required_fields if field not in remarks
        ]
        if len(missing_fields) > 0:
            return _make_error(protocol, "Parsing",
                               "Du hast vergessen, Metadaten anzugeben.",
                               ", ".join(missing_fields))
    try:
        protocol.fill_from_remarks(remarks)
    except ValueError:
        return _make_error(
            protocol, "Parsing", "Invalid fields",
            "Date or time fields are not '%d.%m.%Y' respectively '%H:%M', "
            "but rather {}".format(", ".join([
                remarks["Datum"].value.strip(),
                remarks["Beginn"].value.strip(), remarks["Ende"].value.strip()
            ])))
    except DateNotMatchingException as exc:
        return _make_error(
            protocol, "Parsing", "Date not matching",
            "This protocol's date should be {}, but the protocol source "
            "says {}.".format(
                date_filter(exc.original_date)
                if exc.original_date is not None else "not present",
                date_filter(exc.protocol_date)
                if exc.protocol_date is not None else "not present"))
    # tags
    tags = tree.get_tags()
    public_elements = tree.get_visible_elements(show_private=False)
    for tag in tags:
        if tag.name not in Tag.KNOWN_TAGS:
            return _make_error(
                protocol, "Parsing", "Invalid tag",
                "The tag in line {} has the kind '{}', which is "
                "not defined. This is probably an error mit a missing "
                "semicolon.".format(tag.linenumber, tag.name))
    # todos
    old_todo_number_map = {}
    for todo in protocol.todos:
        old_todo_number_map[todo.description] = todo.get_id()
    protocol.delete_orphan_todos()
    db.session.commit()
    old_todos = list(protocol.todos)
    todo_tags = [tag for tag in tags if tag.name == "todo"]
    raw_todos = []
    for todo_tag in todo_tags:
        if len(todo_tag.values) < 2:
            return _make_error(
                protocol, "Parsing", "Invalid todo-tag",
                "The todo tag in line {} needs at least "
                "information on who and what, "
                "but has less than that. This is probably "
                "a missing semicolon.".format(todo_tag.linenumber))
        who = todo_tag.values[0]
        what = todo_tag.values[1]
        field_id = None
        field_state = None
        field_date = None
        for other_field in todo_tag.values[2:]:
            other_field = other_field.strip()
            if len(other_field) == 0:
                continue
            if other_field.startswith(ID_FIELD_BEGINNING):
                try:
                    field_id = int(other_field[len(ID_FIELD_BEGINNING):])
                except ValueError:
                    return _make_error(
                        protocol, "Parsing", "Non-numerical todo ID",
                        "The todo in line {} has a nonnumerical ID, but needs "
                        "something like \"id 1234\"".format(
                            todo_tag.linenumber))
            else:
                try:
                    field_state = TodoState.from_name(other_field)
                    continue
                except ValueError:
                    pass
                try:
                    field_date = datetime.strptime(other_field, "%d.%m.%Y")
                    continue
                except ValueError:
                    pass
                try:
                    field_state, field_date = TodoState.from_name_with_date(
                        other_field.strip(), protocol=protocol)
                    continue
                except ValueError:
                    pass
                try:
                    field_state = TodoState.from_name_lazy(other_field)
                except ValueError:
                    return _make_error(
                        protocol, "Parsing", "Invalid field",
                        "The todo in line {} has the field '{}', but "
                        "this does neither match a date (\"%d.%m.%Y\") "
                        "nor a state.".format(todo_tag.linenumber,
                                              other_field))
        raw_todos.append(
            (who, what, field_id, field_state, field_date, todo_tag))
    for (_, _, field_id, _, _, _) in raw_todos:
        if field_id is not None:
            old_todos = [todo for todo in old_todos if todo.id != field_id]
    for todo in old_todos:
        protocol.todos.remove(todo)
    db.session.commit()
    for (who, what, field_id, field_state, field_date, todo_tag) in raw_todos:
        if field_state is None:
            field_state = TodoState.open
        if field_state.needs_date() and field_date is None:
            return _make_error(
                protocol, "Parsing", "Todo missing date",
                "The todo in line {} has a state that needs a date, "
                "but the todo does not have one.".format(todo_tag.linenumber))
        who = who.strip()
        what = what.strip()
        todo = None
        if field_id is not None:
            todo = Todo.query.filter_by(number=field_id).first()
            if todo is None and not config.PARSER_LAZY:
                return _make_error(
                    protocol, "Parsing", "Invalid Todo ID",
                    "The todo in line {} has the ID {}, but there is no "
                    "Todo with that ID.".format(todo_tag.linenumber, field_id))
        if todo is None and field_id is None and what in old_todo_number_map:
            todo = Todo(protocoltype_id=protocol.protocoltype.id,
                        who=who,
                        description=what,
                        state=field_state,
                        date=field_date,
                        number=old_todo_number_map[what])
            db.session.add(todo)
            db.session.commit()
        if todo is None:
            protocol_key = protocol.get_identifier()
            old_candidates = OldTodo.query.filter(
                OldTodo.protocol_key == protocol_key).all()
            if len(old_candidates) == 0:
                # new protocol
                todo = Todo(protocoltype_id=protocol.protocoltype.id,
                            who=who,
                            description=what,
                            state=field_state,
                            date=field_date)
                db.session.add(todo)
                db.session.commit()
                todo.number = field_id or todo.id
                db.session.commit()
            else:
                # old protocol
                number = field_id or lookup_todo_id(old_candidates, who, what)
                todo = Todo.query.filter_by(number=number).first()
                if todo is None:
                    todo = Todo(protocoltype_id=protocol.protocoltype.id,
                                who=who,
                                description=what,
                                state=field_state,
                                date=field_date,
                                number=number)
                    db.session.add(todo)
                    db.session.commit()
        todo.protocols.append(protocol)
        is_newest_protocol = True
        for other_protocol in todo.protocols:
            if other_protocol.date > protocol.date:
                is_newest_protocol = False
                break
        if is_newest_protocol:
            todo.state = field_state
            todo.date = field_date
            todo.who = who
            todo.description = what
        db.session.commit()
        todo_tag.todo = todo
    # Decisions
    decision_tags = [tag for tag in tags if tag.name == "beschluss"]
    for decision_tag in decision_tags:
        if decision_tag not in public_elements:
            return _make_error(
                protocol, "Parsing", "Decision in private context.",
                "The decision in line {} is in a private context, but "
                "decisions are and have to be public. "
                "Please move it to a public spot.".format(
                    decision_tag.linenumber))
    old_decisions = list(protocol.decisions)
    for decision in old_decisions:
        protocol.decisions.remove(decision)
    db.session.commit()
    decisions_to_render = []
    for decision_tag in decision_tags:
        if len(decision_tag.values) == 0:
            return _make_error(
                protocol, "Parsing", "Empty decision found.",
                "The decision in line {} is empty.".format(
                    decision_tag.linenumber))
        decision_content = decision_tag.values[0]
        decision_categories = []
        for decision_category_name in decision_tag.values[1:]:
            decision_category = DecisionCategory.query.filter_by(
                protocoltype_id=protocol.protocoltype.id,
                name=decision_category_name).first()
            if decision_category is None:
                category_candidates = DecisionCategory.query.filter_by(
                    protocoltype_id=protocol.protocoltype.id).all()
                category_names = [
                    "'{}'".format(category.name)
                    for category in category_candidates
                ]
                return _make_error(
                    protocol, "Parsing", "Unknown decision category",
                    "The decision in line {} has the category {}, "
                    "but there is no such category. "
                    "Known categories are {}".format(
                        decision_tag.linenumber, decision_category_name,
                        ", ".join(category_names)))
            else:
                decision_categories.append(decision_category)
        decision = Decision(protocol_id=protocol.id, content=decision_content)
        db.session.add(decision)
        db.session.commit()
        for decision_category in decision_categories:
            decision.categories.append(decision_category)
        decision_tag.decision = decision
        decisions_to_render.append((decision, decision_tag))
    for decision, decision_tag in decisions_to_render:
        decision_top = decision_tag.fork.get_top()
        decision_content = texenv.get_template(
            provide_latex_template(protocol.protocoltype.latex_template,
                                   "decision")).render(
                                       render_type=RenderType.latex,
                                       decision=decision,
                                       protocol=protocol,
                                       top=decision_top,
                                       show_private=True)
        maxdepth = decision_top.get_maxdepth()
        compile_decision(decision_content, decision, maxdepth=maxdepth)

    # Footnotes
    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}:
            return _make_error(
                protocol, "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))
        else:
            try:
                parse_datetime_from_string(protocol_tag.values[0])
            except ValueError as exc:
                return _make_error(
                    protocol, "Parsing", "Invalides Datum",
                    "'{}' ist kein valides Datum.".format(
                        protocol_tag.values[0]))
            if len(protocol_tag.values) > 1:
                try:
                    datetime.strptime(protocol_tag.values[1], "%H:%M")
                except ValueError:
                    return _make_error(
                        protocol, "Parsing", "Invalide Uhrzeit",
                        "'{}' ist keine valide Uhrzeit.".format(
                            protocol_tag.values[1]))
    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")
        if not protocol.protocoltype.get_protocols_on_date(new_protocol_date):
            Protocol.create_new_protocol(protocol.protocoltype,
                                         new_protocol_date, new_protocol_time)

    # TOPs
    old_tops = list(protocol.tops)
    tops = []
    for index, fork in enumerate(
        (child for child in tree.children if isinstance(child, Fork))):
        top = TOP(protocol_id=protocol.id,
                  name=fork.name,
                  number=index,
                  planned=False)
        if top.name is None:
            return _make_error(protocol, "Parsing", "TOP-Name fehlt",
                               "'{Name' sollte '{TOP Name' lauten.")
        tops.append(top)
    for top in old_tops:
        protocol.tops.remove(top)
    for top in tops:
        db.session.add(top)
    db.session.commit()

    # render
    private_render_kwargs = {
        "protocol": protocol,
        "tree": tree,
        "footnotes": footnote_tags,
    }
    public_render_kwargs = copy(private_render_kwargs)
    public_render_kwargs["footnotes"] = public_footnote_tags
    render_kwargs = {True: private_render_kwargs, False: public_render_kwargs}

    maxdepth = tree.get_maxdepth()
    privacy_states = [False]
    content_private = render_template("protocol.txt",
                                      render_type=RenderType.plaintext,
                                      show_private=True,
                                      **private_render_kwargs)
    content_public = render_template("protocol.txt",
                                     render_type=RenderType.plaintext,
                                     show_private=False,
                                     **public_render_kwargs)
    if content_private != content_public:
        privacy_states.append(True)
    protocol.content_private = content_private
    protocol.content_public = content_public
    protocol.content_html_private = render_template(
        "protocol.html",
        render_type=RenderType.html,
        show_private=True,
        **private_render_kwargs)
    protocol.content_html_public = render_template("protocol.html",
                                                   render_type=RenderType.html,
                                                   show_private=False,
                                                   **public_render_kwargs)

    for show_private in privacy_states:
        latex_source = texenv.get_template(
            provide_latex_template(protocol.protocoltype.latex_template,
                                   "protocol")).render(
                                       render_type=RenderType.latex,
                                       show_private=show_private,
                                       **render_kwargs[show_private])
        compile(latex_source,
                protocol,
                show_private=show_private,
                maxdepth=maxdepth)

    if protocol.protocoltype.use_wiki:
        wiki_type = WikiType[getattr(config, "WIKI_TYPE", "MEDIAWIKI")]
        wiki_template = {
            WikiType.MEDIAWIKI: "protocol.wiki",
            WikiType.DOKUWIKI: "protocol.dokuwiki",
        }
        wiki_render_type = {
            WikiType.MEDIAWIKI: RenderType.wikitext,
            WikiType.DOKUWIKI: RenderType.dokuwiki,
        }
        show_private = not protocol.protocoltype.wiki_only_public
        wiki_source = wikienv.get_template(wiki_template[wiki_type]).render(
            render_type=wiki_render_type[wiki_type],
            show_private=show_private,
            **render_kwargs[show_private]).replace("\n\n\n", "\n\n")
        if wiki_type == WikiType.MEDIAWIKI:
            wiki_infobox_source = wikienv.get_template("infobox.wiki").render(
                protocoltype=protocol.protocoltype)
            push_to_wiki(protocol, wiki_source, wiki_infobox_source,
                         "Automatisch generiert vom Protokollsystem 3.0")
        elif wiki_type == WikiType.DOKUWIKI:
            push_to_dokuwiki(protocol, wiki_source,
                             "Automatisch generiert vom Protokollsystem 3.0")
    protocol.done = True
    db.session.commit()