We don'e need `{{server_server_changelog_r0.1.0}}` (for example), so don't go through the hassle of generating it. Instead, we'll generate the changelog for the requested versions of each API and put that in place. In the future, we may wish to consider bringing back more complicated variables when/if we start generating released versions of the spec on the fly rather than manually.
220 lines
8.1 KiB
Python
220 lines
8.1 KiB
Python
# Copyright 2016 OpenMarket Ltd
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Contains all the sections for the spec."""
|
|
from batesian import AccessKeyStore
|
|
from batesian.sections import Sections
|
|
import inspect
|
|
import json
|
|
import os
|
|
import logging
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class MatrixSections(Sections):
|
|
|
|
# pass through git ver so it'll be dropped in the input file
|
|
def render_git_version(self):
|
|
return self.units.get("git_version")["string"]
|
|
|
|
def render_git_rev(self):
|
|
return self.units.get("git_version")["revision"]
|
|
|
|
def render_changelogs(self):
|
|
rendered = {}
|
|
changelogs = self.units.get("changelogs")
|
|
for spec, changelog_text in changelogs.items():
|
|
spec_var = "%s_changelog" % spec
|
|
logger.info("Rendering changelog for spec: %s" % spec)
|
|
rendered[spec_var] = changelog_text
|
|
return rendered
|
|
|
|
def _render_events(self, filterFn, sortFn):
|
|
template = self.env.get_template("events.tmpl")
|
|
examples = self.units.get("event_examples")
|
|
schemas = self.units.get("event_schemas")
|
|
subtitle_title_char = self.units.get("spec_targets")[
|
|
"relative_title_styles"
|
|
]["subtitle"]
|
|
sections = []
|
|
for event_name in sortFn(schemas):
|
|
if not filterFn(event_name):
|
|
continue
|
|
sections.append(template.render(
|
|
examples=examples[event_name],
|
|
event=schemas[event_name],
|
|
title_kind=subtitle_title_char
|
|
))
|
|
return "\n\n".join(sections)
|
|
|
|
def _render_http_api_group(self, group, sortPathList=None):
|
|
template = self.env.get_template("http-api.tmpl")
|
|
http_api = self.units.get("swagger_apis")[group]["__meta"]
|
|
subtitle_title_char = self.units.get("spec_targets")[
|
|
"relative_title_styles"
|
|
]["subtitle"]
|
|
sections = []
|
|
endpoints = []
|
|
if sortPathList:
|
|
# list of substrings to sort by
|
|
sorted_endpoints = []
|
|
for path_substr in sortPathList:
|
|
for e in http_api["endpoints"]:
|
|
if path_substr in e["path"]:
|
|
sorted_endpoints.append(e) # could have multiple
|
|
# dump rest
|
|
rest = [
|
|
e for e in http_api["endpoints"] if e not in sorted_endpoints
|
|
]
|
|
endpoints = sorted_endpoints + rest
|
|
else:
|
|
# sort alphabetically based on path
|
|
endpoints = http_api["endpoints"]
|
|
|
|
for endpoint in endpoints:
|
|
sections.append(template.render(
|
|
endpoint=endpoint,
|
|
title_kind=subtitle_title_char
|
|
))
|
|
return "\n\n".join(sections)
|
|
|
|
|
|
# Special function: Returning a dict will specify multiple sections where
|
|
# the key is the section name and the value is the value of the section
|
|
def render_group_http_apis(self):
|
|
# map all swagger_apis to the form $GROUP_http_api
|
|
swagger_groups = self.units.get("swagger_apis").keys()
|
|
renders = {}
|
|
for group in swagger_groups:
|
|
sortFnOrPathList = None
|
|
if group == "presence_cs":
|
|
sortFnOrPathList = ["status"]
|
|
elif group == "profile_cs":
|
|
sortFnOrPathList=["displayname", "avatar_url"]
|
|
renders[group + "_http_api"] = self._render_http_api_group(
|
|
group, sortFnOrPathList
|
|
)
|
|
return renders
|
|
|
|
# Special function: Returning a dict will specify multiple sections where
|
|
# the key is the section name and the value is the value of the section
|
|
def render_group_events(self):
|
|
# map all event schemata to the form $EVENTTYPE_event with s/./_/g
|
|
# e.g. m_room_topic_event
|
|
schemas = self.units.get("event_schemas")
|
|
renders = {}
|
|
for event_type in schemas:
|
|
renders[event_type.replace(".", "_") + "_event"] = self._render_events(
|
|
lambda x: x == event_type, sorted
|
|
)
|
|
return renders
|
|
|
|
def render_room_events(self):
|
|
def filterFn(eventType):
|
|
return (
|
|
eventType.startswith("m.room") and
|
|
not eventType.startswith("m.room.message#m.")
|
|
)
|
|
return self._render_events(filterFn, sorted)
|
|
|
|
def render_msgtype_events(self):
|
|
template = self.env.get_template("msgtypes.tmpl")
|
|
examples = self.units.get("event_examples")
|
|
schemas = self.units.get("event_schemas")
|
|
subtitle_title_char = self.units.get("spec_targets")[
|
|
"relative_title_styles"
|
|
]["subtitle"]
|
|
sections = []
|
|
msgtype_order = [
|
|
"m.room.message#m.text", "m.room.message#m.emote",
|
|
"m.room.message#m.notice", "m.room.message#m.image",
|
|
"m.room.message#m.file"
|
|
]
|
|
other_msgtypes = [
|
|
k for k in schemas.keys() if k.startswith("m.room.message#") and
|
|
k not in msgtype_order
|
|
]
|
|
for event_name in (msgtype_order + other_msgtypes):
|
|
if not event_name.startswith("m.room.message#m."):
|
|
continue
|
|
sections.append(template.render(
|
|
example=examples[event_name][0],
|
|
event=schemas[event_name],
|
|
title_kind=subtitle_title_char
|
|
))
|
|
return "\n\n".join(sections)
|
|
|
|
def render_voip_events(self):
|
|
def filterFn(eventType):
|
|
return eventType.startswith("m.call")
|
|
def sortFn(eventTypes):
|
|
ordering = [
|
|
"m.call.invite", "m.call.candidates", "m.call.answer",
|
|
"m.call.hangup"
|
|
]
|
|
rest = [
|
|
k for k in eventTypes if k not in ordering
|
|
]
|
|
return ordering + rest
|
|
return self._render_events(filterFn, sortFn)
|
|
|
|
def render_presence_events(self):
|
|
def filterFn(eventType):
|
|
return eventType.startswith("m.presence")
|
|
return self._render_events(filterFn, sorted)
|
|
|
|
def _render_ce_type(self, type):
|
|
template = self.env.get_template("common-event-fields.tmpl")
|
|
ce_types = self.units.get("common_event_fields")
|
|
subtitle_title_char = self.units.get("spec_targets")[
|
|
"relative_title_styles"
|
|
]["subtitle"]
|
|
return template.render(
|
|
common_event=ce_types[type], title_kind=subtitle_title_char
|
|
)
|
|
|
|
def render_common_event_fields(self):
|
|
return self._render_ce_type("event")
|
|
|
|
def render_common_room_event_fields(self):
|
|
return self._render_ce_type("room_event")
|
|
|
|
def render_common_state_event_fields(self):
|
|
return self._render_ce_type("state_event")
|
|
|
|
def render_apis(self):
|
|
template = self.env.get_template("apis.tmpl")
|
|
apis = self.units.get("apis")
|
|
return template.render(apis=apis)
|
|
|
|
def render_unstable_warnings(self):
|
|
rendered = {}
|
|
blocks = self.units.get("unstable_warnings")
|
|
for var, text in blocks.items():
|
|
rendered["unstable_warning_block_" + var] = text
|
|
return rendered
|
|
|
|
def render_swagger_definition(self):
|
|
rendered = {}
|
|
template = self.env.get_template("schema-definition.tmpl")
|
|
subtitle_title_char = self.units.get("spec_targets")[
|
|
"relative_title_styles"
|
|
]["subtitle"]
|
|
definitions = self.units.get("swagger_definitions")
|
|
for group, swagger_def in definitions.items():
|
|
rendered["definition_" + group] = template.render(
|
|
definition=swagger_def['definition'],
|
|
examples=swagger_def['examples'],
|
|
title_kind=subtitle_title_char)
|
|
return rendered
|