Mercurial > libervia-backend
diff src/bridge/DBus.py @ 423:6c20c76abdcc
backend: - bridge async D-Bus method now automatically manage callback and errback, we just have to return a deferred
- getParams, getParamsForCategory and getParamsUI are now asynchronous
primitivus: management of asynchronous getParamsUI
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 07 Nov 2011 00:09:22 +0100 |
parents | 6c167a2e04b8 |
children | 72c13313b6d6 |
line wrap: on
line diff
--- a/src/bridge/DBus.py Sun Nov 06 15:19:51 2011 +0100 +++ b/src/bridge/DBus.py Mon Nov 07 00:09:22 2011 +0100 @@ -24,7 +24,8 @@ import dbus import dbus.service import dbus.mainloop.glib -from logging import debug, info +from logging import debug, info, error +from twisted.internet.defer import Deferred const_INT_PREFIX = "org.goffi.SAT" #Interface prefix const_ERROR_PREFIX = const_INT_PREFIX+".error" @@ -32,10 +33,20 @@ const_CORE_SUFFIX = ".core" const_PLUGIN_SUFFIX = ".plugin" +class MethodNotRegistered(dbus.DBusException): + _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered" + +class InternalError(dbus.DBusException): + _dbus_error_name = const_ERROR_PREFIX + ".InternalError" + +class AsyncNotDeferred(dbus.DBusException): + _dbus_error_name = const_ERROR_PREFIX + ".AsyncNotDeferred" + class GenericException(dbus.DBusException): - def __init__(self, name): + def __init__(self, twisted_error): super(GenericException,self).__init__() - self._dbus_error_name = const_ERROR_PREFIX+"."+name + mess = twisted_error.getErrorMessage() + self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(err.__class__)) class DbusObject(dbus.service.Object): @@ -47,6 +58,32 @@ def register(self, name, cb): self.cb[name]=cb + def _callback(self, name, *args, **kwargs): + """call the callback if it exists, raise an exception else + if the callback return a deferred, use async methods""" + if not name in self.cb: + raise MethodNotRegistered + + if "callback" in kwargs: + #we must have errback too + if not "errback" in kwargs: + error("errback is missing in method call [%s]" % name) + raise InternalError + callback = kwargs.pop("callback") + errback = kwargs.pop("errback") + async = True + else: + async = False + result = self.cb[name](*args, **kwargs) + if async: + if not isinstance(result, Deferred): + error("Asynchrone method [%s] does not return a Deferred." % name) + raise AsyncNotDeferred + result.addCallback(callback) + result.addErrback(lambda err:errback(GenericException(err))) + else: + return result + ### signals ### @dbus.service.signal(const_INT_PREFIX+const_PLUGIN_SUFFIX, @@ -134,217 +171,217 @@ in_signature='ss', out_signature='', async_callbacks=None) def addContact(self, entity_jid, profile_key="@DEFAULT@"): - return self.cb["addContact"](unicode(entity_jid), unicode(profile_key)) + return self._callback("addContact", unicode(entity_jid), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='', async_callbacks=('callback', 'errback')) def asyncConnect(self, profile_key="@DEFAULT@", callback=None, errback=None): - return self.cb["asyncConnect"](unicode(profile_key), callback, lambda arg:errback(GenericException(arg))) + return self._callback("asyncConnect", unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='', async_callbacks=('callback', 'errback')) def asyncCreateProfile(self, profile, callback=None, errback=None): - return self.cb["asyncCreateProfile"](unicode(profile), callback, lambda arg:errback(GenericException(arg))) + return self._callback("asyncCreateProfile", unicode(profile), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssss', out_signature='s', async_callbacks=('callback', 'errback')) def asyncGetParamA(self, name, category, attribute="value", profile_key="@DEFAULT@", callback=None, errback=None): - return self.cb["asyncGetParamA"](unicode(name), unicode(category), unicode(attribute), unicode(profile_key), callback, lambda arg:errback(GenericException(arg))) + return self._callback("asyncGetParamA", unicode(name), unicode(category), unicode(attribute), unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssss', out_signature='s', async_callbacks=None) def callMenu(self, category, name, menu_type, profile_key): - return self.cb["callMenu"](unicode(category), unicode(name), unicode(menu_type), unicode(profile_key)) + return self._callback("callMenu", unicode(category), unicode(name), unicode(menu_type), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='sba{ss}', out_signature='', async_callbacks=None) def confirmationAnswer(self, id, accepted, data): - return self.cb["confirmationAnswer"](unicode(id), accepted, data) + return self._callback("confirmationAnswer", unicode(id), accepted, data) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='', async_callbacks=None) def connect(self, profile_key="@DEFAULT@"): - return self.cb["connect"](unicode(profile_key)) + return self._callback("connect", unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='i', async_callbacks=None) def createProfile(self, profile): - return self.cb["createProfile"](unicode(profile)) + return self._callback("createProfile", unicode(profile)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ss', out_signature='', async_callbacks=None) def delContact(self, entity_jid, profile_key="@DEFAULT@"): - return self.cb["delContact"](unicode(entity_jid), unicode(profile_key)) + return self._callback("delContact", unicode(entity_jid), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='i', async_callbacks=None) def deleteProfile(self, profile): - return self.cb["deleteProfile"](unicode(profile)) + return self._callback("deleteProfile", unicode(profile)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='', async_callbacks=None) def disconnect(self, profile_key="@DEFAULT@"): - return self.cb["disconnect"](unicode(profile_key)) + return self._callback("disconnect", unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ss', out_signature='s', async_callbacks=None) def getConfig(self, section, name): - return self.cb["getConfig"](unicode(section), unicode(name)) + return self._callback("getConfig", unicode(section), unicode(name)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='a(sa{ss}as)', async_callbacks=None) def getContacts(self, profile_key="@DEFAULT@"): - return self.cb["getContacts"](unicode(profile_key)) + return self._callback("getContacts", unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssi', out_signature='a{i(ss)}', async_callbacks=None) def getHistory(self, from_jid, to_jid, size): - return self.cb["getHistory"](unicode(from_jid), unicode(to_jid), size) + return self._callback("getHistory", unicode(from_jid), unicode(to_jid), size) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ss', out_signature='s', async_callbacks=None) def getLastResource(self, contact_jid, profile_key="@DEFAULT@"): - return self.cb["getLastResource"](unicode(contact_jid), unicode(profile_key)) + return self._callback("getLastResource", unicode(contact_jid), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='sss', out_signature='s', async_callbacks=None) def getMenuHelp(self, category, name, menu_type): - return self.cb["getMenuHelp"](unicode(category), unicode(name), unicode(menu_type)) + return self._callback("getMenuHelp", unicode(category), unicode(name), unicode(menu_type)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='', out_signature='a(sss)', async_callbacks=None) def getMenus(self, ): - return self.cb["getMenus"]() + return self._callback("getMenus", ) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssss', out_signature='s', async_callbacks=None) def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@"): - return self.cb["getParamA"](unicode(name), unicode(category), unicode(attribute), unicode(profile_key)) + return self._callback("getParamA", unicode(name), unicode(category), unicode(attribute), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='s', - async_callbacks=None) - def getParams(self, profile_key="@DEFAULT@"): - return self.cb["getParams"](unicode(profile_key)) + async_callbacks=('callback', 'errback')) + def getParams(self, profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("getParams", unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='', out_signature='as', async_callbacks=None) def getParamsCategories(self, ): - return self.cb["getParamsCategories"]() + return self._callback("getParamsCategories", ) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ss', out_signature='s', - async_callbacks=None) - def getParamsForCategory(self, category, profile_key="@DEFAULT@"): - return self.cb["getParamsForCategory"](unicode(category), unicode(profile_key)) + async_callbacks=('callback', 'errback')) + def getParamsForCategory(self, category, profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("getParamsForCategory", unicode(category), unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='s', - async_callbacks=None) - def getParamsUI(self, profile_key="@DEFAULT@"): - return self.cb["getParamsUI"](unicode(profile_key)) + async_callbacks=('callback', 'errback')) + def getParamsUI(self, profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("getParamsUI", unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='a{sa{s(sia{ss})}}', async_callbacks=None) def getPresenceStatus(self, profile_key="@DEFAULT@"): - return self.cb["getPresenceStatus"](unicode(profile_key)) + return self._callback("getPresenceStatus", unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='s', async_callbacks=None) def getProfileName(self, profile_key="@DEFAULT@"): - return self.cb["getProfileName"](unicode(profile_key)) + return self._callback("getProfileName", unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='', out_signature='as', async_callbacks=None) def getProfilesList(self, ): - return self.cb["getProfilesList"]() + return self._callback("getProfilesList", ) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='a{ss}', async_callbacks=None) def getProgress(self, id): - return self.cb["getProgress"](unicode(id)) + return self._callback("getProgress", unicode(id)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='', out_signature='s', async_callbacks=None) def getVersion(self, ): - return self.cb["getVersion"]() + return self._callback("getVersion", ) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='a{ss}', async_callbacks=None) def getWaitingSub(self, profile_key="@DEFAULT@"): - return self.cb["getWaitingSub"](unicode(profile_key)) + return self._callback("getWaitingSub", unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='b', async_callbacks=None) def isConnected(self, profile_key="@DEFAULT@"): - return self.cb["isConnected"](unicode(profile_key)) + return self._callback("isConnected", unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='sa{ss}s', out_signature='s', async_callbacks=None) def launchAction(self, action_type, data, profile_key="@DEFAULT@"): - return self.cb["launchAction"](unicode(action_type), data, unicode(profile_key)) + return self._callback("launchAction", unicode(action_type), data, unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssssi', out_signature='s', async_callbacks=None) def registerNewAccount(self, login, password, email, host, port=5222): - return self.cb["registerNewAccount"](unicode(login), unicode(password), unicode(email), unicode(host), port) + return self._callback("registerNewAccount", unicode(login), unicode(password), unicode(email), unicode(host), port) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='sssss', out_signature='', async_callbacks=None) def sendMessage(self, to_jid, message, subject='', mess_type="chat", profile_key="@DEFAULT@"): - return self.cb["sendMessage"](unicode(to_jid), unicode(message), unicode(subject), unicode(mess_type), unicode(profile_key)) + return self._callback("sendMessage", unicode(to_jid), unicode(message), unicode(subject), unicode(mess_type), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssss', out_signature='', async_callbacks=None) def setParam(self, name, value, category, profile_key="@DEFAULT@"): - return self.cb["setParam"](unicode(name), unicode(value), unicode(category), unicode(profile_key)) + return self._callback("setParam", unicode(name), unicode(value), unicode(category), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssia{ss}s', out_signature='', async_callbacks=None) def setPresence(self, to_jid='', show='', priority=0, statuses={}, profile_key="@DEFAULT@"): - return self.cb["setPresence"](unicode(to_jid), unicode(show), priority, statuses, unicode(profile_key)) + return self._callback("setPresence", unicode(to_jid), unicode(show), priority, statuses, unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='sss', out_signature='', async_callbacks=None) def subscription(self, sub_type, entity, profile_key="@DEFAULT@"): - return self.cb["subscription"](unicode(sub_type), unicode(entity), unicode(profile_key)) + return self._callback("subscription", unicode(sub_type), unicode(entity), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssass', out_signature='', async_callbacks=None) def updateContact(self, entity_jid, name, groups, profile_key="@DEFAULT@"): - return self.cb["updateContact"](unicode(entity_jid), unicode(name), groups, unicode(profile_key)) + return self._callback("updateContact", unicode(entity_jid), unicode(name), groups, unicode(profile_key)) def __attributes(self, in_sign):