Mercurial > libervia-backend
comparison sat/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py @ 2562:26edcf3a30eb
core, setup: huge cleaning:
- moved directories from src and frontends/src to sat and sat_frontends, which is the recommanded naming convention
- move twisted directory to root
- removed all hacks from setup.py, and added missing dependencies, it is now clean
- use https URL for website in setup.py
- removed "Environment :: X11 Applications :: GTK", as wix is deprecated and removed
- renamed sat.sh to sat and fixed its installation
- added python_requires to specify Python version needed
- replaced glib2reactor which use deprecated code by gtk3reactor
sat can now be installed directly from virtualenv without using --system-site-packages anymore \o/
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 02 Apr 2018 19:44:50 +0200 |
parents | src/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py@0046283a285d |
children | 779351da2c13 |
comparison
equal
deleted
inserted
replaced
2561:bd30dc3ffe5a | 2562:26edcf3a30eb |
---|---|
1 #!/usr/bin/env python2 | |
2 #-*- coding: utf-8 -*- | |
3 | |
4 # SAT communication bridge | |
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org) | |
6 | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 from sat.core.i18n import _ | |
21 from bridge_frontend import BridgeException | |
22 import dbus | |
23 from sat.core.log import getLogger | |
24 log = getLogger(__name__) | |
25 from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError | |
26 | |
27 from dbus.mainloop.glib import DBusGMainLoop | |
28 DBusGMainLoop(set_as_default=True) | |
29 | |
30 import ast | |
31 | |
32 const_INT_PREFIX = "org.goffi.SAT" # Interface prefix | |
33 const_ERROR_PREFIX = const_INT_PREFIX + ".error" | |
34 const_OBJ_PATH = '/org/goffi/SAT/bridge' | |
35 const_CORE_SUFFIX = ".core" | |
36 const_PLUGIN_SUFFIX = ".plugin" | |
37 const_TIMEOUT = 120 | |
38 | |
39 | |
40 def dbus_to_bridge_exception(dbus_e): | |
41 """Convert a DBusException to a BridgeException. | |
42 | |
43 @param dbus_e (DBusException) | |
44 @return: BridgeException | |
45 """ | |
46 full_name = dbus_e.get_dbus_name() | |
47 if full_name.startswith(const_ERROR_PREFIX): | |
48 name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1:] | |
49 else: | |
50 name = full_name | |
51 # XXX: dbus_e.args doesn't contain the original DBusException args, but we | |
52 # receive its serialized form in dbus_e.args[0]. From that we can rebuild | |
53 # the original arguments list thanks to ast.literal_eval (secure eval). | |
54 message = dbus_e.get_dbus_message() # similar to dbus_e.args[0] | |
55 try: | |
56 message, condition = ast.literal_eval(message) | |
57 except (SyntaxError, ValueError, TypeError): | |
58 condition = '' | |
59 return BridgeException(name, message, condition) | |
60 | |
61 | |
62 class Bridge(object): | |
63 | |
64 def bridgeConnect(self, callback, errback): | |
65 try: | |
66 self.sessions_bus = dbus.SessionBus() | |
67 self.db_object = self.sessions_bus.get_object(const_INT_PREFIX, | |
68 const_OBJ_PATH) | |
69 self.db_core_iface = dbus.Interface(self.db_object, | |
70 dbus_interface=const_INT_PREFIX + const_CORE_SUFFIX) | |
71 self.db_plugin_iface = dbus.Interface(self.db_object, | |
72 dbus_interface=const_INT_PREFIX + const_PLUGIN_SUFFIX) | |
73 except dbus.exceptions.DBusException, e: | |
74 if e._dbus_error_name in ('org.freedesktop.DBus.Error.ServiceUnknown', | |
75 'org.freedesktop.DBus.Error.Spawn.ExecFailed'): | |
76 errback(BridgeExceptionNoService()) | |
77 elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported': | |
78 log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it")) | |
79 errback(BridgeInitError) | |
80 else: | |
81 errback(e) | |
82 callback() | |
83 #props = self.db_core_iface.getProperties() | |
84 | |
85 def register_signal(self, functionName, handler, iface="core"): | |
86 if iface == "core": | |
87 self.db_core_iface.connect_to_signal(functionName, handler) | |
88 elif iface == "plugin": | |
89 self.db_plugin_iface.connect_to_signal(functionName, handler) | |
90 else: | |
91 log.error(_('Unknown interface')) | |
92 | |
93 def __getattribute__(self, name): | |
94 """ usual __getattribute__ if the method exists, else try to find a plugin method """ | |
95 try: | |
96 return object.__getattribute__(self, name) | |
97 except AttributeError: | |
98 # The attribute is not found, we try the plugin proxy to find the requested method | |
99 | |
100 def getPluginMethod(*args, **kwargs): | |
101 # We first check if we have an async call. We detect this in two ways: | |
102 # - if we have the 'callback' and 'errback' keyword arguments | |
103 # - or if the last two arguments are callable | |
104 | |
105 async = False | |
106 args = list(args) | |
107 | |
108 if kwargs: | |
109 if 'callback' in kwargs: | |
110 async = True | |
111 _callback = kwargs.pop('callback') | |
112 _errback = kwargs.pop('errback', lambda failure: log.error(unicode(failure))) | |
113 try: | |
114 args.append(kwargs.pop('profile')) | |
115 except KeyError: | |
116 try: | |
117 args.append(kwargs.pop('profile_key')) | |
118 except KeyError: | |
119 pass | |
120 # at this point, kwargs should be empty | |
121 if kwargs: | |
122 log.warnings(u"unexpected keyword arguments, they will be ignored: {}".format(kwargs)) | |
123 elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]): | |
124 async = True | |
125 _errback = args.pop() | |
126 _callback = args.pop() | |
127 | |
128 method = getattr(self.db_plugin_iface, name) | |
129 | |
130 if async: | |
131 kwargs['timeout'] = const_TIMEOUT | |
132 kwargs['reply_handler'] = _callback | |
133 kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err)) | |
134 | |
135 return method(*args, **kwargs) | |
136 | |
137 return getPluginMethod | |
138 | |
139 ##METHODS_PART## |