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)
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 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()