aboutsummaryrefslogtreecommitdiffstats
path: root/examples/dbus
diff options
context:
space:
mode:
authordavemds <dave@gurumeditation.it>2013-05-05 16:41:14 +0200
committerdavemds <dave@gurumeditation.it>2013-05-05 16:41:14 +0200
commit1c261835d50137535d2e1e48916f3b026f9d8175 (patch)
tree2f2a3ab964e0286ee380a792ef3a0352502a3c32 /examples/dbus
parentAdd an example for installing to a custom prefix to the INSTALL file and (diff)
downloadpython-efl-1c261835d50137535d2e1e48916f3b026f9d8175.tar.gz
Python-EFL: espionage: can now execute methods, with arguments too.
Diffstat (limited to 'examples/dbus')
-rwxr-xr-xexamples/dbus/test_dbus_spy.py146
1 files changed, 140 insertions, 6 deletions
diff --git a/examples/dbus/test_dbus_spy.py b/examples/dbus/test_dbus_spy.py
index 408ca4a..efcb145 100755
--- a/examples/dbus/test_dbus_spy.py
+++ b/examples/dbus/test_dbus_spy.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# -*- coding: utf-8 -*-
import dbus
import xml.etree.ElementTree as ElementTree
@@ -9,8 +10,14 @@ from efl.elementary.window import StandardWindow
from efl.elementary.background import Background
from efl.elementary.box import Box
from efl.elementary.button import Button
+from efl.elementary.entry import Entry, \
+ Entry_markup_to_utf8 as markup_to_utf8, \
+ Entry_utf8_to_markup as utf8_to_markup
from efl.elementary.flipselector import FlipSelector
+from efl.elementary.label import Label
from efl.elementary.panes import Panes
+from efl.elementary.popup import Popup
+from efl.elementary.separator import Separator
from efl.elementary.genlist import Genlist, GenlistItem, GenlistItemClass
from efl.dbus_mainloop import DBusEcoreMainLoop
@@ -111,6 +118,7 @@ class DBusMethod(DBusNode):
def returns_str(self):
return ', '.join([(ty+' '+name).strip() for name, ty in self._returns])
+
class DBusSignal(DBusNode):
"""object to represent a DBus Signal"""
def __init__(self, name, parent_iface):
@@ -141,11 +149,11 @@ def recursive_introspect(bus, named_service, object_path, ret_data=None):
xml_root = ElementTree.fromstring(xml_data)
# debug
- print('=' * 80)
- print("Introspecting path:'%s' on service:'%s'" % (object_path, named_service))
- print('=' * 80)
- print(xml_data)
- print('=' * 80)
+ # print('=' * 80)
+ # print("Introspecting path:'%s' on service:'%s'" % (object_path, named_service))
+ # print('=' * 80)
+ # print(xml_data)
+ # print('=' * 80)
# traverse the xml tree
if xml_root.find('interface'):
@@ -299,7 +307,7 @@ class NodeItemClass(GenlistItemClass):
params = obj.params_str
rets = obj.returns_str
if rets:
- return '[METH] %s(%s) -> (%s)' % (obj.name, params, rets)
+ return '[METH] %s(%s) ↦ (%s)' % (obj.name, params, rets)
else:
return '[METH] %s(%s)' % (obj.name, params)
if isinstance(obj, DBusSignal):
@@ -308,12 +316,14 @@ class NodeItemClass(GenlistItemClass):
class DetailList(Genlist):
def __init__(self, parent):
Genlist.__init__(self, parent)
+ self._parent = parent
self.itc = NodeItemClass()
self.itc_g = ObjectItemClass()
self.callback_expand_request_add(self.expand_request_cb)
self.callback_expanded_add(self.expanded_cb)
self.callback_contract_request_add(self.contract_request_cb)
self.callback_contracted_add(self.contracted_cb)
+ self.callback_clicked_double_add(self.double_click_cb)
def populate(self, name):
@@ -358,6 +368,130 @@ class DetailList(Genlist):
def contracted_cb(self, genlist, item):
item.subitems_clear()
+ def double_click_cb(self, genlist, item):
+ if isinstance(item.data, DBusMethod):
+ MethodRunner(self._parent, item.data)
+
+
+### Methods runner
+class MethodRunner(Popup):
+ def __init__(self, parent, method):
+ Popup.__init__(self, parent)
+ self._method = method
+ self._param_entry = None
+ self._return_entry = None
+
+ # title
+ self.part_text_set('title,text', 'Method: %s()' % method.name)
+ self.show()
+
+ # content is vbox
+ vbox = Box(parent)
+ vbox.show()
+ self.content = vbox
+
+ # params label + entry
+ if len(method.params) > 0:
+ label = Label(parent)
+ label.size_hint_align = 0.0, 0.0
+ label.text = 'Params: ' + method.params_str
+ label.show()
+ vbox.pack_end(label)
+
+ en = Entry(parent)
+ self._param_entry = en
+ en.editable = True
+ en.scrollable = True
+ en.single_line = True
+ en.entry = ''
+ en.size_hint_weight = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
+ en.size_hint_align = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL
+ en.show()
+ vbox.pack_end(en)
+
+ sp = Separator(win)
+ sp.horizontal = True
+ sp.show()
+ vbox.pack_end(sp)
+
+ # returns label + entry
+ label = Label(parent)
+ label.size_hint_align = 0.0, 0.0
+ label.text = 'Returns: '
+ label.text += method.returns_str if method.returns_str else 'None'
+ label.show()
+ vbox.pack_end(label)
+
+ en = Entry(parent)
+ self._return_entry = en
+ en.size_hint_weight = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
+ en.size_hint_align = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL
+ en.editable = False
+ en.scrollable = True
+ en.disabled = True
+ en.single_line = True # TODO this is wrong, but the only way to show the entry :/
+ en.entry = '<br> <br> <br>'
+ en.show()
+ vbox.pack_end(en)
+
+ # popup buttons
+ btn = Button(parent)
+ btn.text = 'Close'
+ btn.callback_clicked_add(lambda b: self.delete())
+ self.part_content_set('button1', btn)
+
+ btn = Button(parent)
+ btn.text = 'Clear output'
+ btn.callback_clicked_add(lambda b: self._return_entry.entry_set(''))
+ self.part_content_set('button2', btn)
+
+ btn = Button(parent)
+ btn.text = 'Run method'
+ btn.callback_clicked_add(self.run_clicked_cb)
+ self.part_content_set('button3', btn)
+
+ def run_clicked_cb(self, btn):
+ # collect method infos
+ named_service = self._method.parent.parent.parent
+ object_path = self._method.parent.parent.name
+ iface_name = self._method.parent.name
+ method_name = self._method.name
+ if self._param_entry:
+ user_params = markup_to_utf8(self._param_entry.entry)
+ else:
+ user_params = None
+
+ # create the dbus proxy
+ obj = bus.get_object(named_service, object_path)
+ iface = dbus.Interface(obj, iface_name)
+ meth = iface.get_dbus_method(method_name)
+
+ # async method call # TODO make another example for this
+ try:
+ if user_params:
+ meth(eval(user_params),
+ reply_handler = self.reply_handler,
+ error_handler = self.error_handler)
+ else:
+ meth(reply_handler = self.reply_handler,
+ error_handler = self.error_handler)
+ except Exception as e:
+ s = "Error running method<br>Exception: "
+ self._return_entry.entry = s + utf8_to_markup(str(e))
+
+ # TODO find a way to catch errors after this point
+ # wrong params for example are raised later :/
+
+ def reply_handler(self, *rets):
+ if rets:
+ s = utf8_to_markup(str(*rets))
+ else:
+ s = "Method executed successfully.<br>Nothing returned."
+ self._return_entry.entry = s
+
+ def error_handler(self, *rets):
+ self._return_entry.entry = 'Error executing method'
+
### The main window
class MyWin(StandardWindow):