From 7563f1058b49a8bfaa37fc4489b3c8c35e86c3a7 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Tue, 19 May 2015 15:03:31 +0100 Subject: [PATCH] Make the templating system work(!) --- .gitignore | 1 + templating/build.py | 9 ++- templating/internal/__init__.py | 3 + templating/internal/sections.py | 21 +++++-- templating/internal/units.py | 92 ++++++++++++++++++++++++++++++- templating/templates/events.tmpl | 4 +- templating/templates/skeleton.rst | 6 ++ 7 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 templating/templates/skeleton.rst diff --git a/.gitignore b/.gitignore index c838ab29..b362f22c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ scripts/gen +*.pyc diff --git a/templating/build.py b/templating/build.py index 4510fa65..14941cb0 100755 --- a/templating/build.py +++ b/templating/build.py @@ -55,6 +55,9 @@ def load_sections(env, units): def create_from_skeleton(skeleton, sections): print "Creating spec from skeleton..." + print "Section keys: %s" % (sections.keys()) + return skeleton.render(sections.data) + def check_unaccessed(name, store): unaccessed_keys = store.get_unaccessed_set() @@ -80,12 +83,14 @@ def main(): sections = load_sections(env, units) # combine all the RST sections into a coherent spec - skeleton = "foo" + skeleton = env.get_template("skeleton.rst") spec = create_from_skeleton(skeleton, sections) check_unaccessed("units", units) check_unaccessed("sections", sections) - print spec + + with open("spec.rst", "w") as f: + f.write(spec) if __name__ == '__main__': diff --git a/templating/internal/__init__.py b/templating/internal/__init__.py index e14e1ecd..7a9c7a22 100644 --- a/templating/internal/__init__.py +++ b/templating/internal/__init__.py @@ -9,6 +9,9 @@ class AccessKeyStore(object): self.data = {} self.accessed_set = Set() + def keys(self): + return self.data.keys() + def add(self, key, unit_dict): self.data[key] = unit_dict diff --git a/templating/internal/sections.py b/templating/internal/sections.py index 758e0b6f..9a6d3bfc 100644 --- a/templating/internal/sections.py +++ b/templating/internal/sections.py @@ -4,15 +4,26 @@ import os def _render_section_room_events(env, units): template = env.get_template("events.tmpl") - return template.render(example=example, event=event) + examples = units.get("event-examples") + schemas = units.get("event-schemas") + sections = [] + for event_name in schemas: + sections.append(template.render( + example=examples[event_name], + event=schemas[event_name] + )) + return "\n\n".join(sections) SECTION_DICT = { - "room-events": _render_section_room_events + "room_events": _render_section_room_events } def load(env, units): store = AccessKeyStore() - for unit_key in SECTION_DICT: - unit = SECTION_DICT[unit_key](env, units) - store.add(unit_key, unit) + for section_key in SECTION_DICT: + section = SECTION_DICT[section_key](env, units) + print "Generated section '%s' : %s" % ( + section_key, section[:60].replace("\n","") + ) + store.add(section_key, section) return store \ No newline at end of file diff --git a/templating/internal/units.py b/templating/internal/units.py index cae113ff..cdade683 100644 --- a/templating/internal/units.py +++ b/templating/internal/units.py @@ -1,18 +1,101 @@ """Contains all the units for the spec.""" from . import AccessKeyStore +import json import os +def prop(obj, path): + # Helper method to extract nested property values + nested_keys = path.split("/") + val = obj + for key in nested_keys: + val = val.get(key, {}) + return val + def _load_examples(): path = "../event-schemas/examples" examples = {} for filename in os.listdir(path): - with open(filename, "r") as f: - print filename + if not filename.startswith("m."): + continue + with open(os.path.join(path, filename), "r") as f: + examples[filename] = json.loads(f.read()) + if filename == "m.room.message_m.text": + examples["m.room.message"] = examples[filename] return examples +def _load_schemas(): + path = "../event-schemas/schema" + schemata = {} + + def format_for_obj(obj): + obj_type = "<%s>" % obj.get("type") + if obj_type == "": + if obj.get("properties"): + format = {} + for key in obj.get("properties"): + format[key] = format_for_obj(obj.get("properties")[key]) + return format + elif obj.get("additionalProperties"): + return { + "": ( + "<%s>" % obj.get("additionalProperties").get("type") + ) + } + enum_text = "" + # add on enum info + enum = obj.get("enum") + if enum: + if len(enum) > 1: + obj_type = "" + enum_text = " (" + "|".join(enum) + ")" + else: + obj_type = enum[0] + + return obj_type + enum_text + + for filename in os.listdir(path): + if not filename.startswith("m."): + continue + with open(os.path.join(path, filename), "r") as f: + json_schema = json.loads(f.read()) + schema = { + "typeof": None, + "type": None, + "summary": None, + "desc": None, + "json_format": None + } + + # add typeof + base_defs = { + "core#/definitions/room_event": "Room Event", + "core#/definitions/state_event": "State Event" + } + if type(json_schema.get("allOf")) == list: + schema["typeof"] = base_defs.get( + json_schema["allOf"][0].get("$ref") + ) + + # add type + schema["type"] = prop(json_schema, "properties/type/enum")[0] + + # add summary and desc + schema["summary"] = json_schema.get("title") + schema["desc"] = json_schema.get("description") + + # add json_format + content_props = prop(json_schema, "properties/content") + if content_props: + schema["json_format"] = format_for_obj(content_props) + + + schemata[filename] = schema + return schemata + UNIT_DICT = { - "event-examples": _load_examples + "event-examples": _load_examples, + "event-schemas": _load_schemas } @@ -20,5 +103,8 @@ def load(): store = AccessKeyStore() for unit_key in UNIT_DICT: unit = UNIT_DICT[unit_key]() + print "Generated unit '%s' : %s" % ( + unit_key, json.dumps(unit)[:50].replace("\n","") + ) store.add(unit_key, unit) return store diff --git a/templating/templates/events.tmpl b/templating/templates/events.tmpl index 512f7a2e..fa70e5eb 100644 --- a/templating/templates/events.tmpl +++ b/templating/templates/events.tmpl @@ -1,7 +1,7 @@ {{event.type}} -------------- Summary: {{event.summary}} -Type: {{event.parent}} +Type: {{event.typeof}} Description: {{event.desc}} -JSON Format: {{event.content | jsonify}} +JSON Format: {{event.json_format | jsonify}} Example: {{example.content | jsonify}} diff --git a/templating/templates/skeleton.rst b/templating/templates/skeleton.rst new file mode 100644 index 00000000..1fd2d965 --- /dev/null +++ b/templating/templates/skeleton.rst @@ -0,0 +1,6 @@ +This is the skeleton of the spec. + +{{room_events}} + + +Here a footer thingy. \ No newline at end of file