Merge lp:~thekorn/zeitgeist/dbus-inspect-properties into lp:zeitgeist/0.1

Proposed by Markus Korn
Status: Merged
Merged at revision: 1675
Proposed branch: lp:~thekorn/zeitgeist/dbus-inspect-properties
Merge into: lp:zeitgeist/0.1
Diff against target: 137 lines (+58/-8)
2 files modified
_zeitgeist/engine/remote.py (+52/-2)
zeitgeist/client.py (+6/-6)
To merge this branch: bzr merge lp:~thekorn/zeitgeist/dbus-inspect-properties
Reviewer Review Type Date Requested Status
Zeitgeist Framework Team Pending
Review via email: mp+46890@code.launchpad.net

Description of the change

* Changed dbus introspection output to show information about properties (LP: #704931).
* raise a ValueError if the property methods are called on an unknown
  interface.

To post a comment you must log in.
Revision history for this message
Markus Korn (thekorn) wrote :

I'm going to change this branch such that we only use one xml parser, minidom or etree, thanks Mikkel for pointing this out.

1667. By Markus Korn

Use the etree parser in zeitgeist.client too, so we are not using two
different parsers for xml parsing.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '_zeitgeist/engine/remote.py'
2--- _zeitgeist/engine/remote.py 2011-01-18 10:49:04 +0000
3+++ _zeitgeist/engine/remote.py 2011-01-20 14:57:46 +0000
4@@ -5,6 +5,7 @@
5 # Copyright © 2009-2010 Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>
6 # Copyright © 2009 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
7 # Copyright © 2010 Seif Lotfy <seif@lotfy.com>
8+# Copyright © 2011 Markus Korn <thekorn@gmx.de>
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU Lesser General Public License as published by
12@@ -23,6 +24,8 @@
13 import dbus.service
14 import logging
15
16+from xml.etree import ElementTree
17+
18 from zeitgeist.datamodel import TimeRange, StorageState, ResultType, NULL_EVENT
19 from _zeitgeist.engine.datamodel import Event, Subject
20 from _zeitgeist.engine import get_engine
21@@ -30,6 +33,18 @@
22 from _zeitgeist.engine import constants
23 from _zeitgeist.singleton import SingletonApplication
24
25+class DBUSProperty(property):
26+
27+ def __init__(self, fget=None, fset=None, in_signature=None, out_signature=None):
28+ assert not (fget and not out_signature), "fget needs a dbus signature"
29+ assert not (fset and not in_signature), "fset needs a dbus signature"
30+ assert (fget and not fset) or (fset and fget), \
31+ "dbus properties needs to be either readonly or readwritable"
32+ self.in_signature = in_signature
33+ self.out_signature = out_signature
34+ super(DBUSProperty, self).__init__(fget, fset)
35+
36+
37 class RemoteInterface(SingletonApplication):
38 """
39 Primary interface to the Zeitgeist engine. Used to update and query
40@@ -42,8 +57,8 @@
41 :const:`org.gnome.zeitgeist.Engine`.
42 """
43 _dbus_properties = {
44- "version": property(lambda self: (0, 7, 0)),
45- "extensions": property(lambda self: list(self._engine.extensions.iter_names())),
46+ "version": DBUSProperty(lambda self: (0, 7, 0), out_signature="iii"),
47+ "extensions": DBUSProperty(lambda self: list(self._engine.extensions.iter_names()), out_signature="as"),
48 }
49
50 # Initialization
51@@ -357,6 +372,11 @@
52 @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
53 in_signature="ss", out_signature="v")
54 def Get(self, interface_name, property_name):
55+ if interface_name != constants.DBUS_INTERFACE:
56+ raise ValueError(
57+ "'%s' doesn't know anything about the '%s' interface" \
58+ %(constants.DBUS_INTERFACE, interface_name)
59+ )
60 try:
61 return self._dbus_properties[property_name].fget(self)
62 except KeyError, e:
63@@ -365,6 +385,11 @@
64 @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
65 in_signature="ssv", out_signature="")
66 def Set(self, interface_name, property_name, value):
67+ if interface_name != constants.DBUS_INTERFACE:
68+ raise ValueError(
69+ "'%s' doesn't know anything about the '%s' interface" \
70+ %(constants.DBUS_INTERFACE, interface_name)
71+ )
72 try:
73 prop = self._dbus_properties[property_name].fset(self, value)
74 except (KeyError, TypeError), e:
75@@ -373,7 +398,32 @@
76 @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
77 in_signature="s", out_signature="a{sv}")
78 def GetAll(self, interface_name):
79+ if interface_name != constants.DBUS_INTERFACE:
80+ raise ValueError(
81+ "'%s' doesn't know anything about the '%s' interface" \
82+ %(constants.DBUS_INTERFACE, interface_name)
83+ )
84 return dict((k, v.fget(self)) for (k,v) in self._dbus_properties.items())
85+
86+ # Instrospection Interface
87+
88+ @dbus.service.method(dbus.INTROSPECTABLE_IFACE, in_signature="", out_signature="s",
89+ path_keyword="object_path", connection_keyword="connection")
90+ def Introspect(self, object_path, connection):
91+ data = dbus.service.Object.Introspect(self, object_path, connection)
92+ xml = ElementTree.fromstring(data)
93+ for iface in xml.findall("interface"):
94+ if iface.attrib["name"] != constants.DBUS_INTERFACE:
95+ continue
96+ for prop_name, prop_func in self._dbus_properties.iteritems():
97+ prop = {"name": prop_name}
98+ if prop_func.fset is not None:
99+ prop["access"] = "readwrite"
100+ else:
101+ prop["access"] = "read"
102+ prop["type"] = prop_func.out_signature
103+ iface.append(ElementTree.Element("property", prop))
104+ return ElementTree.tostring(xml, encoding="UTF-8")
105
106 # Notifications interface
107
108
109=== modified file 'zeitgeist/client.py'
110--- zeitgeist/client.py 2011-01-17 15:54:47 +0000
111+++ zeitgeist/client.py 2011-01-20 14:57:46 +0000
112@@ -28,7 +28,7 @@
113 import logging
114 import inspect
115
116-from xml.dom.minidom import parseString as minidom_parse
117+from xml.etree import ElementTree
118
119 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
120
121@@ -48,11 +48,11 @@
122 a tuple, where the first item is a list of all methods and the
123 second one a list of all signals for the related interface
124 """
125- doc = minidom_parse(introspection_xml)
126- nodes = doc.getElementsByTagName("signal")
127- signals = [node.getAttribute("name") for node in nodes]
128- nodes = doc.getElementsByTagName("method")
129- methods = [node.getAttribute("name") for node in nodes]
130+ xml = ElementTree.fromstring(introspection_xml)
131+ nodes = xml.findall("interface/signal")
132+ signals = [node.attrib["name"] for node in nodes]
133+ nodes = xml.findall("interface/method")
134+ methods = [node.attrib["name"] for node in nodes]
135 try:
136 methods.remove("Introspect") # Introspect is not part of the API
137 except ValueError:

Subscribers

People subscribed via source and target branches