dbus: add file format version negotiation for the JSON data
Export the supported versions in a Manager property and require the client to request a specific version in GetJSONData. Without that, the server could never update the format and clients would have to support every single historical version to make sure they can run against any version server. Fixes #98
This commit is contained in:
parent
d4ea6e3938
commit
caf1264952
21
README.md
21
README.md
|
@ -94,6 +94,12 @@ org.freedesktop.tuhi1.Manager
|
||||||
|
|
||||||
Read-only
|
Read-only
|
||||||
|
|
||||||
|
Property: JSONDataVersions (au)
|
||||||
|
Specifies the JSON file format versions the server supports. The
|
||||||
|
client must request one of these versions in Device.GetJSONData().
|
||||||
|
|
||||||
|
Read-only, constant
|
||||||
|
|
||||||
Method: StartSearch() -> ()
|
Method: StartSearch() -> ()
|
||||||
Start searching for available devices ready for registering
|
Start searching for available devices ready for registering
|
||||||
for an unspecified timeout. When the timeout expires or an error
|
for an unspecified timeout. When the timeout expires or an error
|
||||||
|
@ -295,14 +301,17 @@ org.freedesktop.tuhi1.Device
|
||||||
arriving, the device may still send events. It's the responsibility of
|
arriving, the device may still send events. It's the responsibility of
|
||||||
the client to handle events until the LiveStopped signal arrives.
|
the client to handle events until the LiveStopped signal arrives.
|
||||||
|
|
||||||
Method: GetJSONData(timestamp: t) -> (s)
|
Method: GetJSONData(file-version: u, timestamp: t) -> (s)
|
||||||
Returns a JSON file with the drawings specified by the timestamp
|
Returns a JSON file with the drawings specified by the timestamp
|
||||||
argument. The requested timestamp must be one of the entries in the
|
argument. The requested timestamp must be one of the entries in the
|
||||||
DrawingsAvailable property value. See section JSON FILE
|
DrawingsAvailable property value. The file-version argument specifies
|
||||||
|
the file format version the client requests. See section JSON FILE
|
||||||
FORMAT for the format of the returned data.
|
FORMAT for the format of the returned data.
|
||||||
|
|
||||||
Returns a string representing the JSON data from the last drawings or
|
Returns a string representing the JSON data from the last drawings or
|
||||||
the empty string if the timestamp is not available.
|
the empty string if the timestamp is not available or the file format
|
||||||
|
version is outside the server-supported range advertised in
|
||||||
|
Manager.JSONDataVersions.
|
||||||
|
|
||||||
Signal: ButtonPressRequired()
|
Signal: ButtonPressRequired()
|
||||||
Sent when the user is expected to press the physical button on the
|
Sent when the user is expected to press the physical button on the
|
||||||
|
@ -368,6 +377,12 @@ org.freedesktop.tuhi1.Device
|
||||||
JSON File Format
|
JSON File Format
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
The current file format version is 1. A server may only support a subset of
|
||||||
|
historical file formats, this subset is advertized as list of versions in
|
||||||
|
the **org.freedesktop.tuhi1.Manager.JSONDataVersions** property. Likewise, a
|
||||||
|
client may only support a subset of the possible formats. A client should
|
||||||
|
always pick the highest format supported by both the client and the server.
|
||||||
|
|
||||||
Below is the example file format (with comments, not present in the real
|
Below is the example file format (with comments, not present in the real
|
||||||
files). The JSON objects are "drawing" (the root object), "strokes",
|
files). The JSON objects are "drawing" (the root object), "strokes",
|
||||||
"points". Pseudo-code is used to illustrate the objects in the file.
|
"points". Pseudo-code is used to illustrate the objects in the file.
|
||||||
|
|
|
@ -271,7 +271,8 @@ class TuhiKeteDevice(_DBusObject):
|
||||||
self.live = False
|
self.live = False
|
||||||
|
|
||||||
def json(self, timestamp):
|
def json(self, timestamp):
|
||||||
return self.proxy.GetJSONData('(t)', timestamp)
|
SUPPORTED_FILE_FORMAT = 1
|
||||||
|
return self.proxy.GetJSONData('(ut)', SUPPORTED_FILE_FORMAT, timestamp)
|
||||||
|
|
||||||
def _on_signal_received(self, proxy, sender, signal, parameters):
|
def _on_signal_received(self, proxy, sender, signal, parameters):
|
||||||
if signal == 'ButtonPressRequired':
|
if signal == 'ButtonPressRequired':
|
||||||
|
|
|
@ -15,6 +15,7 @@ import logging
|
||||||
import errno
|
import errno
|
||||||
|
|
||||||
from gi.repository import GObject, Gio, GLib
|
from gi.repository import GObject, Gio, GLib
|
||||||
|
from .drawing import Drawing
|
||||||
|
|
||||||
logger = logging.getLogger('tuhi.dbus')
|
logger = logging.getLogger('tuhi.dbus')
|
||||||
|
|
||||||
|
@ -29,6 +30,10 @@ INTROSPECTION_XML = '''
|
||||||
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
<property type='au' name='JSONDataVersions' access='read'>
|
||||||
|
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='const'/>
|
||||||
|
</property>
|
||||||
|
|
||||||
<method name='StartSearch'>
|
<method name='StartSearch'>
|
||||||
<annotation name='org.freedesktop.DBus.Method.NoReply' value='true'/>
|
<annotation name='org.freedesktop.DBus.Method.NoReply' value='true'/>
|
||||||
</method>
|
</method>
|
||||||
|
@ -87,6 +92,7 @@ INTROSPECTION_XML = '''
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
<method name='GetJSONData'>
|
<method name='GetJSONData'>
|
||||||
|
<arg name='file_version' type='u' direction='in'/>
|
||||||
<arg name='timestamp' type='t' direction='in'/>
|
<arg name='timestamp' type='t' direction='in'/>
|
||||||
<arg name='json' type='s' direction='out'/>
|
<arg name='json' type='s' direction='out'/>
|
||||||
</method>
|
</method>
|
||||||
|
@ -427,7 +433,12 @@ class TuhiDBusDevice(_TuhiDBus):
|
||||||
self.live = False
|
self.live = False
|
||||||
|
|
||||||
def _json_data(self, args):
|
def _json_data(self, args):
|
||||||
index = args[0]
|
file_format = args[0]
|
||||||
|
if file_format != Drawing.JSON_FILE_FORMAT_VERSION:
|
||||||
|
logger.info(f'Unsupported file format requested: {file_format}')
|
||||||
|
return ''
|
||||||
|
|
||||||
|
index = args[1]
|
||||||
try:
|
try:
|
||||||
drawing = self.drawings[index]
|
drawing = self.drawings[index]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -533,6 +544,9 @@ class TuhiDBusServer(_TuhiDBus):
|
||||||
return GLib.Variant.new_objv([d.objpath for d in self._devices if d.registered])
|
return GLib.Variant.new_objv([d.objpath for d in self._devices if d.registered])
|
||||||
elif propname == 'Searching':
|
elif propname == 'Searching':
|
||||||
return GLib.Variant.new_boolean(self.is_searching)
|
return GLib.Variant.new_boolean(self.is_searching)
|
||||||
|
elif propname == 'JSONDataVersions':
|
||||||
|
return GLib.Variant.new_array(GLib.VariantType('u'),
|
||||||
|
[GLib.Variant.new_uint32(Drawing.JSON_FILE_FORMAT_VERSION)])
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue