← Back to team overview

zeitgeist team mailing list archive

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

 

Markus Korn has proposed merging lp:~thekorn/zeitgeist/dbus-inspect-properties into lp:zeitgeist.

Requested reviews:
  Zeitgeist Framework Team (zeitgeist)

For more details, see:
https://code.launchpad.net/~thekorn/zeitgeist/dbus-inspect-properties/+merge/46890

* Changed dbus introspection output to show information about properties (LP: #704931).
* raise a ValueError if the property methods are called on an unknown
  interface.
-- 
https://code.launchpad.net/~thekorn/zeitgeist/dbus-inspect-properties/+merge/46890
Your team Zeitgeist Framework Team is requested to review the proposed merge of lp:~thekorn/zeitgeist/dbus-inspect-properties into lp:zeitgeist.
=== modified file '_zeitgeist/engine/remote.py'
--- _zeitgeist/engine/remote.py	2011-01-18 10:49:04 +0000
+++ _zeitgeist/engine/remote.py	2011-01-20 11:21:12 +0000
@@ -5,6 +5,7 @@
 # Copyright © 2009-2010 Siegfried-Angel Gevatter Pujals <rainct@xxxxxxxxxx>
 # Copyright © 2009 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@xxxxxxxxx>
 # Copyright © 2010 Seif Lotfy <seif@xxxxxxxxx>
+# Copyright © 2011 Markus Korn <thekorn@xxxxxx>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published by
@@ -23,6 +24,8 @@
 import dbus.service
 import logging
 
+from xml.etree import ElementTree
+
 from zeitgeist.datamodel import TimeRange, StorageState, ResultType, NULL_EVENT
 from _zeitgeist.engine.datamodel import Event, Subject
 from _zeitgeist.engine import get_engine
@@ -30,6 +33,18 @@
 from _zeitgeist.engine import constants
 from _zeitgeist.singleton import SingletonApplication
 
+class DBUSProperty(property):
+	
+	def __init__(self, fget=None, fset=None, in_signature=None, out_signature=None):
+		assert not (fget and not out_signature), "fget needs a dbus signature"
+		assert not (fset and not in_signature), "fset needs a dbus signature"
+		assert (fget and not fset) or (fset and fget), \
+			"dbus properties needs to be either readonly or readwritable"
+		self.in_signature = in_signature
+		self.out_signature = out_signature
+		super(DBUSProperty, self).__init__(fget, fset)
+
+
 class RemoteInterface(SingletonApplication):
 	"""
 	Primary interface to the Zeitgeist engine. Used to update and query
@@ -42,8 +57,8 @@
 	:const:`org.gnome.zeitgeist.Engine`.
 	"""
 	_dbus_properties = {
-		"version": property(lambda self: (0, 7, 0)),
-		"extensions": property(lambda self: list(self._engine.extensions.iter_names())),
+		"version": DBUSProperty(lambda self: (0, 7, 0), out_signature="iii"),
+		"extensions": DBUSProperty(lambda self: list(self._engine.extensions.iter_names()), out_signature="as"),
 	}
 	
 	# Initialization
@@ -357,6 +372,11 @@
 	@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
 						 in_signature="ss", out_signature="v")
 	def Get(self, interface_name, property_name):
+		if interface_name != constants.DBUS_INTERFACE:
+			raise ValueError(
+				"'%s' doesn't know anything about the '%s' interface" \
+				%(constants.DBUS_INTERFACE, interface_name)
+			)
 		try:
 			return self._dbus_properties[property_name].fget(self)
 		except KeyError, e:
@@ -365,6 +385,11 @@
 	@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
 						 in_signature="ssv", out_signature="")
 	def Set(self, interface_name, property_name, value):
+		if interface_name != constants.DBUS_INTERFACE:
+			raise ValueError(
+				"'%s' doesn't know anything about the '%s' interface" \
+				%(constants.DBUS_INTERFACE, interface_name)
+			)
 		try:
 			prop = self._dbus_properties[property_name].fset(self, value)
 		except (KeyError, TypeError), e:
@@ -373,7 +398,32 @@
 	@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
 						 in_signature="s", out_signature="a{sv}")
 	def GetAll(self, interface_name):
+		if interface_name != constants.DBUS_INTERFACE:
+			raise ValueError(
+				"'%s' doesn't know anything about the '%s' interface" \
+				%(constants.DBUS_INTERFACE, interface_name)
+			)
 		return dict((k, v.fget(self)) for (k,v) in self._dbus_properties.items())
+		
+	# Instrospection Interface
+	
+	@dbus.service.method(dbus.INTROSPECTABLE_IFACE, in_signature="", out_signature="s",
+						 path_keyword="object_path", connection_keyword="connection")
+	def Introspect(self, object_path, connection):
+		data = dbus.service.Object.Introspect(self, object_path, connection)
+		xml = ElementTree.fromstring(data)
+		for iface in xml.findall("interface"):
+			if iface.attrib["name"] != constants.DBUS_INTERFACE:
+				continue
+			for prop_name, prop_func in self._dbus_properties.iteritems():
+				prop = {"name": prop_name}
+				if prop_func.fset is not None:
+					prop["access"] = "readwrite"
+				else:
+					prop["access"] = "read"
+				prop["type"] = prop_func.out_signature
+				iface.append(ElementTree.Element("property", prop))
+		return ElementTree.tostring(xml, encoding="UTF-8")
 	
 	# Notifications interface
 	


Follow ups