From 365a9076b93500cd87e85e68129e6ba7729f7625 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 1 Oct 2015 12:11:26 +0100 Subject: [PATCH] Add nested dict template support; Add x-pattern For cases where event schema specify `patternProperties` it would be nice to give that pattern a "human-readable" form rather than a raw regex. This is now supported by specifying `x-pattern` in the value part of the specified pattern e.g. `patternProperties:{ "^.*":{ x-pattern: "$THING", ... } }` Templating had limited record type descriptions limited to value primitives e.g. `{string: integer}`. It now supports inspecting the values recursively if the value is `object`. Updated `m.receipt` to take both these points into account to make it read better. Tweak receipt module text. --- event-schemas/schema/v1/m.receipt | 9 ++++--- specification/modules/receipts.rst | 37 ++++++++++++---------------- templating/matrix_templates/units.py | 26 +++++++++++++++---- 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/event-schemas/schema/v1/m.receipt b/event-schemas/schema/v1/m.receipt index 0f365eed..5be232ad 100644 --- a/event-schemas/schema/v1/m.receipt +++ b/event-schemas/schema/v1/m.receipt @@ -5,17 +5,20 @@ "properties": { "content": { "type": "object", - "description": "The event ids which the receipts relate to.", "patternProperties": { "^\\$": { "type": "object", - "description": "The types of the receipts.", + "x-pattern": "$EVENT_ID", + "description": "The mapping of event ID to receipt type. The event ID is the ID which the receipts relate to and *not* an ID for the receipt itself. The key in the object is an enum which must be ``read``.", "additionalProperties": { "type": "object", - "description": "User ids of the receipts", + "title": "Users", "patternProperties": { "^@": { "type": "object", + "title": "Receipt", + "description": "The mapping of user ID to receipt. The user ID is the entity who sent this receipt.", + "x-pattern": "$USER_ID", "properties": { "ts": { "type": "number", diff --git a/specification/modules/receipts.rst b/specification/modules/receipts.rst index e2f83eea..f32c12db 100644 --- a/specification/modules/receipts.rst +++ b/specification/modules/receipts.rst @@ -6,8 +6,16 @@ have interacted with. For example, which events the user has read. For efficiency this is done as "up to" markers, i.e. marking a particular event as, say, ``read`` indicates the user has read all events *up to* that event. -Client-Server API -~~~~~~~~~~~~~~~~~ +Events +------ + +{{m_receipt_event}} + +Client behaviour +---------------- + + - When clients should send receipts + - What clients should do when they receive these receipts Clients will receive receipts in the following format:: @@ -25,22 +33,6 @@ Clients will receive receipts in the following format:: } } -For example:: - - { - "type": "m.receipt", - "room_id": "!KpjVgQyZpzBwvMBsnT:matrix.org", - "content": { - "$1435641916114394fHBLK:matrix.org": { - "read": { - "@erikj:jki.re": { "ts": 1436451550453 }, - ... - } - }, - ... - } - } - For efficiency, receipts are batched into one event per room. In the initialSync and v2 sync APIs the receipts are listed in a separate top level ``receipts`` key. Each ``user_id``, ``receipt_type`` pair must be associated with only a @@ -56,9 +48,8 @@ A client can update the markers for its user by issuing a request:: Where the contents of the ``POST`` will be included in the content sent to other users. The server will automatically set the ``ts`` field. - -Server-Server API -~~~~~~~~~~~~~~~~~ +Server behaviour +---------------- Receipts are sent across federation as EDUs with type ``m.receipt``. The format of the EDUs are:: @@ -75,3 +66,7 @@ format of the EDUs are:: These are always sent as deltas to previously sent receipts. +Security considerations +----------------------- + + diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index 50fa784e..473fdd82 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -49,8 +49,17 @@ def get_json_schema_object_fields(obj, enforce_title=False): } tables = [fields] - props = obj.get("properties", obj.get("patternProperties")) parents = obj.get("allOf") + props = obj.get("properties") + if not props: + props = obj.get("patternProperties") + if props: + # try to replace horrible regex key names with pretty x-pattern ones + for key_name in props.keys(): + pretty_key = props[key_name].get("x-pattern") + if pretty_key: + props[pretty_key] = props[key_name] + del props[key_name] if not props and not parents: raise Exception( "Object %s has no properties or parents." % obj @@ -70,10 +79,17 @@ def get_json_schema_object_fields(obj, enforce_title=False): if props[key_name]["type"] == "object": if props[key_name].get("additionalProperties"): # not "really" an object, just a KV store - value_type = ( - "{string: %s}" % - props[key_name]["additionalProperties"]["type"] - ) + prop_val = props[key_name]["additionalProperties"]["type"] + if prop_val == "object": + nested_object = get_json_schema_object_fields( + props[key_name]["additionalProperties"], + enforce_title=True + ) + value_type = "{string: %s}" % nested_object[0]["title"] + if not nested_object[0].get("no-table"): + tables += nested_object + else: + value_type = "{string: %s}" % prop_val else: nested_object = get_json_schema_object_fields( props[key_name],