comparison libervia/backend/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py @ 4270:0d7bb4df2343

Reformatted code base using black.
author Goffi <goffi@goffi.org>
date Wed, 19 Jun 2024 18:44:57 +0200
parents 4b842c1fb686
children
comparison
equal deleted inserted replaced
4269:64a85ce8be70 4270:0d7bb4df2343
31 log = getLogger(__name__) 31 log = getLogger(__name__)
32 32
33 33
34 # Interface prefix 34 # Interface prefix
35 const_INT_PREFIX = config.config_get( 35 const_INT_PREFIX = config.config_get(
36 config.parse_main_conf(), 36 config.parse_main_conf(), "", "bridge_dbus_int_prefix", "org.libervia.Libervia"
37 "", 37 )
38 "bridge_dbus_int_prefix",
39 "org.libervia.Libervia")
40 const_ERROR_PREFIX = const_INT_PREFIX + ".error" 38 const_ERROR_PREFIX = const_INT_PREFIX + ".error"
41 const_OBJ_PATH = '/org/libervia/Libervia/bridge' 39 const_OBJ_PATH = "/org/libervia/Libervia/bridge"
42 const_CORE_SUFFIX = ".core" 40 const_CORE_SUFFIX = ".core"
43 const_PLUGIN_SUFFIX = ".plugin" 41 const_PLUGIN_SUFFIX = ".plugin"
44 const_TIMEOUT = 120 42 const_TIMEOUT = 120
45 43
46 44
50 @param dbus_e (DBusException) 48 @param dbus_e (DBusException)
51 @return: BridgeException 49 @return: BridgeException
52 """ 50 """
53 full_name = dbus_e.get_dbus_name() 51 full_name = dbus_e.get_dbus_name()
54 if full_name.startswith(const_ERROR_PREFIX): 52 if full_name.startswith(const_ERROR_PREFIX):
55 name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1:] 53 name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1 :]
56 else: 54 else:
57 name = full_name 55 name = full_name
58 # XXX: dbus_e.args doesn't contain the original DBusException args, but we 56 # XXX: dbus_e.args doesn't contain the original DBusException args, but we
59 # receive its serialized form in dbus_e.args[0]. From that we can rebuild 57 # receive its serialized form in dbus_e.args[0]. From that we can rebuild
60 # the original arguments list thanks to ast.literal_eval (secure eval). 58 # the original arguments list thanks to ast.literal_eval (secure eval).
61 message = dbus_e.get_dbus_message() # similar to dbus_e.args[0] 59 message = dbus_e.get_dbus_message() # similar to dbus_e.args[0]
62 try: 60 try:
63 message, condition = ast.literal_eval(message) 61 message, condition = ast.literal_eval(message)
64 except (SyntaxError, ValueError, TypeError): 62 except (SyntaxError, ValueError, TypeError):
65 condition = '' 63 condition = ""
66 return BridgeException(name, message, condition) 64 return BridgeException(name, message, condition)
67 65
68 66
69 class bridge: 67 class bridge:
70 68
71 def bridge_connect(self, callback, errback): 69 def bridge_connect(self, callback, errback):
72 try: 70 try:
73 self.sessions_bus = dbus.SessionBus() 71 self.sessions_bus = dbus.SessionBus()
74 self.db_object = self.sessions_bus.get_object(const_INT_PREFIX, 72 self.db_object = self.sessions_bus.get_object(
75 const_OBJ_PATH) 73 const_INT_PREFIX, const_OBJ_PATH
76 self.db_core_iface = dbus.Interface(self.db_object, 74 )
77 dbus_interface=const_INT_PREFIX + const_CORE_SUFFIX) 75 self.db_core_iface = dbus.Interface(
78 self.db_plugin_iface = dbus.Interface(self.db_object, 76 self.db_object, dbus_interface=const_INT_PREFIX + const_CORE_SUFFIX
79 dbus_interface=const_INT_PREFIX + const_PLUGIN_SUFFIX) 77 )
78 self.db_plugin_iface = dbus.Interface(
79 self.db_object, dbus_interface=const_INT_PREFIX + const_PLUGIN_SUFFIX
80 )
80 except dbus.exceptions.DBusException as e: 81 except dbus.exceptions.DBusException as e:
81 if e._dbus_error_name in ('org.freedesktop.DBus.Error.ServiceUnknown', 82 if e._dbus_error_name in (
82 'org.freedesktop.DBus.Error.Spawn.ExecFailed'): 83 "org.freedesktop.DBus.Error.ServiceUnknown",
84 "org.freedesktop.DBus.Error.Spawn.ExecFailed",
85 ):
83 errback(BridgeExceptionNoService()) 86 errback(BridgeExceptionNoService())
84 elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported': 87 elif e._dbus_error_name == "org.freedesktop.DBus.Error.NotSupported":
85 log.error(_("D-Bus is not launched, please see README to see instructions on how to launch it")) 88 log.error(
89 _(
90 "D-Bus is not launched, please see README to see instructions on how to launch it"
91 )
92 )
86 errback(BridgeInitError) 93 errback(BridgeInitError)
87 else: 94 else:
88 errback(e) 95 errback(e)
89 else: 96 else:
90 callback() 97 callback()
91 #props = self.db_core_iface.getProperties() 98 # props = self.db_core_iface.getProperties()
92 99
93 def register_signal(self, functionName, handler, iface="core"): 100 def register_signal(self, functionName, handler, iface="core"):
94 if iface == "core": 101 if iface == "core":
95 self.db_core_iface.connect_to_signal(functionName, handler) 102 self.db_core_iface.connect_to_signal(functionName, handler)
96 elif iface == "plugin": 103 elif iface == "plugin":
97 self.db_plugin_iface.connect_to_signal(functionName, handler) 104 self.db_plugin_iface.connect_to_signal(functionName, handler)
98 else: 105 else:
99 log.error(_('Unknown interface')) 106 log.error(_("Unknown interface"))
100 107
101 def __getattribute__(self, name): 108 def __getattribute__(self, name):
102 """ usual __getattribute__ if the method exists, else try to find a plugin method """ 109 """usual __getattribute__ if the method exists, else try to find a plugin method"""
103 try: 110 try:
104 return object.__getattribute__(self, name) 111 return object.__getattribute__(self, name)
105 except AttributeError: 112 except AttributeError:
106 # The attribute is not found, we try the plugin proxy to find the requested method 113 # The attribute is not found, we try the plugin proxy to find the requested method
107 114
112 119
113 async_ = False 120 async_ = False
114 args = list(args) 121 args = list(args)
115 122
116 if kwargs: 123 if kwargs:
117 if 'callback' in kwargs: 124 if "callback" in kwargs:
118 async_ = True 125 async_ = True
119 _callback = kwargs.pop('callback') 126 _callback = kwargs.pop("callback")
120 _errback = kwargs.pop('errback', lambda failure: log.error(str(failure))) 127 _errback = kwargs.pop(
128 "errback", lambda failure: log.error(str(failure))
129 )
121 try: 130 try:
122 args.append(kwargs.pop('profile')) 131 args.append(kwargs.pop("profile"))
123 except KeyError: 132 except KeyError:
124 try: 133 try:
125 args.append(kwargs.pop('profile_key')) 134 args.append(kwargs.pop("profile_key"))
126 except KeyError: 135 except KeyError:
127 pass 136 pass
128 # at this point, kwargs should be empty 137 # at this point, kwargs should be empty
129 if kwargs: 138 if kwargs:
130 log.warning("unexpected keyword arguments, they will be ignored: {}".format(kwargs)) 139 log.warning(
140 "unexpected keyword arguments, they will be ignored: {}".format(
141 kwargs
142 )
143 )
131 elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]): 144 elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]):
132 async_ = True 145 async_ = True
133 _errback = args.pop() 146 _errback = args.pop()
134 _callback = args.pop() 147 _callback = args.pop()
135 148
136 method = getattr(self.db_plugin_iface, name) 149 method = getattr(self.db_plugin_iface, name)
137 150
138 if async_: 151 if async_:
139 kwargs['timeout'] = const_TIMEOUT 152 kwargs["timeout"] = const_TIMEOUT
140 kwargs['reply_handler'] = _callback 153 kwargs["reply_handler"] = _callback
141 kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err)) 154 kwargs["error_handler"] = lambda err: _errback(
155 dbus_to_bridge_exception(err)
156 )
142 157
143 try: 158 try:
144 return method(*args, **kwargs) 159 return method(*args, **kwargs)
145 except ValueError as e: 160 except ValueError as e:
146 if e.args[0].startswith("Unable to guess signature"): 161 if e.args[0].startswith("Unable to guess signature"):
156 return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs) 171 return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs)
157 raise e 172 raise e
158 173
159 return get_plugin_method 174 return get_plugin_method
160 175
176
161 ##METHODS_PART## 177 ##METHODS_PART##
178
162 179
163 class AIOBridge(bridge): 180 class AIOBridge(bridge):
164 181
165 def register_signal(self, functionName, handler, iface="core"): 182 def register_signal(self, functionName, handler, iface="core"):
166 loop = asyncio.get_running_loop() 183 loop = asyncio.get_running_loop()
167 async_handler = lambda *args: asyncio.run_coroutine_threadsafe(handler(*args), loop) 184 async_handler = lambda *args: asyncio.run_coroutine_threadsafe(
185 handler(*args), loop
186 )
168 return super().register_signal(functionName, async_handler, iface) 187 return super().register_signal(functionName, async_handler, iface)
169 188
170 def __getattribute__(self, name): 189 def __getattribute__(self, name):
171 """ usual __getattribute__ if the method exists, else try to find a plugin method """ 190 """usual __getattribute__ if the method exists, else try to find a plugin method"""
172 try: 191 try:
173 return object.__getattribute__(self, name) 192 return object.__getattribute__(self, name)
174 except AttributeError: 193 except AttributeError:
175 # The attribute is not found, we try the plugin proxy to find the requested method 194 # The attribute is not found, we try the plugin proxy to find the requested method
176 def get_plugin_method(*args, **kwargs): 195 def get_plugin_method(*args, **kwargs):
177 loop = asyncio.get_running_loop() 196 loop = asyncio.get_running_loop()
178 fut = loop.create_future() 197 fut = loop.create_future()
179 method = getattr(self.db_plugin_iface, name) 198 method = getattr(self.db_plugin_iface, name)
180 reply_handler = lambda ret=None: loop.call_soon_threadsafe( 199 reply_handler = lambda ret=None: loop.call_soon_threadsafe(
181 fut.set_result, ret) 200 fut.set_result, ret
201 )
182 error_handler = lambda err: loop.call_soon_threadsafe( 202 error_handler = lambda err: loop.call_soon_threadsafe(
183 fut.set_exception, dbus_to_bridge_exception(err)) 203 fut.set_exception, dbus_to_bridge_exception(err)
204 )
184 try: 205 try:
185 method( 206 method(
186 *args, 207 *args,
187 **kwargs, 208 **kwargs,
188 timeout=const_TIMEOUT, 209 timeout=const_TIMEOUT,
189 reply_handler=reply_handler, 210 reply_handler=reply_handler,
190 error_handler=error_handler 211 error_handler=error_handler,
191 ) 212 )
192 except ValueError as e: 213 except ValueError as e:
193 if e.args[0].startswith("Unable to guess signature"): 214 if e.args[0].startswith("Unable to guess signature"):
194 # same hack as for bridge.__getattribute__ 215 # same hack as for bridge.__getattribute__
195 log.warning("using hack to work around inspection issue") 216 log.warning("using hack to work around inspection issue")
200 self.db_plugin_iface.get_dbus_method(name)( 221 self.db_plugin_iface.get_dbus_method(name)(
201 *args, 222 *args,
202 **kwargs, 223 **kwargs,
203 timeout=const_TIMEOUT, 224 timeout=const_TIMEOUT,
204 reply_handler=reply_handler, 225 reply_handler=reply_handler,
205 error_handler=error_handler 226 error_handler=error_handler,
206 ) 227 )
207 228
208 else: 229 else:
209 raise e 230 raise e
210 return fut 231 return fut
214 def bridge_connect(self): 235 def bridge_connect(self):
215 loop = asyncio.get_running_loop() 236 loop = asyncio.get_running_loop()
216 fut = loop.create_future() 237 fut = loop.create_future()
217 super().bridge_connect( 238 super().bridge_connect(
218 callback=lambda: loop.call_soon_threadsafe(fut.set_result, None), 239 callback=lambda: loop.call_soon_threadsafe(fut.set_result, None),
219 errback=lambda e: loop.call_soon_threadsafe(fut.set_exception, e) 240 errback=lambda e: loop.call_soon_threadsafe(fut.set_exception, e),
220 ) 241 )
221 return fut 242 return fut
222 243
244
223 ##ASYNC_METHODS_PART## 245 ##ASYNC_METHODS_PART##