From 8a1a02a11bc63a93c5e43a594bebd813a27cefe2 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 15 Feb 2016 16:28:43 +0000 Subject: [PATCH 01/20] Update the predefined push rules in the spec --- specification/modules/push.rst | 230 ++++++++++++++++++++++++++++----- 1 file changed, 197 insertions(+), 33 deletions(-) diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 133b838a..d0c3968c 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -202,14 +202,70 @@ than "user-defined rules". The ``rule_id`` for all server-default rules MUST start with a dot (".") to identify them as "server-default". The following server-default rules are specified: + +Default Override Rules +^^^^^^^^^^^^^^^^^^^^^^ + +``m.rule.master`` + Matches all events, this can be enabled to turn off all push notifications + other than those generated by override rules set by the user. By default this + rule is disabled. + + Definition + +.. code:: json + + { + "rule_id": ".m.rule.master, + "default": true, + "enabled": false, + "conditions": [], + "actions": [ + "dont_notify" + ] + } + +``.m.rule.suppress_notices`` + Matches messages with a ``msgtype`` of ``notice``. This should be an + ``override`` rule so that it takes priority over ``content`` / ``sender`` / + ``room`` rules. + + Definition: + +.. code:: json + + { + "rule_id": ".m.rule.suppress_notices", + "default": true, + "enabled": true, + "conditions': [ + { + "kind": "event_match", + "key": "content.msgtype", + "pattern": "m.notice", + } + ], + "actions": [ + "dont_notify", + ] + } + + +Default Content Rules +^^^^^^^^^^^^^^^^^^^^^ + ``.m.rule.contains_user_name`` Matches any message whose content is unencrypted and contains the local part of the user's Matrix ID, separated by word boundaries. - Definition (as a ``content`` rule):: + Definition (as a ``content`` rule): + +.. code:: json { - "rule_id": ".m.rule.contains_user_name" + "rule_id": ".m.rule.contains_user_name", + "default": true, + "enabled": true, "pattern": "[the local part of the user's Matrix ID]", "actions": [ "notify", @@ -217,17 +273,56 @@ server-default rules are specified: "set_tweak": "sound", "value": "default" } - ], + ] } +Default Underride Rules +^^^^^^^^^^^^^^^^^^^^^^^ + +``.m.rule.call`` + Matches any incoming VOIP call. + + Definition: + +.. code:: json + + { + "rule_id": ".m.rule.call", + "default": true, + "enabled": true, + "conditions": [ + { + "key": "type", + "kind": "event_match", + "pattern": "m.call.invite" + } + ], + "actions": [ + "notify", + { + "set_tweak": "sound", + "value": "ring" + }, + { + "set_tweak": "highlight", + "value": false + } + ] + }, + + ``.m.rule.contains_display_name`` Matches any message whose content is unencrypted and contains the user's current display name in the room in which it was sent. - Definition (this rule can only be an ``override`` or ``underride`` rule):: + Definition: + +.. code:: json { - "rule_id": ".m.rule.contains_display_name" + "rule_id": ".m.rule.contains_display_name", + "default": true, + "enabled": true, "conditions": [ { "kind": "contains_display_name" @@ -238,21 +333,28 @@ server-default rules are specified: { "set_tweak": "sound", "value": "default" + }, + { + "set_tweak": "highlight" } - ], + ] } ``.m.rule.room_one_to_one`` Matches any message sent in a room with exactly two members. - Definition (this rule can only be an ``override`` or ``underride`` rule):: + Definition: + +.. code:: json { - "rule_id": ".m.rule.room_two_members" + "rule_id": ".m.rule.room_two_members", + "default": true, + "enabled": true, "conditions": [ { - "is": "2", "kind": "room_member_count" + "is": "2", } ], "actions": [ @@ -260,46 +362,108 @@ server-default rules are specified: { "set_tweak": "sound", "value": "default" + }, + { + "set_tweak": "highlight", + "value": false } ], } -``.m.rule.suppress_notices`` - Matches messages with a ``msgtype`` of ``notice``. This should be an - ``override`` rule so that it takes priority over ``content`` / ``sender`` / - ``room`` rules. +``.m.rule.invite_for_me`` + Matches any invites to a new room for this user. - Definition:: + Definition: + +.. code:: json { - 'rule_id': '.m.rule.suppress_notices', - 'conditions': [ + "rule_id": ".m.rule.invite_for_me", + "default": true, + "enabled": true, + "conditions": [ + { + "key": "type", + "kind": "event_match", + "pattern": "m.room.member" + }, { - 'kind': 'event_match', - 'key': 'content.msgtype', - 'pattern': 'm.notice', + "key": "content.membership", + "kind": "event_match", + "pattern": "invite" + }, + { + "key": "state_key", + "kind": "event_match", + "pattern": "@alice:example.com" } ], - 'actions': [ - 'dont-notify', + "actions": [ + "notify", + { + "set_tweak": "sound", + "value": "default" + }, + { + "set_tweak": "highlight", + "value": false + } ] } - -``.m.rule.fallback`` - Matches any message. Used to define the behaviour of messages that match no - other rules. If homeservers define this it should be the lowest priority - ``underride`` rule. - Definition:: +``.m.rule.member_event`` + Matches membership change events. - { - "rule_id": ".m.rule.fallback" - "conditions": [], - "actions": [ - "notify" + Definition: + +.. code:: json + + { + "rule_id": ".m.rule.member_event", + "default": true, + "enabled": true, + "conditions": [ + { + "key": "type", + "kind": "event_match", + "pattern": "m.room.member" + } ], - } + "actions": [ + "notify", + { + "set_tweak": "highlight", + "value": false + } + ] + } +``.m.rule.message`` + Matches all chat messages. + + Definition: + +.. code:: json + + { + "rule_id": ".m.rule.member_event", + "default": true, + "enabled": true, + "conditions": [ + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.message" + } + ], + "actions": [ + "notify", + { + "set_tweak": "highlight", + "value": false + } + ] + } Conditions From b16af5ef6454db3cf32eb28641947fe9787fb30c Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 15 Feb 2016 16:41:47 +0000 Subject: [PATCH 02/20] Fix JSON, add headers --- specification/modules/push.rst | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/specification/modules/push.rst b/specification/modules/push.rst index d0c3968c..11ce8154 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -207,6 +207,7 @@ Default Override Rules ^^^^^^^^^^^^^^^^^^^^^^ ``m.rule.master`` +````````````````` Matches all events, this can be enabled to turn off all push notifications other than those generated by override rules set by the user. By default this rule is disabled. @@ -216,7 +217,7 @@ Default Override Rules .. code:: json { - "rule_id": ".m.rule.master, + "rule_id": ".m.rule.master", "default": true, "enabled": false, "conditions": [], @@ -226,6 +227,7 @@ Default Override Rules } ``.m.rule.suppress_notices`` +```````````````````````````` Matches messages with a ``msgtype`` of ``notice``. This should be an ``override`` rule so that it takes priority over ``content`` / ``sender`` / ``room`` rules. @@ -238,7 +240,7 @@ Default Override Rules "rule_id": ".m.rule.suppress_notices", "default": true, "enabled": true, - "conditions': [ + "conditions": [ { "kind": "event_match", "key": "content.msgtype", @@ -255,6 +257,7 @@ Default Content Rules ^^^^^^^^^^^^^^^^^^^^^ ``.m.rule.contains_user_name`` +`````````````````````````````` Matches any message whose content is unencrypted and contains the local part of the user's Matrix ID, separated by word boundaries. @@ -280,6 +283,7 @@ Default Underride Rules ^^^^^^^^^^^^^^^^^^^^^^^ ``.m.rule.call`` +```````````````` Matches any incoming VOIP call. Definition: @@ -312,6 +316,7 @@ Default Underride Rules ``.m.rule.contains_display_name`` +````````````````````````````````` Matches any message whose content is unencrypted and contains the user's current display name in the room in which it was sent. @@ -341,6 +346,7 @@ Default Underride Rules } ``.m.rule.room_one_to_one`` +``````````````````````````` Matches any message sent in a room with exactly two members. Definition: @@ -367,10 +373,11 @@ Default Underride Rules "set_tweak": "highlight", "value": false } - ], + ] } ``.m.rule.invite_for_me`` +````````````````````````` Matches any invites to a new room for this user. Definition: @@ -412,6 +419,7 @@ Default Underride Rules } ``.m.rule.member_event`` +```````````````````````` Matches membership change events. Definition: @@ -439,6 +447,7 @@ Default Underride Rules } ``.m.rule.message`` +``````````````````` Matches all chat messages. Definition: From afe7638e302bbd45a5e1fa2ff11c2162216ce3d6 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 15 Feb 2016 16:50:15 +0000 Subject: [PATCH 03/20] Add a new title level to appease gendoc --- specification/targets.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/targets.yaml b/specification/targets.yaml index 98ca9322..4b08d6ef 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -42,7 +42,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/event_context.rst -title_styles: ["=", "-", "~", "+", "^", "`", "@"] +title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"] # The templating system doesn't know the right title style to use when generating # RST. These symbols are 'relative' to say "make a sub-title" (-1), "make a title From 5d85e3a505f81d2c7ece4e7398deca8f2361d3a1 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 15 Feb 2016 16:53:08 +0000 Subject: [PATCH 04/20] Remove indents --- specification/modules/push.rst | 48 +++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 11ce8154..f3690159 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -208,11 +208,11 @@ Default Override Rules ``m.rule.master`` ````````````````` - Matches all events, this can be enabled to turn off all push notifications - other than those generated by override rules set by the user. By default this - rule is disabled. +Matches all events, this can be enabled to turn off all push notifications +other than those generated by override rules set by the user. By default this +rule is disabled. - Definition +Definition .. code:: json @@ -228,11 +228,11 @@ Default Override Rules ``.m.rule.suppress_notices`` ```````````````````````````` - Matches messages with a ``msgtype`` of ``notice``. This should be an - ``override`` rule so that it takes priority over ``content`` / ``sender`` / - ``room`` rules. +Matches messages with a ``msgtype`` of ``notice``. This should be an +``override`` rule so that it takes priority over ``content`` / ``sender`` / +``room`` rules. - Definition: +Definition: .. code:: json @@ -258,10 +258,10 @@ Default Content Rules ``.m.rule.contains_user_name`` `````````````````````````````` - Matches any message whose content is unencrypted and contains the local part - of the user's Matrix ID, separated by word boundaries. +Matches any message whose content is unencrypted and contains the local part +of the user's Matrix ID, separated by word boundaries. - Definition (as a ``content`` rule): +Definition (as a ``content`` rule): .. code:: json @@ -284,9 +284,9 @@ Default Underride Rules ``.m.rule.call`` ```````````````` - Matches any incoming VOIP call. +Matches any incoming VOIP call. - Definition: +Definition: .. code:: json @@ -317,10 +317,10 @@ Default Underride Rules ``.m.rule.contains_display_name`` ````````````````````````````````` - Matches any message whose content is unencrypted and contains the user's - current display name in the room in which it was sent. +Matches any message whose content is unencrypted and contains the user's +current display name in the room in which it was sent. - Definition: +Definition: .. code:: json @@ -347,9 +347,9 @@ Default Underride Rules ``.m.rule.room_one_to_one`` ``````````````````````````` - Matches any message sent in a room with exactly two members. +Matches any message sent in a room with exactly two members. - Definition: +Definition: .. code:: json @@ -378,9 +378,9 @@ Default Underride Rules ``.m.rule.invite_for_me`` ````````````````````````` - Matches any invites to a new room for this user. +Matches any invites to a new room for this user. - Definition: +Definition: .. code:: json @@ -420,9 +420,9 @@ Default Underride Rules ``.m.rule.member_event`` ```````````````````````` - Matches membership change events. +Matches membership change events. - Definition: +Definition: .. code:: json @@ -448,9 +448,9 @@ Default Underride Rules ``.m.rule.message`` ``````````````````` - Matches all chat messages. +Matches all chat messages. - Definition: +Definition: .. code:: json From 8a050aebc0e085455ff99aad663d39e1efecddae Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 15 Feb 2016 17:17:58 +0000 Subject: [PATCH 05/20] Add a note to the docs for before and after to make it clear that they cannot be used with the predefined rules --- api/client-server/pushrules.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/client-server/pushrules.yaml b/api/client-server/pushrules.yaml index 07bd6bdb..2aba7bd9 100644 --- a/api/client-server/pushrules.yaml +++ b/api/client-server/pushrules.yaml @@ -380,7 +380,8 @@ paths: x-example: someRuleId description: |- Use 'before' with a ``rule_id`` as its value to make the new rule the - next-most important rule with respect to the given rule. + next-most important rule with respect to the given user defined rule. + It is not possible to add a rule relative to a predefined server rule. - in: query type: string name: after @@ -388,7 +389,8 @@ paths: x-example: anotherRuleId description: |- This makes the new rule the next-less important rule relative to the - given rule. + given user defined rule. It is not possible to add a rule relative + to a predefined server rule. - in: body name: pushrule description: |- From 740f7759324d8d6b7dcab1fc14f0c10b7408519f Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 18 Feb 2016 18:36:08 +0000 Subject: [PATCH 06/20] Fix a couple of typos, remove .m.rule.member_event --- specification/modules/push.rst | 38 +++++----------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/specification/modules/push.rst b/specification/modules/push.rst index f3690159..363d1a66 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -354,13 +354,13 @@ Definition: .. code:: json { - "rule_id": ".m.rule.room_two_members", + "rule_id": ".m.rule.room_one_to_one", "default": true, "enabled": true, "conditions": [ { - "kind": "room_member_count" - "is": "2", + "kind": "room_member_count", + "is": "2" } ], "actions": [ @@ -402,7 +402,7 @@ Definition: { "key": "state_key", "kind": "event_match", - "pattern": "@alice:example.com" + "pattern": "[the user's Matrix ID]" } ], "actions": [ @@ -418,34 +418,6 @@ Definition: ] } -``.m.rule.member_event`` -```````````````````````` -Matches membership change events. - -Definition: - -.. code:: json - - { - "rule_id": ".m.rule.member_event", - "default": true, - "enabled": true, - "conditions": [ - { - "key": "type", - "kind": "event_match", - "pattern": "m.room.member" - } - ], - "actions": [ - "notify", - { - "set_tweak": "highlight", - "value": false - } - ] - } - ``.m.rule.message`` ``````````````````` Matches all chat messages. @@ -455,7 +427,7 @@ Definition: .. code:: json { - "rule_id": ".m.rule.member_event", + "rule_id": ".m.rule.message", "default": true, "enabled": true, "conditions": [ From cbe466e5729a06ae4b036714ae7d1c555579768c Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 23 Feb 2016 09:00:55 +0000 Subject: [PATCH 07/20] Update API docs --- api/client-server/presence.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/api/client-server/presence.yaml b/api/client-server/presence.yaml index d9a1b866..fc47029c 100644 --- a/api/client-server/presence.yaml +++ b/api/client-server/presence.yaml @@ -49,11 +49,14 @@ paths: properties: presence: type: string - enum: ["online", "offline", "unavailable", "free_for_chat"] + enum: ["online", "offline", "unavailable"] description: The new presence state. status_msg: type: string description: "The status message to attach to this state." + currently_online: + type: boolean + description: "Whether the user is currently active" required: ["presence"] responses: 200: @@ -94,7 +97,7 @@ paths: properties: presence: type: string - enum: ["online", "offline", "unavailable", "free_for_chat"] + enum: ["online", "offline", "unavailable"] description: This user's presence. last_active_ago: type: integer @@ -185,8 +188,6 @@ paths: [ { "content": { - "avatar_url": "mxc://matrix.org/AfwefuigfWEfhuiPP", - "displayname": "Alice Margatroid", "last_active_ago": 395, "presence": "offline", "user_id": "@alice:matrix.org" @@ -195,11 +196,10 @@ paths: }, { "content": { - "avatar_url": "mxc://matrix.org/FWEhuiwegfWEfhuiwf", - "displayname": "Marisa Kirisame", "last_active_ago": 16874, "presence": "online", - "user_id": "@marisa:matrix.org" + "user_id": "@marisa:matrix.org", + "currently_active": true }, "type": "m.presence" } From f1a8306d080fe319703b13c77f4ce114ba5458f7 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 23 Feb 2016 11:13:02 +0000 Subject: [PATCH 08/20] Spec currently_active time and idle timeout behaviour --- specification/modules/presence.rst | 79 ++++++++++-------------------- 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/specification/modules/presence.rst b/specification/modules/presence.rst index 4eddaeee..7459ca7c 100644 --- a/specification/modules/presence.rst +++ b/specification/modules/presence.rst @@ -20,7 +20,7 @@ membership of a room. A presence list is a list of user IDs whose presence the user wants to follow. To be added to this list, the user being added must be invited by the list owner who must accept the invitation. - + User's presence state is represented by the ``presence`` key, which is an enum of one of the following: @@ -30,8 +30,6 @@ of one of the following: idle. - ``offline`` : The user is not connected to an event stream or is explicitly suppressing their profile information from being sent. -- ``free_for_chat`` : The user is generally willing to receive messages - moreso than default. Events ------ @@ -46,67 +44,44 @@ listed below. {{presence_http_api}} -Idle timeout -~~~~~~~~~~~~ - -Clients SHOULD implement an "idle timeout". This is a timer which fires after -a period of inactivity on the client. The definition of inactivity varies -depending on the client. For example, web implementations may determine -inactivity to be not moving the mouse for a certain period of time. When this -timer fires it should set the presence state to ``unavailable``. When the user -becomes active again (e.g. by moving the mouse) the client should set the -presence state to ``online``. A timeout value between 1 and 5 minutes is -recommended. - Server behaviour ---------------- Each user's homeserver stores a "presence list" per user. Once a user accepts a presence list, both user's HSes must track the subscription. -Propagating profile information -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Because the profile display name and avatar information are likely to be used in -many places of a client's display, changes to these fields SHOULD cause an -automatic propagation event to occur, informing likely-interested parties of the -new values. One of these change mechanisms SHOULD be via ``m.presence`` events. -These events should set ``displayname`` and ``avatar_url`` to the new values -along with the presence-specific keys. This SHOULD be done automatically by the -homeserver when a user successfully changes their display name or avatar URL. - -.. admonition:: Rationale - - The intention for sending this information in ``m.presence`` is so that any - "user list" can display the *current* name/presence for a user ID outside the - scope of a room e.g. for a user page. This is bundled into a single event for - several reasons. The user's display name can change per room. This - event provides the "canonical" name for the user. In addition, the name is - bundled into a single event for the ease of client implementations. If this - was not done, the client would need to search all rooms for their own - membership event to pull out the display name. - - Last active ago ~~~~~~~~~~~~~~~ -The server maintains a timestamp of the last time it saw a -pro-active event from the user. A pro-active event may be sending a message to a -room or changing presence state to a higher level of availability. Levels of -availability are defined from low to high as follows: +The server maintains a timestamp of the last time it saw a pro-active event from +the user. A pro-active event may be sending a message to a room or changing +presence state to ``online``. This timestamp is presented via a key called +``last_active_ago`` which gives the relative number of milliseconds since the +pro-active event. + +To reduce the number of presence updates sent to clients the server may include +a ``currently_active`` boolean field when the presence state is ``online``. When +true, the server will not send further updates to the last active time until an +update is sent to the client with either a) ``currently_active`` set to false or +b) a presence state other than ``online``. During this period clients must +consider the user to be currently active, irrespective of the last active time. + +The last active time must be up to date whenever the server gives a presence +event to the client; the ``currently_active`` mechanism should purely be used to +disable as opposed to disabling last active tracking. Thus clients can fetch up +to date last active times by explicitly requesting the presence for a given +user. -- ``offline`` -- ``unavailable`` -- ``online`` -- ``free_for_chat`` +Idle timeout +~~~~~~~~~~~~ -Based on this list, changing state from ``unavailable`` to ``online`` counts as -a pro-active event, whereas ``online`` to ``unavailable`` does not. This -timestamp is presented via a key called ``last_active_ago`` which gives the -relative number of milliseconds since the pro-active event. +The server will automatically set a users presence to ``unavailable`` if their +last active time was over 5 minutes ago. Clients can manually set a users +presence to ``unavailable``. Any activity that bumps the last active time on any +of the user's clients will cause the server to automatically set their presence +to ``online``. Security considerations ----------------------- - + Presence information is shared with all users who share a room with the target user. In large public rooms this could be undesirable. - From bc68177471066ed0797c612fc026fcfeb8647791 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 1 Mar 2016 16:07:25 +0000 Subject: [PATCH 09/20] Grammar --- specification/modules/presence.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/modules/presence.rst b/specification/modules/presence.rst index 7459ca7c..19fe13ba 100644 --- a/specification/modules/presence.rst +++ b/specification/modules/presence.rst @@ -74,8 +74,8 @@ user. Idle timeout ~~~~~~~~~~~~ -The server will automatically set a users presence to ``unavailable`` if their -last active time was over 5 minutes ago. Clients can manually set a users +The server will automatically set a user's presence to ``unavailable`` if their +last active time was over 5 minutes ago. Clients can manually set a user's presence to ``unavailable``. Any activity that bumps the last active time on any of the user's clients will cause the server to automatically set their presence to ``online``. From 167a08a80516f193800838988440664de3adb6b4 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 1 Mar 2016 16:13:41 +0000 Subject: [PATCH 10/20] Allow idle timeout to be configurable --- specification/modules/presence.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/modules/presence.rst b/specification/modules/presence.rst index 19fe13ba..de327e3c 100644 --- a/specification/modules/presence.rst +++ b/specification/modules/presence.rst @@ -75,10 +75,10 @@ Idle timeout ~~~~~~~~~~~~ The server will automatically set a user's presence to ``unavailable`` if their -last active time was over 5 minutes ago. Clients can manually set a user's -presence to ``unavailable``. Any activity that bumps the last active time on any -of the user's clients will cause the server to automatically set their presence -to ``online``. +last active time was over a threshold value (e.g. 5 minutes). Clients can +manually set a user's presence to ``unavailable``. Any activity that bumps the +last active time on any of the user's clients will cause the server to +automatically set their presence to ``online``. Security considerations ----------------------- From 3d4d91a462c8d211caf857d3b9ce3d2421871e81 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 1 Mar 2016 16:15:59 +0000 Subject: [PATCH 11/20] Reword to make sense --- specification/modules/presence.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/modules/presence.rst b/specification/modules/presence.rst index de327e3c..52e59970 100644 --- a/specification/modules/presence.rst +++ b/specification/modules/presence.rst @@ -66,10 +66,10 @@ b) a presence state other than ``online``. During this period clients must consider the user to be currently active, irrespective of the last active time. The last active time must be up to date whenever the server gives a presence -event to the client; the ``currently_active`` mechanism should purely be used to -disable as opposed to disabling last active tracking. Thus clients can fetch up -to date last active times by explicitly requesting the presence for a given -user. +event to the client. The ``currently_active`` mechanism should purely be used by +servers to stop sending continuous presence updates, as opposed to disabling +last active tracking entirely. Thus clients can fetch up to date last active +times by explicitly requesting the presence for a given user. Idle timeout ~~~~~~~~~~~~ From 5b12e2cfef515d917d36375f925472e990d0d2eb Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 22 Jun 2016 11:03:02 +0100 Subject: [PATCH 12/20] Convert event schemas to yaml We've decided to make the event schemas YAML, so we might as well take advantage of it. (This conversion was done mostly automatically, except for: - s/null/"null"/ in m.room.member - reformat description in m.room.power_levels --- event-schemas/schema/m.room.aliases | 55 +++-- event-schemas/schema/m.room.avatar | 87 ++++---- event-schemas/schema/m.room.canonical_alias | 49 ++--- event-schemas/schema/m.room.create | 59 +++--- event-schemas/schema/m.room.guest_access | 56 +++-- .../schema/m.room.history_visibility | 58 +++-- event-schemas/schema/m.room.join_rules | 58 +++-- event-schemas/schema/m.room.member | 200 +++++++++--------- event-schemas/schema/m.room.message | 51 ++--- event-schemas/schema/m.room.message#m.audio | 93 ++++---- event-schemas/schema/m.room.message#m.emote | 52 +++-- event-schemas/schema/m.room.message#m.file | 115 +++++----- event-schemas/schema/m.room.message#m.image | 121 +++++------ .../schema/m.room.message#m.location | 79 ++++--- event-schemas/schema/m.room.message#m.notice | 52 +++-- event-schemas/schema/m.room.message#m.text | 52 +++-- event-schemas/schema/m.room.message#m.video | 126 +++++------ event-schemas/schema/m.room.message.feedback | 55 +++-- event-schemas/schema/m.room.name | 52 ++--- event-schemas/schema/m.room.power_levels | 145 +++++++------ event-schemas/schema/m.room.redaction | 50 ++--- .../schema/m.room.third_party_invite | 102 ++++----- event-schemas/schema/m.room.topic | 52 ++--- 23 files changed, 846 insertions(+), 973 deletions(-) diff --git a/event-schemas/schema/m.room.aliases b/event-schemas/schema/m.room.aliases index a3427703..348d490d 100644 --- a/event-schemas/schema/m.room.aliases +++ b/event-schemas/schema/m.room.aliases @@ -1,31 +1,24 @@ -{ - "type": "object", - "title": "Informs the room about what room aliases it has been given.", - "description": "This event is sent by a homeserver directly to inform of changes to the list of aliases it knows about for that room. The ``state_key`` for this event is set to the homeserver which owns the room alias. The entire set of known aliases for the room is the union of all the ``m.room.aliases`` events, one for each homeserver. Clients **should** check the validity of any room alias given in this list before presenting it to the user as trusted fact. The lists given by this event should be considered simply as advice on which aliases might exist, for which the client can perform the lookup to confirm whether it receives the correct room ID.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "aliases": { - "type": "array", - "description": "A list of room aliases.", - "items": { - "type": "string" - } - } - }, - "required": ["aliases"] - }, - "state_key": { - "type": "string", - "description": "The homeserver domain which owns these room aliases." - }, - "type": { - "type": "string", - "enum": ["m.room.aliases"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: 'This event is sent by a homeserver directly to inform of changes to the list of aliases it knows about for that room. The ``state_key`` for this event is set to the homeserver which owns the room alias. The entire set of known aliases for the room is the union of all the ``m.room.aliases`` events, one for each homeserver. Clients **should** check the validity of any room alias given in this list before presenting it to the user as trusted fact. The lists given by this event should be considered simply as advice on which aliases might exist, for which the client can perform the lookup to confirm whether it receives the correct room ID.' +properties: + content: + properties: + aliases: + description: A list of room aliases. + items: + type: string + type: array + required: + - aliases + type: object + state_key: + description: The homeserver domain which owns these room aliases. + type: string + type: + enum: + - m.room.aliases + type: string +title: Informs the room about what room aliases it has been given. +type: object diff --git a/event-schemas/schema/m.room.avatar b/event-schemas/schema/m.room.avatar index 593efe0d..f99ae285 100644 --- a/event-schemas/schema/m.room.avatar +++ b/event-schemas/schema/m.room.avatar @@ -1,49 +1,38 @@ -{ - "title": "RoomAvatar", - "description": "A picture that is associated with the room. This can be displayed alongside the room information.", - "type": "object", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "url": { - "type": "string", - "description": "The URL to the image." - }, - "thumbnail_url": { - "type": "string", - "description": "The URL to the thumbnail of the image." - }, - "thumbnail_info": { - "type": "object", - "title": "ImageInfo", - "description": "Metadata about the image referred to in ``thumbnail_url``.", - "allOf": [{ - "$ref": "core-event-schema/msgtype_infos/image_info.yaml" - }] - }, - "info": { - "type": "object", - "title": "ImageInfo", - "description": "Metadata about the image referred to in ``url``.", - "allOf": [{ - "$ref": "core-event-schema/msgtype_infos/image_info.yaml" - }] - } - }, - "required": ["url"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.avatar"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: A picture that is associated with the room. This can be displayed alongside the room information. +properties: + content: + properties: + info: + allOf: + - $ref: core-event-schema/msgtype_infos/image_info.yaml + description: Metadata about the image referred to in ``url``. + title: ImageInfo + type: object + thumbnail_info: + allOf: + - $ref: core-event-schema/msgtype_infos/image_info.yaml + description: Metadata about the image referred to in ``thumbnail_url``. + title: ImageInfo + type: object + thumbnail_url: + description: The URL to the thumbnail of the image. + type: string + url: + description: The URL to the image. + type: string + required: + - url + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.avatar + type: string +title: RoomAvatar +type: object diff --git a/event-schemas/schema/m.room.canonical_alias b/event-schemas/schema/m.room.canonical_alias index 4d6f956b..63bf4d95 100644 --- a/event-schemas/schema/m.room.canonical_alias +++ b/event-schemas/schema/m.room.canonical_alias @@ -1,28 +1,21 @@ -{ - "type": "object", - "title": "Informs the room as to which alias is the canonical one.", - "description": "This event is used to inform the room about which alias should be considered the canonical one. This could be for display purposes or as suggestion to users which alias to use to advertise the room.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "alias": { - "type": "string", - "description": "The canonical alias." - } - } - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.canonical_alias"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: This event is used to inform the room about which alias should be considered the canonical one. This could be for display purposes or as suggestion to users which alias to use to advertise the room. +properties: + content: + properties: + alias: + description: The canonical alias. + type: string + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.canonical_alias + type: string +title: Informs the room as to which alias is the canonical one. +type: object diff --git a/event-schemas/schema/m.room.create b/event-schemas/schema/m.room.create index 13e5513c..a07ab90f 100644 --- a/event-schemas/schema/m.room.create +++ b/event-schemas/schema/m.room.create @@ -1,33 +1,26 @@ -{ - "type": "object", - "title": "The first event in the room.", - "description": "This is the first event in a room and cannot be changed. It acts as the root of all other events.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "creator": { - "type": "string", - "description": "The ``user_id`` of the room creator. This is set by the homeserver." - }, - "m.federate": { - "type": "boolean", - "description": "Whether users on other servers can join this room. Defaults to ``true`` if key does not exist." - } - }, - "required": ["creator"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.create"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: This is the first event in a room and cannot be changed. It acts as the root of all other events. +properties: + content: + properties: + creator: + description: The ``user_id`` of the room creator. This is set by the homeserver. + type: string + m.federate: + description: Whether users on other servers can join this room. Defaults to ``true`` if key does not exist. + type: boolean + required: + - creator + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.create + type: string +title: The first event in the room. +type: object diff --git a/event-schemas/schema/m.room.guest_access b/event-schemas/schema/m.room.guest_access index c7ef9026..f886dfe5 100644 --- a/event-schemas/schema/m.room.guest_access +++ b/event-schemas/schema/m.room.guest_access @@ -1,30 +1,26 @@ -{ - "type": "object", - "title": "Controls whether guest users are allowed to join rooms.", - "description": "This event controls whether guest users are allowed to join rooms. If this event is absent, servers should act as if it is present and has the guest_access value \"forbidden\".", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "guest_access": { - "type": "string", - "description": "Whether guests can join the room.", - "enum": ["can_join", "forbidden"] - } - }, - "required": ["guest_access"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.guest_access"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: 'This event controls whether guest users are allowed to join rooms. If this event is absent, servers should act as if it is present and has the guest_access value "forbidden".' +properties: + content: + properties: + guest_access: + description: Whether guests can join the room. + enum: + - can_join + - forbidden + type: string + required: + - guest_access + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.guest_access + type: string +title: Controls whether guest users are allowed to join rooms. +type: object diff --git a/event-schemas/schema/m.room.history_visibility b/event-schemas/schema/m.room.history_visibility index aaf25261..27ec67c7 100644 --- a/event-schemas/schema/m.room.history_visibility +++ b/event-schemas/schema/m.room.history_visibility @@ -1,30 +1,28 @@ -{ - "type": "object", - "title": "Controls visibility of history.", - "description": "This event controls whether a user can see the events that happened in a room from before they joined.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "history_visibility": { - "type": "string", - "description": "Who can see the room history.", - "enum": ["invited","joined","shared","world_readable"] - } - }, - "required": ["history_visibility"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.history_visibility"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: This event controls whether a user can see the events that happened in a room from before they joined. +properties: + content: + properties: + history_visibility: + description: Who can see the room history. + enum: + - invited + - joined + - shared + - world_readable + type: string + required: + - history_visibility + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.history_visibility + type: string +title: Controls visibility of history. +type: object diff --git a/event-schemas/schema/m.room.join_rules b/event-schemas/schema/m.room.join_rules index 680d6f60..b8e8501c 100644 --- a/event-schemas/schema/m.room.join_rules +++ b/event-schemas/schema/m.room.join_rules @@ -1,30 +1,28 @@ -{ - "type": "object", - "title": "Describes how users are allowed to join the room.", - "description": "A room may be ``public`` meaning anyone can join the room without any prior action. Alternatively, it can be ``invite`` meaning that a user who wishes to join the room must first receive an invite to the room from someone already inside of the room. Currently, ``knock`` and ``private`` are reserved keywords which are not implemented.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "join_rule": { - "type": "string", - "description": "The type of rules used for users wishing to join this room.", - "enum": ["public","knock","invite","private"] - } - }, - "required": ["join_rule"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.join_rules"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: 'A room may be ``public`` meaning anyone can join the room without any prior action. Alternatively, it can be ``invite`` meaning that a user who wishes to join the room must first receive an invite to the room from someone already inside of the room. Currently, ``knock`` and ``private`` are reserved keywords which are not implemented.' +properties: + content: + properties: + join_rule: + description: The type of rules used for users wishing to join this room. + enum: + - public + - knock + - invite + - private + type: string + required: + - join_rule + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.join_rules + type: string +title: Describes how users are allowed to join the room. +type: object diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 84d85b2a..055a1945 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -1,95 +1,105 @@ -{ - "type": "object", - "title": "The current membership state of a user in the room.", - "description": "Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms//invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail. \n\nThe following membership states are specified:\n\n- ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join.\n\n- ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it.\n\n- ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked).\n\n- ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``).\n\n- ``knock`` - This is a reserved word, which currently has no meaning.\n\nThe ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.\n\nThis event may also include an ``invite_room_state`` key **outside the** ``content`` **key**. If present, this contains an array of ``StrippedState`` Events. These events provide information on a subset of state events such as the room name.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "title": "EventContent", - "properties": { - "membership": { - "type": "string", - "description": "The membership state of the user.", - "enum": ["invite","join","knock","leave","ban"] - }, - "avatar_url": { - "type": "string", - "description": "The avatar URL for this user, if any. This is added by the homeserver." - }, - "displayname": { - "type": ["string", "null"], - "description": "The display name for this user, if any. This is added by the homeserver." - }, - "third_party_invite": { - "type": "object", - "title": "Invite", - "properties": { - "display_name": { - "type": "string", - "description": "A name which can be displayed to represent the user instead of their third party identifier" - }, - "signed": { - "type": "object", - "title": "signed", - "description": "A block of content which has been signed, which servers can use to verify the event. Clients should ignore this.", - "properties": { - "mxid": { - "type": "string", - "description": "The invited matrix user ID. Must be equal to the user_id property of the event." - }, - "token": { - "type": "string", - "description": "The token property of the containing third_party_invite object." - }, - "signatures": { - "type": "object", - "description": "A single signature from the verifying server, in the format specified by the Signing Events section of the server-server API.", - "title": "Signatures" - } - }, - "required": ["mxid", "signatures", "token"] - } - }, - "required": ["display_name", "signed"] - } - }, - "required": ["membership"] - }, - "state_key": { - "type": "string", - "description": "The ``user_id`` this membership event relates to." - }, - "type": { - "type": "string", - "enum": ["m.room.member"] - }, - "invite_room_state": { - "type": "array", - "description": "A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.", - "items": { - "type": "object", - "title": "StrippedState", - "description": "A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.", - "required": ["type", "state_key", "content"], - "properties": { - "type": { - "type": "string", - "description": "The ``type`` for the event." - }, - "state_key": { - "type": "string", - "description": "The ``state_key`` for the event." - }, - "content": { - "title": "EventContent", - "type": "object", - "description": "The ``content`` for the event." - } - } - } - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: |- + Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms//invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail. + + The following membership states are specified: + + - ``invite`` - The user has been invited to join a room, but has not yet joined it. They may not participate in the room until they join. + + - ``join`` - The user has joined the room (possibly after accepting an invite), and may participate in it. + + - ``leave`` - The user was once joined to the room, but has since left (possibly by choice, or possibly by being kicked). + + - ``ban`` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than ``ban``). + + - ``knock`` - This is a reserved word, which currently has no meaning. + + The ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise. + + This event may also include an ``invite_room_state`` key **outside the** ``content`` **key**. If present, this contains an array of ``StrippedState`` Events. These events provide information on a subset of state events such as the room name. +properties: + content: + properties: + avatar_url: + description: 'The avatar URL for this user, if any. This is added by the homeserver.' + type: string + displayname: + description: 'The display name for this user, if any. This is added by the homeserver.' + type: + - string + - "null" + membership: + description: The membership state of the user. + enum: + - invite + - join + - knock + - leave + - ban + type: string + third_party_invite: + properties: + display_name: + description: A name which can be displayed to represent the user instead of their third party identifier + type: string + signed: + description: 'A block of content which has been signed, which servers can use to verify the event. Clients should ignore this.' + properties: + mxid: + description: The invited matrix user ID. Must be equal to the user_id property of the event. + type: string + signatures: + description: 'A single signature from the verifying server, in the format specified by the Signing Events section of the server-server API.' + title: Signatures + type: object + token: + description: The token property of the containing third_party_invite object. + type: string + required: + - mxid + - signatures + - token + title: signed + type: object + required: + - display_name + - signed + title: Invite + type: object + required: + - membership + title: EventContent + type: object + invite_room_state: + description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.' + items: + description: 'A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.' + properties: + content: + description: The ``content`` for the event. + title: EventContent + type: object + state_key: + description: The ``state_key`` for the event. + type: string + type: + description: The ``type`` for the event. + type: string + required: + - type + - state_key + - content + title: StrippedState + type: object + type: array + state_key: + description: The ``user_id`` this membership event relates to. + type: string + type: + enum: + - m.room.member + type: string +title: The current membership state of a user in the room. +type: object diff --git a/event-schemas/schema/m.room.message b/event-schemas/schema/m.room.message index 82de26a8..45025c99 100644 --- a/event-schemas/schema/m.room.message +++ b/event-schemas/schema/m.room.message @@ -1,28 +1,23 @@ -{ - "type": "object", - "title": "Message", - "description": "This event is used when sending messages in a room. Messages are not limited to be text. The ``msgtype`` key outlines the type of message, e.g. text, audio, image, video, etc. The ``body`` key is text and MUST be used with every kind of ``msgtype`` as a fallback mechanism for when a client cannot render a message. This allows clients to display *something* even if it is just plain text.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "description": "The type of message, e.g. ``m.image``, ``m.text``" - }, - "body": { - "type": "string", - "description": "The textual representation of this message." - } - }, - "required": ["msgtype", "body"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: 'This event is used when sending messages in a room. Messages are not limited to be text. The ``msgtype`` key outlines the type of message, e.g. text, audio, image, video, etc. The ``body`` key is text and MUST be used with every kind of ``msgtype`` as a fallback mechanism for when a client cannot render a message. This allows clients to display *something* even if it is just plain text.' +properties: + content: + properties: + body: + description: The textual representation of this message. + type: string + msgtype: + description: 'The type of message, e.g. ``m.image``, ``m.text``' + type: string + required: + - msgtype + - body + type: object + type: + enum: + - m.room.message + type: string +title: Message +type: object diff --git a/event-schemas/schema/m.room.message#m.audio b/event-schemas/schema/m.room.message#m.audio index cd55426c..f15c71a3 100644 --- a/event-schemas/schema/m.room.message#m.audio +++ b/event-schemas/schema/m.room.message#m.audio @@ -1,51 +1,42 @@ -{ - "type": "object", - "title": "AudioMessage", - "description": "This message represents a single audio clip.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.audio"] - }, - "body": { - "type": "string", - "description": "A description of the audio e.g. 'Bee Gees - Stayin' Alive', or some kind of content description for accessibility e.g. 'audio attachment'." - }, - "url": { - "type": "string", - "description": "The URL to the audio clip." - }, - "info": { - "type": "object", - "title": "AudioInfo", - "description": "Metadata for the audio clip referred to in ``url``.", - "properties": { - "mimetype": { - "type": "string", - "description": "The mimetype of the audio e.g. ``audio/aac``." - }, - "size": { - "type": "integer", - "description": "The size of the audio clip in bytes." - }, - "duration": { - "type": "integer", - "description": "The duration of the audio in milliseconds." - } - } - } - }, - "required": ["msgtype", "body", "url"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: This message represents a single audio clip. +properties: + content: + properties: + body: + description: "A description of the audio e.g. 'Bee Gees - Stayin' Alive', or some kind of content description for accessibility e.g. 'audio attachment'." + type: string + info: + description: Metadata for the audio clip referred to in ``url``. + properties: + duration: + description: The duration of the audio in milliseconds. + type: integer + mimetype: + description: The mimetype of the audio e.g. ``audio/aac``. + type: string + size: + description: The size of the audio clip in bytes. + type: integer + title: AudioInfo + type: object + msgtype: + enum: + - m.audio + type: string + url: + description: The URL to the audio clip. + type: string + required: + - msgtype + - body + - url + type: object + type: + enum: + - m.room.message + type: string +title: AudioMessage +type: object diff --git a/event-schemas/schema/m.room.message#m.emote b/event-schemas/schema/m.room.message#m.emote index 8fa63951..88860cb2 100644 --- a/event-schemas/schema/m.room.message#m.emote +++ b/event-schemas/schema/m.room.message#m.emote @@ -1,28 +1,24 @@ -{ - "type": "object", - "title": "EmoteMessage", - "description": "This message is similar to ``m.text`` except that the sender is 'performing' the action contained in the ``body`` key, similar to ``/me`` in IRC. This message should be prefixed by the name of the sender. This message could also be represented in a different colour to distinguish it from regular ``m.text`` messages.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.emote"] - }, - "body": { - "type": "string", - "description": "The emote action to perform." - } - }, - "required": ["msgtype", "body"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: "This message is similar to ``m.text`` except that the sender is 'performing' the action contained in the ``body`` key, similar to ``/me`` in IRC. This message should be prefixed by the name of the sender. This message could also be represented in a different colour to distinguish it from regular ``m.text`` messages." +properties: + content: + properties: + body: + description: The emote action to perform. + type: string + msgtype: + enum: + - m.emote + type: string + required: + - msgtype + - body + type: object + type: + enum: + - m.room.message + type: string +title: EmoteMessage +type: object diff --git a/event-schemas/schema/m.room.message#m.file b/event-schemas/schema/m.room.message#m.file index f921b23f..2f56c804 100644 --- a/event-schemas/schema/m.room.message#m.file +++ b/event-schemas/schema/m.room.message#m.file @@ -1,63 +1,52 @@ -{ - "type": "object", - "title": "FileMessage", - "description": "This message represents a generic file.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.file"] - }, - "filename": { - "type": "string", - "description": "The original filename of the uploaded file." - }, - "body": { - "type": "string", - "description": "A human-readable description of the file. This is recommended to be the filename of the original upload." - }, - "url": { - "type": "string", - "description": "The URL to the file." - }, - "info": { - "type": "object", - "title": "FileInfo", - "description": "Information about the file referred to in ``url``.", - "properties": { - "size": { - "type": "integer", - "description": "The size of the file in bytes." - }, - "mimetype": { - "type": "string", - "description": "The mimetype of the file e.g. ``application/msword``." - } - } - }, - "thumbnail_url": { - "type": "string", - "description": "The URL to the thumbnail of the file." - }, - "thumbnail_info": { - "type": "object", - "title": "ImageInfo", - "description": "Metadata about the image referred to in ``thumbnail_url``.", - "allOf": [{ - "$ref": "core-event-schema/msgtype_infos/image_info.yaml" - }] - } - }, - "required": ["msgtype", "body", "url", "filename"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: This message represents a generic file. +properties: + content: + properties: + body: + description: A human-readable description of the file. This is recommended to be the filename of the original upload. + type: string + filename: + description: The original filename of the uploaded file. + type: string + info: + description: Information about the file referred to in ``url``. + properties: + mimetype: + description: The mimetype of the file e.g. ``application/msword``. + type: string + size: + description: The size of the file in bytes. + type: integer + title: FileInfo + type: object + msgtype: + enum: + - m.file + type: string + thumbnail_info: + allOf: + - $ref: core-event-schema/msgtype_infos/image_info.yaml + description: Metadata about the image referred to in ``thumbnail_url``. + title: ImageInfo + type: object + thumbnail_url: + description: The URL to the thumbnail of the file. + type: string + url: + description: The URL to the file. + type: string + required: + - msgtype + - body + - url + - filename + type: object + type: + enum: + - m.room.message + type: string +title: FileMessage +type: object diff --git a/event-schemas/schema/m.room.message#m.image b/event-schemas/schema/m.room.message#m.image index 1085bb85..4573ff27 100644 --- a/event-schemas/schema/m.room.message#m.image +++ b/event-schemas/schema/m.room.message#m.image @@ -1,67 +1,54 @@ -{ - "type": "object", - "title": "ImageMessage", - "description": "This message represents a single image and an optional thumbnail.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.image"] - }, - "body": { - "type": "string", - "description": "A textual representation of the image. This could be the alt text of the image, the filename of the image, or some kind of content description for accessibility e.g. 'image attachment'." - }, - "url": { - "type": "string", - "description": "The URL to the image." - }, - "thumbnail_url": { - "type": "string", - "description": "The URL to the thumbnail of the image." - }, - "thumbnail_info": { - "type": "object", - "title": "ImageInfo", - "description": "Metadata about the image referred to in ``thumbnail_url``.", - "allOf": [{ - "$ref": "core-event-schema/msgtype_infos/image_info.yaml" - }] - }, - "info": { - "type": "object", - "title": "ImageInfo", - "description": "Metadata about the image referred to in ``url``.", - "properties": { - "size": { - "type": "integer", - "description": "Size of the image in bytes." - }, - "w": { - "type": "integer", - "description": "The width of the image in pixels." - }, - "h": { - "type": "integer", - "description": "The height of the image in pixels." - }, - "mimetype": { - "type": "string", - "description": "The mimetype of the image, e.g. ``image/jpeg``." - } - } - } - }, - "required": ["msgtype", "body", "url"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: This message represents a single image and an optional thumbnail. +properties: + content: + properties: + body: + description: "A textual representation of the image. This could be the alt text of the image, the filename of the image, or some kind of content description for accessibility e.g. 'image attachment'." + type: string + info: + description: Metadata about the image referred to in ``url``. + properties: + h: + description: The height of the image in pixels. + type: integer + mimetype: + description: 'The mimetype of the image, e.g. ``image/jpeg``.' + type: string + size: + description: Size of the image in bytes. + type: integer + w: + description: The width of the image in pixels. + type: integer + title: ImageInfo + type: object + msgtype: + enum: + - m.image + type: string + thumbnail_info: + allOf: + - $ref: core-event-schema/msgtype_infos/image_info.yaml + description: Metadata about the image referred to in ``thumbnail_url``. + title: ImageInfo + type: object + thumbnail_url: + description: The URL to the thumbnail of the image. + type: string + url: + description: The URL to the image. + type: string + required: + - msgtype + - body + - url + type: object + type: + enum: + - m.room.message + type: string +title: ImageMessage +type: object diff --git a/event-schemas/schema/m.room.message#m.location b/event-schemas/schema/m.room.message#m.location index 7deb6f8d..ca37856d 100644 --- a/event-schemas/schema/m.room.message#m.location +++ b/event-schemas/schema/m.room.message#m.location @@ -1,43 +1,36 @@ -{ - "type": "object", - "title": "LocationMessage", - "description": "This message represents a real-world location.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.location"] - }, - "body": { - "type": "string", - "description": "A description of the location e.g. 'Big Ben, London, UK', or some kind of content description for accessibility e.g. 'location attachment'." - }, - "geo_uri": { - "type": "string", - "description": "A geo URI representing this location." - }, - "thumbnail_url": { - "type": "string", - "description": "The URL to a thumbnail of the location being represented." - }, - "thumbnail_info": { - "type": "object", - "title": "ImageInfo", - "allOf": [{ - "$ref": "core-event-schema/msgtype_infos/image_info.yaml" - }] - } - }, - "required": ["msgtype", "body", "geo_uri"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: This message represents a real-world location. +properties: + content: + properties: + body: + description: "A description of the location e.g. 'Big Ben, London, UK', or some kind of content description for accessibility e.g. 'location attachment'." + type: string + geo_uri: + description: A geo URI representing this location. + type: string + msgtype: + enum: + - m.location + type: string + thumbnail_info: + allOf: + - $ref: core-event-schema/msgtype_infos/image_info.yaml + title: ImageInfo + type: object + thumbnail_url: + description: The URL to a thumbnail of the location being represented. + type: string + required: + - msgtype + - body + - geo_uri + type: object + type: + enum: + - m.room.message + type: string +title: LocationMessage +type: object diff --git a/event-schemas/schema/m.room.message#m.notice b/event-schemas/schema/m.room.message#m.notice index 100c3d60..7b91c649 100644 --- a/event-schemas/schema/m.room.message#m.notice +++ b/event-schemas/schema/m.room.message#m.notice @@ -1,28 +1,24 @@ -{ - "type": "object", - "title": "NoticeMessage", - "description": "A m.notice message should be considered similar to a plain m.text message except that clients should visually distinguish it in some way. It is intended to be used by automated clients, such as bots, bridges, and other entities, rather than humans. Additionally, such automated agents which watch a room for messages and respond to them ought to ignore m.notice messages. This helps to prevent infinite-loop situations where two automated clients continuously exchange messages, as each responds to the other.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.notice"] - }, - "body": { - "type": "string", - "description": "The notice text to send." - } - }, - "required": ["msgtype", "body"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: 'A m.notice message should be considered similar to a plain m.text message except that clients should visually distinguish it in some way. It is intended to be used by automated clients, such as bots, bridges, and other entities, rather than humans. Additionally, such automated agents which watch a room for messages and respond to them ought to ignore m.notice messages. This helps to prevent infinite-loop situations where two automated clients continuously exchange messages, as each responds to the other.' +properties: + content: + properties: + body: + description: The notice text to send. + type: string + msgtype: + enum: + - m.notice + type: string + required: + - msgtype + - body + type: object + type: + enum: + - m.room.message + type: string +title: NoticeMessage +type: object diff --git a/event-schemas/schema/m.room.message#m.text b/event-schemas/schema/m.room.message#m.text index 0b638113..2720172d 100644 --- a/event-schemas/schema/m.room.message#m.text +++ b/event-schemas/schema/m.room.message#m.text @@ -1,28 +1,24 @@ -{ - "type": "object", - "title": "TextMessage", - "description": "This message is the most basic message and is used to represent text.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.text"] - }, - "body": { - "type": "string", - "description": "The body of the message." - } - }, - "required": ["msgtype", "body"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: This message is the most basic message and is used to represent text. +properties: + content: + properties: + body: + description: The body of the message. + type: string + msgtype: + enum: + - m.text + type: string + required: + - msgtype + - body + type: object + type: + enum: + - m.room.message + type: string +title: TextMessage +type: object diff --git a/event-schemas/schema/m.room.message#m.video b/event-schemas/schema/m.room.message#m.video index 6381543f..09753965 100644 --- a/event-schemas/schema/m.room.message#m.video +++ b/event-schemas/schema/m.room.message#m.video @@ -1,70 +1,56 @@ -{ - "type": "object", - "title": "VideoMessage", - "description": "This message represents a single video clip.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "msgtype": { - "type": "string", - "enum": ["m.video"] - }, - "body": { - "type": "string", - "description": "A description of the video e.g. 'Gangnam style', or some kind of content description for accessibility e.g. 'video attachment'." - }, - "url": { - "type": "string", - "description": "The URL to the video clip." - }, - "info": { - "type": "object", - "title": "VideoInfo", - "description": "Metadata about the video clip referred to in ``url``.", - "properties": { - "mimetype": { - "type": "string", - "description": "The mimetype of the video e.g. ``video/mp4``." - }, - "size": { - "type": "integer", - "description": "The size of the video in bytes." - }, - "duration": { - "type": "integer", - "description": "The duration of the video in milliseconds." - }, - "w": { - "type": "integer", - "description": "The width of the video in pixels." - }, - "h": { - "type": "integer", - "description": "The height of the video in pixels." - }, - "thumbnail_url": { - "type": "string", - "description": "The URL to a thumbnail of the video clip." - }, - "thumbnail_info": { - "type": "object", - "title": "ImageInfo", - "allOf": [{ - "$ref": "core-event-schema/msgtype_infos/image_info.yaml" - }] - } - } - } - }, - "required": ["msgtype", "body", "url"] - }, - "type": { - "type": "string", - "enum": ["m.room.message"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: This message represents a single video clip. +properties: + content: + properties: + body: + description: "A description of the video e.g. 'Gangnam style', or some kind of content description for accessibility e.g. 'video attachment'." + type: string + info: + description: Metadata about the video clip referred to in ``url``. + properties: + duration: + description: The duration of the video in milliseconds. + type: integer + h: + description: The height of the video in pixels. + type: integer + mimetype: + description: The mimetype of the video e.g. ``video/mp4``. + type: string + size: + description: The size of the video in bytes. + type: integer + thumbnail_info: + allOf: + - $ref: core-event-schema/msgtype_infos/image_info.yaml + title: ImageInfo + type: object + thumbnail_url: + description: The URL to a thumbnail of the video clip. + type: string + w: + description: The width of the video in pixels. + type: integer + title: VideoInfo + type: object + msgtype: + enum: + - m.video + type: string + url: + description: The URL to the video clip. + type: string + required: + - msgtype + - body + - url + type: object + type: + enum: + - m.room.message + type: string +title: VideoMessage +type: object diff --git a/event-schemas/schema/m.room.message.feedback b/event-schemas/schema/m.room.message.feedback index 38e5ce05..fa3390fa 100644 --- a/event-schemas/schema/m.room.message.feedback +++ b/event-schemas/schema/m.room.message.feedback @@ -1,29 +1,26 @@ -{ - "type": "object", - "title": "MessageFeedback", - "description": "**NB: Usage of this event is discouraged in favour of the** `receipts module`_. **Most clients will not recognise this event.** Feedback events are events sent to acknowledge a message in some way. There are two supported acknowledgements: ``delivered`` (sent when the event has been received) and ``read`` (sent when the event has been observed by the end-user). The ``target_event_id`` should reference the ``m.room.message`` event being acknowledged.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "The type of feedback.", - "enum": ["delivered", "read"] - }, - "target_event_id": { - "type": "string", - "description": "The event that this feedback is related to." - } - }, - "required": ["type", "target_event_id"] - }, - "type": { - "type": "string", - "enum": ["m.room.message.feedback"] - } - } -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: '**NB: Usage of this event is discouraged in favour of the** `receipts module`_. **Most clients will not recognise this event.** Feedback events are events sent to acknowledge a message in some way. There are two supported acknowledgements: ``delivered`` (sent when the event has been received) and ``read`` (sent when the event has been observed by the end-user). The ``target_event_id`` should reference the ``m.room.message`` event being acknowledged.' +properties: + content: + properties: + target_event_id: + description: The event that this feedback is related to. + type: string + type: + description: The type of feedback. + enum: + - delivered + - read + type: string + required: + - type + - target_event_id + type: object + type: + enum: + - m.room.message.feedback + type: string +title: MessageFeedback +type: object diff --git a/event-schemas/schema/m.room.name b/event-schemas/schema/m.room.name index 9a21c26f..f07120a8 100644 --- a/event-schemas/schema/m.room.name +++ b/event-schemas/schema/m.room.name @@ -1,29 +1,23 @@ -{ - "title": "RoomName", - "description": "A room has an opaque room ID which is not human-friendly to read. A room alias is human-friendly, but not all rooms have room aliases. The room name is a human-friendly string designed to be displayed to the end-user. The room name is not unique, as multiple rooms can have the same room name set. The room name can also be set when creating a room using ``/createRoom`` with the ``name`` key.", - "type": "object", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the room. This MUST NOT exceed 255 bytes." - } - }, - "required": ["name"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.name"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: 'A room has an opaque room ID which is not human-friendly to read. A room alias is human-friendly, but not all rooms have room aliases. The room name is a human-friendly string designed to be displayed to the end-user. The room name is not unique, as multiple rooms can have the same room name set. The room name can also be set when creating a room using ``/createRoom`` with the ``name`` key.' +properties: + content: + properties: + name: + description: The name of the room. This MUST NOT exceed 255 bytes. + type: string + required: + - name + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.name + type: string +title: RoomName +type: object diff --git a/event-schemas/schema/m.room.power_levels b/event-schemas/schema/m.room.power_levels index 8bc8cdb4..5244ba79 100644 --- a/event-schemas/schema/m.room.power_levels +++ b/event-schemas/schema/m.room.power_levels @@ -1,70 +1,75 @@ -{ - "type": "object", - "title": "Defines the power levels (privileges) of users in the room.", - "description": "This event specifies the minimum level a user must have in order to perform a certain action. It also specifies the levels of each user in the room.\n\nIf a ``user_id`` is in the ``users`` list, then that ``user_id`` has the associated power level. Otherwise they have the default level ``users_default``. If ``users_default`` is not supplied, it is assumed to be 0.\n\nThe level required to send a certain event is governed by ``events``, ``state_default`` and ``events_default``. If an event type is specified in ``events``, then the user must have at least the level specified in order to send that event. If the event type is not supplied, it defaults to ``events_default`` for Message Events and ``state_default`` for State Events. If there is no ``state_default`` in the ``power_levels`` event, the ``state_default`` is 50. If the room contains no ``power_levels`` event, the ``state_default`` is 0. The ``events_default`` is 0 in either of these cases.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "ban": { - "type": "number", - "description": "The level required to ban a user." - }, - "events_default": { - "type": "number", - "description": "The default level required to send message events. Can be overridden by the ``events`` key." - }, - "kick": { - "type": "number", - "description": "The level required to kick a user." - }, - "redact": { - "type": "number", - "description": "The level required to redact an event." - }, - "invite": { - "type": "number", - "description": "The level required to invite a user." - }, - "state_default": { - "type": "number", - "description": "The default level required to send state events. Can be overridden by the ``events`` key." - }, - "users_default": { - "type": "number", - "description": "The default power level for every user in the room, unless their ``user_id`` is mentioned in the ``users`` key." - }, - "events": { - "type": "object", - "title": "Event power levels", - "description": "The level required to send specific event types. This is a mapping from event type to power level required.", - "additionalProperties": { - "type": "number" - } - }, - "users": { - "type": "object", - "title": "User power levels", - "description": "The power levels for specific users. This is a mapping from ``user_id`` to power level for that user.", - "additionalProperties": { - "type": "number" - } - } - }, - "required": ["ban","events","events_default","kick","redact", - "state_default","users"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.power_levels"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: |- + This event specifies the minimum level a user must have in order to perform a + certain action. It also specifies the levels of each user in the room. + + If a ``user_id`` is in the ``users`` list, then that ``user_id`` has the + associated power level. Otherwise they have the default level + ``users_default``. If ``users_default`` is not supplied, it is assumed to be + 0. + + The level required to send a certain event is governed by ``events``, + ``state_default`` and ``events_default``. If an event type is specified in + ``events``, then the user must have at least the level specified in order to + send that event. If the event type is not supplied, it defaults to + ``events_default`` for Message Events and ``state_default`` for State + Events. If there is no ``state_default`` in the ``power_levels`` event, the + ``state_default`` is 50. If the room contains no ``power_levels`` event, the + ``state_default`` is 0. The ``events_default`` is 0 in either of these cases. +properties: + content: + properties: + ban: + description: The level required to ban a user. + type: number + events: + additionalProperties: + type: number + description: The level required to send specific event types. This is a mapping from event type to power level required. + title: Event power levels + type: object + events_default: + description: The default level required to send message events. Can be overridden by the ``events`` key. + type: number + invite: + description: The level required to invite a user. + type: number + kick: + description: The level required to kick a user. + type: number + redact: + description: The level required to redact an event. + type: number + state_default: + description: The default level required to send state events. Can be overridden by the ``events`` key. + type: number + users: + additionalProperties: + type: number + description: The power levels for specific users. This is a mapping from ``user_id`` to power level for that user. + title: User power levels + type: object + users_default: + description: 'The default power level for every user in the room, unless their ``user_id`` is mentioned in the ``users`` key.' + type: number + required: + - ban + - events + - events_default + - kick + - redact + - state_default + - users + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.power_levels + type: string +title: Defines the power levels (privileges) of users in the room. +type: object diff --git a/event-schemas/schema/m.room.redaction b/event-schemas/schema/m.room.redaction index 173969f4..b3bc418e 100644 --- a/event-schemas/schema/m.room.redaction +++ b/event-schemas/schema/m.room.redaction @@ -1,28 +1,22 @@ -{ - "type": "object", - "title": "Redaction", - "description": "Events can be redacted by either room or server admins. Redacting an event means that all keys not required by the protocol are stripped off, allowing admins to remove offensive or illegal content that may have been attached to any event. This cannot be undone, allowing server owners to physically delete the offending data. There is also a concept of a moderator hiding a message event, which can be undone, but cannot be applied to state events. The event that has been redacted is specified in the ``redacts`` event level key.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "reason": { - "type": "string", - "description": "The reason for the redaction, if any." - } - } - }, - "redacts": { - "type": "string", - "description": "The event ID that was redacted." - }, - "type": { - "type": "string", - "enum": ["m.room.redaction"] - } - }, - "required": ["redacts"] -} +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: 'Events can be redacted by either room or server admins. Redacting an event means that all keys not required by the protocol are stripped off, allowing admins to remove offensive or illegal content that may have been attached to any event. This cannot be undone, allowing server owners to physically delete the offending data. There is also a concept of a moderator hiding a message event, which can be undone, but cannot be applied to state events. The event that has been redacted is specified in the ``redacts`` event level key.' +properties: + content: + properties: + reason: + description: 'The reason for the redaction, if any.' + type: string + type: object + redacts: + description: The event ID that was redacted. + type: string + type: + enum: + - m.room.redaction + type: string +required: + - redacts +title: Redaction +type: object diff --git a/event-schemas/schema/m.room.third_party_invite b/event-schemas/schema/m.room.third_party_invite index 878211e2..794bd232 100644 --- a/event-schemas/schema/m.room.third_party_invite +++ b/event-schemas/schema/m.room.third_party_invite @@ -1,56 +1,46 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "title": "An invitation to a room issued to a third party identifier, rather than a matrix user ID.", - "description": "Acts as an ``m.room.member`` invite event, where there isn't a target user_id to invite. This event contains a token and a public key whose private key must be used to sign the token. Any user who can present that signature may use this invitation to join the target room.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "display_name": { - "type": "string", - "description": "A user-readable string which represents the user who has been invited. This should not contain the user's third party ID, as otherwise when the invite is accepted it would leak the association between the matrix ID and the third party ID." - }, - "key_validity_url": { - "type": "string", - "description": "A URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'." - }, - "public_key": { - "type": "string", - "description": "A base64-encoded ed25519 key with which token must be signed (though a signature from any entry in public_keys is also sufficient). This exists for backwards compatibility." - }, - "public_keys": { - "type": "array", - "description": "Keys with which the token may be signed.", - "items": { - "type": "object", - "title": "PublicKeys", - "properties": { - "public_key": { - "type": "string", - "description": "A base-64 encoded ed25519 key with which token may be signed." - }, - "key_validity_url": { - "type": "string", - "description": "An optional URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'. If this URL is absent, the key must be considered valid indefinitely." - } - }, - "required": ["public_key"] - } - } - }, - "required": ["display_name", "key_validity_url", "public_key"] - }, - "state_key": { - "type": "string", - "description": "The token, of which a signature must be produced in order to join the room." - }, - "type": { - "type": "string", - "enum": ["m.room.third_party_invite"] - } - } -} +--- +$schema: http://json-schema.org/draft-04/schema# +allOf: + - $ref: core-event-schema/state_event.yaml +description: "Acts as an ``m.room.member`` invite event, where there isn't a target user_id to invite. This event contains a token and a public key whose private key must be used to sign the token. Any user who can present that signature may use this invitation to join the target room." +properties: + content: + properties: + display_name: + description: "A user-readable string which represents the user who has been invited. This should not contain the user's third party ID, as otherwise when the invite is accepted it would leak the association between the matrix ID and the third party ID." + type: string + key_validity_url: + description: "A URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'." + type: string + public_key: + description: A base64-encoded ed25519 key with which token must be signed (though a signature from any entry in public_keys is also sufficient). This exists for backwards compatibility. + type: string + public_keys: + description: Keys with which the token may be signed. + items: + properties: + key_validity_url: + description: "An optional URL which can be fetched, with querystring public_key=public_key, to validate whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'. If this URL is absent, the key must be considered valid indefinitely." + type: string + public_key: + description: A base-64 encoded ed25519 key with which token may be signed. + type: string + required: + - public_key + title: PublicKeys + type: object + type: array + required: + - display_name + - key_validity_url + - public_key + type: object + state_key: + description: 'The token, of which a signature must be produced in order to join the room.' + type: string + type: + enum: + - m.room.third_party_invite + type: string +title: 'An invitation to a room issued to a third party identifier, rather than a matrix user ID.' +type: object diff --git a/event-schemas/schema/m.room.topic b/event-schemas/schema/m.room.topic index dec649ea..ad2a3ba2 100644 --- a/event-schemas/schema/m.room.topic +++ b/event-schemas/schema/m.room.topic @@ -1,29 +1,23 @@ -{ - "type": "object", - "title": "Topic", - "description": "A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using ``/createRoom`` with the ``topic`` key.", - "allOf": [{ - "$ref": "core-event-schema/state_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "topic": { - "type": "string", - "description": "The topic text." - } - }, - "required": ["topic"] - }, - "state_key": { - "type": "string", - "description": "A zero-length string.", - "pattern": "^$" - }, - "type": { - "type": "string", - "enum": ["m.room.topic"] - } - } -} +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: 'A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using ``/createRoom`` with the ``topic`` key.' +properties: + content: + properties: + topic: + description: The topic text. + type: string + required: + - topic + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.topic + type: string +title: Topic +type: object From 4875be05ced5e2c743a017b2cc2522bb8a3d971e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 22 Jun 2016 13:34:29 +0100 Subject: [PATCH 13/20] Give better error messages when parsing fails An attempt to give slightly more helpful error messages when we have a problem parsing an event schema file (in particular, which file contains the problem, and which property within it). A bit of light refactoring to make it tractable. --- templating/matrix_templates/units.py | 322 +++++++++++++++------------ 1 file changed, 178 insertions(+), 144 deletions(-) diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index fbe45c51..e0394d15 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -14,6 +14,7 @@ import json import os import re import subprocess +import sys import urllib import yaml @@ -153,98 +154,120 @@ def get_json_schema_object_fields(obj, enforce_title=False, required_keys = set(obj.get("required", [])) - fields = { - "title": obj.get("title"), - "rows": [] - } - - tables = [fields] + obj_title = obj.get("title") + first_table_rows = [] + tables = [] for key_name in props: - logger.debug("Processing property %s.%s", obj.get('title'), key_name) - prop = inherit_parents(props[key_name]) + try: + logger.debug("Processing property %s.%s", obj_title, key_name) + required = key_name in required_keys + res = process_prop(key_name, props[key_name], required, + mark_required) + + first_table_rows.append(res["row"]) + tables.extend(res["tables"]) + logger.debug("Done property %s" % key_name) + + except Exception, e: + e2 = Exception("Error reading property %s.%s: %s" % + (obj_title, key_name, str(e))) + raise e2, None, sys.exc_info()[2] + - value_type = None - required = key_name in required_keys - desc = prop.get("description", "") - prop_type = prop.get('type') + tables.insert(0, { + "title": obj_title, + "rows": first_table_rows, + }) - if prop_type is None: - raise KeyError("Property '%s' of object '%s' missing 'type' field" - % (key_name, obj)) - logger.debug("%s is a %s", key_name, prop_type) + return tables + +def process_prop(key_name, prop, required, mark_required): + prop = inherit_parents(prop) + + value_type = None + desc = prop.get("description", "") + prop_type = prop.get('type') + tables = [] + + if prop_type is None: + raise KeyError("Property '%s' of object '%s' missing 'type' field" + % (key_name, obj)) + logger.debug("%s is a %s", key_name, prop_type) - if prop_type == "object": + if prop_type == "object": + nested_objects = get_json_schema_object_fields( + prop, + enforce_title=True, + mark_required=mark_required, + ) + value_type = nested_objects[0]["title"] + value_id = value_type + + tables += [x for x in nested_objects if not x.get("no-table")] + elif prop_type == "array": + items = inherit_parents(prop["items"]) + # if the items of the array are objects then recurse + if items["type"] == "object": nested_objects = get_json_schema_object_fields( - prop, + items, enforce_title=True, mark_required=mark_required, ) - value_type = nested_objects[0]["title"] - value_id = value_type - - tables += [x for x in nested_objects if not x.get("no-table")] - elif prop_type == "array": - items = inherit_parents(prop["items"]) - # if the items of the array are objects then recurse - if items["type"] == "object": - nested_objects = get_json_schema_object_fields( - items, - enforce_title=True, - mark_required=mark_required, - ) - value_id = nested_objects[0]["title"] - value_type = "[%s]" % value_id - tables += nested_objects - else: - value_type = items["type"] - if isinstance(value_type, list): - value_type = " or ".join(value_type) - value_id = value_type - value_type = "[%s]" % value_type - array_enums = items.get("enum") - if array_enums: - if len(array_enums) > 1: - value_type = "[enum]" - desc += ( - " One of: %s" % json.dumps(array_enums) - ) - else: - desc += ( - " Must be '%s'." % array_enums[0] - ) + value_id = nested_objects[0]["title"] + value_type = "[%s]" % value_id + tables += nested_objects else: - value_type = prop_type - value_id = prop_type - if prop.get("enum"): - if len(prop["enum"]) > 1: - value_type = "enum" - if desc: - desc += " " + value_type = items["type"] + if isinstance(value_type, list): + value_type = " or ".join(value_type) + value_id = value_type + value_type = "[%s]" % value_type + array_enums = items.get("enum") + if array_enums: + if len(array_enums) > 1: + value_type = "[enum]" desc += ( - "One of: %s" % json.dumps(prop["enum"]) + " One of: %s" % json.dumps(array_enums) ) else: - if desc: - desc += " " desc += ( - "Must be '%s'." % prop["enum"][0] + " Must be '%s'." % array_enums[0] ) - if isinstance(value_type, list): - value_type = " or ".join(value_type) + else: + value_type = prop_type + value_id = prop_type + if prop.get("enum"): + if len(prop["enum"]) > 1: + value_type = "enum" + if desc: + desc += " " + desc += ( + "One of: %s" % json.dumps(prop["enum"]) + ) + else: + if desc: + desc += " " + desc += ( + "Must be '%s'." % prop["enum"][0] + ) + if isinstance(value_type, list): + value_type = " or ".join(value_type) + + + if required and mark_required: + desc = "**Required.** " + desc - if required and mark_required: - desc = "**Required.** " + desc - fields["rows"].append({ + return { + "row": { "key": key_name, "type": value_type, "id": value_id, "required": required, "desc": desc, - }) - logger.debug("Done property %s" % key_name) - - return tables + }, + "tables": tables, + } def get_tables_for_schema(schema, mark_required=True): @@ -611,89 +634,100 @@ class MatrixUnits(Units): if not filename.startswith("m."): continue filepath = os.path.join(path, filename) - self.log("Reading %s" % filepath) - with open(filepath, "r") as f: - json_schema = yaml.load(f) - schema = { - "typeof": None, - "typeof_info": "", - "type": None, - "title": None, - "desc": None, - "msgtype": None, - "content_fields": [ - # { - # title: " key" - # rows: [ - # { key: <key_name>, type: <string>, - # desc: <desc>, required: <bool> } - # ] - # } - ] - } + try: + schemata[filename] = self.read_event_schema(filepath) + except Exception, e: + e2 = Exception("Error reading event schema "+filepath+": "+ + str(e)) + raise e2, None, sys.exc_info()[2] - # add typeof - base_defs = { - ROOM_EVENT: "Message Event", - STATE_EVENT: "State Event" - } - if type(json_schema.get("allOf")) == list: - schema["typeof"] = base_defs.get( - json_schema["allOf"][0].get("$ref") - ) - elif json_schema.get("title"): - schema["typeof"] = json_schema["title"] + return schemata + + def read_event_schema(self, filepath): + self.log("Reading %s" % filepath) + + with open(filepath, "r") as f: + json_schema = yaml.load(f) + + schema = { + "typeof": None, + "typeof_info": "", + "type": None, + "title": None, + "desc": None, + "msgtype": None, + "content_fields": [ + # { + # title: "<title> key" + # rows: [ + # { key: <key_name>, type: <string>, + # desc: <desc>, required: <bool> } + # ] + # } + ] + } + + # add typeof + base_defs = { + ROOM_EVENT: "Message Event", + STATE_EVENT: "State Event" + } + if type(json_schema.get("allOf")) == list: + schema["typeof"] = base_defs.get( + json_schema["allOf"][0].get("$ref") + ) + elif json_schema.get("title"): + schema["typeof"] = json_schema["title"] - json_schema = resolve_references(filepath, json_schema) + json_schema = resolve_references(filepath, json_schema) - # add type - schema["type"] = Units.prop( - json_schema, "properties/type/enum" - )[0] + # add type + schema["type"] = Units.prop( + json_schema, "properties/type/enum" + )[0] - # add summary and desc - schema["title"] = json_schema.get("title") - schema["desc"] = json_schema.get("description", "") + # add summary and desc + schema["title"] = json_schema.get("title") + schema["desc"] = json_schema.get("description", "") - # walk the object for field info - schema["content_fields"] = get_tables_for_schema( - Units.prop(json_schema, "properties/content") - ) + # walk the object for field info + schema["content_fields"] = get_tables_for_schema( + Units.prop(json_schema, "properties/content") + ) - # This is horrible because we're special casing a key on m.room.member. - # We need to do this because we want to document a non-content object. - if schema["type"] == "m.room.member": - invite_room_state = get_tables_for_schema( - json_schema["properties"]["invite_room_state"]["items"], - ) - schema["content_fields"].extend(invite_room_state) + # This is horrible because we're special casing a key on m.room.member. + # We need to do this because we want to document a non-content object. + if schema["type"] == "m.room.member": + invite_room_state = get_tables_for_schema( + json_schema["properties"]["invite_room_state"]["items"], + ) + schema["content_fields"].extend(invite_room_state) - # grab msgtype if it is the right kind of event - msgtype = Units.prop( - json_schema, "properties/content/properties/msgtype/enum" - ) - if msgtype: - schema["msgtype"] = msgtype[0] # enum prop - - # link to msgtypes for m.room.message - if schema["type"] == "m.room.message" and not msgtype: - schema["desc"] += ( - " For more information on ``msgtypes``, see "+ - "`m.room.message msgtypes`_." - ) + # grab msgtype if it is the right kind of event + msgtype = Units.prop( + json_schema, "properties/content/properties/msgtype/enum" + ) + if msgtype: + schema["msgtype"] = msgtype[0] # enum prop + + # link to msgtypes for m.room.message + if schema["type"] == "m.room.message" and not msgtype: + schema["desc"] += ( + " For more information on ``msgtypes``, see "+ + "`m.room.message msgtypes`_." + ) - # Assign state key info if it has some - if schema["typeof"] == "State Event": - skey_desc = Units.prop( - json_schema, "properties/state_key/description" - ) - if not skey_desc: - raise Exception("Missing description for state_key") - schema["typeof_info"] = "``state_key``: %s" % skey_desc + # Assign state key info if it has some + if schema["typeof"] == "State Event": + skey_desc = Units.prop( + json_schema, "properties/state_key/description" + ) + if not skey_desc: + raise Exception("Missing description for state_key") + schema["typeof_info"] = "``state_key``: %s" % skey_desc - schemata[filename] = schema - return schemata + return schema def load_changelogs(self): changelogs = {} From 2691d4925bf9f0ce90185bee66c064ddae68430d Mon Sep 17 00:00:00 2001 From: Erik Johnston <erik@matrix.org> Date: Wed, 22 Jun 2016 14:07:24 +0100 Subject: [PATCH 14/20] s/currently_online/currently_active/ --- api/client-server/presence.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/presence.yaml b/api/client-server/presence.yaml index fc47029c..4f637698 100644 --- a/api/client-server/presence.yaml +++ b/api/client-server/presence.yaml @@ -54,7 +54,7 @@ paths: status_msg: type: string description: "The status message to attach to this state." - currently_online: + currently_active: type: boolean description: "Whether the user is currently active" required: ["presence"] From af091ff6142fa613c9db36f1c863145d9caec66c Mon Sep 17 00:00:00 2001 From: Mark Haines <mark.haines@matrix.org> Date: Wed, 22 Jun 2016 16:34:23 +0100 Subject: [PATCH 15/20] Document changes to the default push rules --- specification/modules/push.rst | 109 ++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 42 deletions(-) diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 3bac810c..0e5fffd1 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -245,6 +245,73 @@ Definition: ] } +``.m.rule.invite_for_me`` +````````````````````````` +Matches any invites to a new room for this user. + +Definition: + +.. code:: json + + { + "rule_id": ".m.rule.invite_for_me", + "default": true, + "enabled": true, + "conditions": [ + { + "key": "type", + "kind": "event_match", + "pattern": "m.room.member" + }, + { + "key": "content.membership", + "kind": "event_match", + "pattern": "invite" + }, + { + "key": "state_key", + "kind": "event_match", + "pattern": "[the user's Matrix ID]" + } + ], + "actions": [ + "notify", + { + "set_tweak": "sound", + "value": "default" + }, + { + "set_tweak": "highlight", + "value": false + } + ] + } + +``.m.rule.member_event`` +```````````````````````` + +Matches any ``m.room.member_event``. + +Definition: + +.. code:: json + + { + "rule_id": ".m.rule.member_event", + "default": true, + "enabled": true, + "conditions": [ + { + "key": "type", + "kind": "event_match", + "pattern": "m.room.member" + } + ], + "actions": [ + "dont_notify" + ] + } + Default Content Rules ^^^^^^^^^^^^^^^^^^^^^ @@ -369,48 +436,6 @@ Definition: ] } -``.m.rule.invite_for_me`` -````````````````````````` -Matches any invites to a new room for this user. - -Definition: - -.. code:: json - - { - "rule_id": ".m.rule.invite_for_me", - "default": true, - "enabled": true, - "conditions": [ - { - "key": "type", - "kind": "event_match", - "pattern": "m.room.member" - }, - { - "key": "content.membership", - "kind": "event_match", - "pattern": "invite" - }, - { - "key": "state_key", - "kind": "event_match", - "pattern": "[the user's Matrix ID]" - } - ], - "actions": [ - "notify", - { - "set_tweak": "sound", - "value": "default" - }, - { - "set_tweak": "highlight", - "value": false - } - ] - } - ``.m.rule.message`` ``````````````````` Matches all chat messages. From e594132e954ff7e47ed05c7d823b412c48b71681 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <github@rvanderhoff.org.uk> Date: Wed, 22 Jun 2016 17:32:01 +0100 Subject: [PATCH 16/20] m.room.member: yaml tweak Quote "string" for consistency with "null" --- event-schemas/schema/m.room.member | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 055a1945..f9aa5051 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -28,7 +28,7 @@ properties: displayname: description: 'The display name for this user, if any. This is added by the homeserver.' type: - - string + - "string" - "null" membership: description: The membership state of the user. From adb57687313360dc1d642a75a7f5d9eaa14c3551 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <richard@matrix.org> Date: Wed, 22 Jun 2016 14:13:23 +0100 Subject: [PATCH 17/20] m.room.power_levels: clarify documentation - clarify description and add text for invite, ban, etc. - the keys aren't required. Document their defaults - add 'invite' to example --- changelogs/client_server.rst | 1 + event-schemas/examples/m.room.power_levels | 1 + event-schemas/schema/m.room.power_levels | 47 +++++++++++++--------- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index ae2736f2..081d7d34 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -7,6 +7,7 @@ federated aliases - ``GET /directory/room/{roomAlias}`` cannot return a 409; the ``PUT`` endpoint can, however. + - Clarify the behaviour of the ``m.room.power_levels`` event. r0.1.0 ====== diff --git a/event-schemas/examples/m.room.power_levels b/event-schemas/examples/m.room.power_levels index 42ef5a5d..0c8f8bc5 100644 --- a/event-schemas/examples/m.room.power_levels +++ b/event-schemas/examples/m.room.power_levels @@ -7,6 +7,7 @@ "m.room.power_levels": 100 }, "events_default": 0, + "invite": 50, "kick": 50, "redact": 50, "state_default": 50, diff --git a/event-schemas/schema/m.room.power_levels b/event-schemas/schema/m.room.power_levels index 5244ba79..0353b166 100644 --- a/event-schemas/schema/m.room.power_levels +++ b/event-schemas/schema/m.room.power_levels @@ -15,14 +15,25 @@ description: |- ``events``, then the user must have at least the level specified in order to send that event. If the event type is not supplied, it defaults to ``events_default`` for Message Events and ``state_default`` for State - Events. If there is no ``state_default`` in the ``power_levels`` event, the - ``state_default`` is 50. If the room contains no ``power_levels`` event, the - ``state_default`` is 0. The ``events_default`` is 0 in either of these cases. + Events. + + If there is no ``state_default`` in the ``m.room.power_levels`` event, the + ``state_default`` is 50. If there is no ``events_default`` in the + ``m.room.power_levels`` event, the ``events_default`` is 0. If the room + contains no ``m.room.power_levels`` event, *both* the ``state_default`` and + ``events_default`` are 0. + + The power level required to invite a user to the room, kick a user from the + room, ban a user from the room, or redact an event, is defined by ``invite``, + ``kick``, ``ban``, and ``redact``, respectively. Each of these levels defaults + to 50 if they are not specified in the ``m.room.power_levels`` event, or if + the room contains no ``m.room.power_levels`` event. + properties: content: properties: ban: - description: The level required to ban a user. + description: The level required to ban a user. Defaults to 50 if unspecified. type: number events: additionalProperties: @@ -31,19 +42,24 @@ properties: title: Event power levels type: object events_default: - description: The default level required to send message events. Can be overridden by the ``events`` key. + description: |- + The default level required to send message events. Can be + overridden by the ``events`` key. Defaults to 0 if unspecified. type: number invite: - description: The level required to invite a user. + description: The level required to invite a user. Defaults to 50 if unspecified. type: number kick: - description: The level required to kick a user. + description: The level required to kick a user. Defaults to 50 if unspecified. type: number redact: - description: The level required to redact an event. + description: The level required to redact an event. Defaults to 50 if unspecified. type: number state_default: - description: The default level required to send state events. Can be overridden by the ``events`` key. + description: |- + The default level required to send state events. Can be overridden + by the ``events`` key. Defaults to 50 if unspecified, but 0 if + there is no ``m.room.power_levels`` event at all. type: number users: additionalProperties: @@ -52,16 +68,11 @@ properties: title: User power levels type: object users_default: - description: 'The default power level for every user in the room, unless their ``user_id`` is mentioned in the ``users`` key.' + description: |- + The default power level for every user in the room, unless their + ``user_id`` is mentioned in the ``users`` key. Defaults to 0 if + unspecified. type: number - required: - - ban - - events - - events_default - - kick - - redact - - state_default - - users type: object state_key: description: A zero-length string. From c0e5f3c3ca040783ed89a383f2086018a6e530f5 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <richard@matrix.org> Date: Wed, 22 Jun 2016 17:50:34 +0100 Subject: [PATCH 18/20] matrix_templates/units.py: add some comments ... to help understand the slightly cryptic python incantation. --- templating/matrix_templates/units.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index e0394d15..07f5aefb 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -172,9 +172,10 @@ def get_json_schema_object_fields(obj, enforce_title=False, except Exception, e: e2 = Exception("Error reading property %s.%s: %s" % (obj_title, key_name, str(e))) + # throw the new exception with the old stack trace, so that + # we don't lose information about where the error occurred. raise e2, None, sys.exc_info()[2] - tables.insert(0, { "title": obj_title, "rows": first_table_rows, @@ -639,6 +640,8 @@ class MatrixUnits(Units): except Exception, e: e2 = Exception("Error reading event schema "+filepath+": "+ str(e)) + # throw the new exception with the old stack trace, so that + # we don't lose information about where the error occurred. raise e2, None, sys.exc_info()[2] return schemata From 0de8ba7f0a5c6ded09d505a2d6573a385029c18e Mon Sep 17 00:00:00 2001 From: Erik Johnston <erik@matrix.org> Date: Wed, 29 Jun 2016 10:35:31 +0100 Subject: [PATCH 19/20] currently_active is a param on GET response, not put --- api/client-server/presence.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/api/client-server/presence.yaml b/api/client-server/presence.yaml index 4f637698..1c97be94 100644 --- a/api/client-server/presence.yaml +++ b/api/client-server/presence.yaml @@ -54,9 +54,6 @@ paths: status_msg: type: string description: "The status message to attach to this state." - currently_active: - type: boolean - description: "Whether the user is currently active" required: ["presence"] responses: 200: @@ -107,6 +104,10 @@ paths: status_msg: type: [string, "null"] description: The state message for this user if one was set. + currently_active: + type: boolean + description: "Whether the user is currently active" + required: ["presence"] 404: description: |- There is no presence state for this user. This user may not exist or From c83940750ce178e9ac5a3b5c9b075f3f95fba33a Mon Sep 17 00:00:00 2001 From: Erik Johnston <erik@matrix.org> Date: Wed, 29 Jun 2016 10:40:39 +0100 Subject: [PATCH 20/20] Update m.presence --- event-schemas/examples/m.presence | 1 + event-schemas/schema/m.presence | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/event-schemas/examples/m.presence b/event-schemas/examples/m.presence index 695bd99b..ead92ccd 100644 --- a/event-schemas/examples/m.presence +++ b/event-schemas/examples/m.presence @@ -3,6 +3,7 @@ "avatar_url": "mxc://localhost:wefuiwegh8742w", "last_active_ago": 2478593, "presence": "online", + "currently_active": false, "user_id": "@example:localhost" }, "event_id": "$WLGTSEFSEF:localhost", diff --git a/event-schemas/schema/m.presence b/event-schemas/schema/m.presence index 79852ac6..bc0f9078 100644 --- a/event-schemas/schema/m.presence +++ b/event-schemas/schema/m.presence @@ -21,7 +21,11 @@ "presence": { "type": "string", "description": "The presence state for this user.", - "enum": ["online", "offline", "unavailable", "free_for_chat", "hidden"] + "enum": ["online", "offline", "unavailable"] + }, + "currently_active": { + "type": boolean, + "description": "Whether the user is currently active" }, "user_id": { "type": "string",