comparison libervia/frontends/bridge/pb.py @ 4074:26b7ed2817da

refactoring: rename `sat_frontends` to `libervia.frontends`
author Goffi <goffi@goffi.org>
date Fri, 02 Jun 2023 14:12:38 +0200
parents sat_frontends/bridge/pb.py@4b842c1fb686
children 02f0adc745c6
comparison
equal deleted inserted replaced
4073:7c5654c54fed 4074:26b7ed2817da
1 #!/usr/bin/env python3
2
3 # SàT communication bridge
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
5
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Affero General Public License for more details.
15
16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 import asyncio
20 from logging import getLogger
21 from functools import partial
22 from pathlib import Path
23 from twisted.spread import pb
24 from twisted.internet import reactor, defer
25 from twisted.internet.error import ConnectionRefusedError, ConnectError
26 from libervia.backend.core import exceptions
27 from libervia.backend.tools import config
28 from libervia.frontends.bridge.bridge_frontend import BridgeException
29
30 log = getLogger(__name__)
31
32
33 class SignalsHandler(pb.Referenceable):
34 def __getattr__(self, name):
35 if name.startswith("remote_"):
36 log.debug("calling an unregistered signal: {name}".format(name=name[7:]))
37 return lambda *args, **kwargs: None
38
39 else:
40 raise AttributeError(name)
41
42 def register_signal(self, name, handler, iface="core"):
43 log.debug("registering signal {name}".format(name=name))
44 method_name = "remote_" + name
45 try:
46 self.__getattribute__(method_name)
47 except AttributeError:
48 pass
49 else:
50 raise exceptions.InternalError(
51 "{name} signal handler has been registered twice".format(
52 name=method_name
53 )
54 )
55 setattr(self, method_name, handler)
56
57
58 class bridge(object):
59
60 def __init__(self):
61 self.signals_handler = SignalsHandler()
62
63 def __getattr__(self, name):
64 return partial(self.call, name)
65
66 def _generic_errback(self, err):
67 log.error(f"bridge error: {err}")
68
69 def _errback(self, failure_, ori_errback):
70 """Convert Failure to BridgeException"""
71 ori_errback(
72 BridgeException(
73 name=failure_.type.decode('utf-8'),
74 message=str(failure_.value)
75 )
76 )
77
78 def remote_callback(self, result, callback):
79 """call callback with argument or None
80
81 if result is not None not argument is used,
82 else result is used as argument
83 @param result: remote call result
84 @param callback(callable): method to call on result
85 """
86 if result is None:
87 callback()
88 else:
89 callback(result)
90
91 def call(self, name, *args, **kwargs):
92 """call a remote method
93
94 @param name(str): name of the bridge method
95 @param args(list): arguments
96 may contain callback and errback as last 2 items
97 @param kwargs(dict): keyword arguments
98 may contain callback and errback
99 """
100 callback = errback = None
101 if kwargs:
102 try:
103 callback = kwargs.pop("callback")
104 except KeyError:
105 pass
106 try:
107 errback = kwargs.pop("errback")
108 except KeyError:
109 pass
110 elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]):
111 errback = args.pop()
112 callback = args.pop()
113 d = self.root.callRemote(name, *args, **kwargs)
114 if callback is not None:
115 d.addCallback(self.remote_callback, callback)
116 if errback is not None:
117 d.addErrback(errback)
118
119 def _init_bridge_eb(self, failure_):
120 log.error("Can't init bridge: {msg}".format(msg=failure_))
121 return failure_
122
123 def _set_root(self, root):
124 """set remote root object
125
126 bridge will then be initialised
127 """
128 self.root = root
129 d = root.callRemote("initBridge", self.signals_handler)
130 d.addErrback(self._init_bridge_eb)
131 return d
132
133 def get_root_object_eb(self, failure_):
134 """Call errback with appropriate bridge error"""
135 if failure_.check(ConnectionRefusedError, ConnectError):
136 raise exceptions.BridgeExceptionNoService
137 else:
138 raise failure_
139
140 def bridge_connect(self, callback, errback):
141 factory = pb.PBClientFactory()
142 conf = config.parse_main_conf()
143 get_conf = partial(config.get_conf, conf, "bridge_pb", "")
144 conn_type = get_conf("connection_type", "unix_socket")
145 if conn_type == "unix_socket":
146 local_dir = Path(config.config_get(conf, "", "local_dir")).resolve()
147 socket_path = local_dir / "bridge_pb"
148 reactor.connectUNIX(str(socket_path), factory)
149 elif conn_type == "socket":
150 host = get_conf("host", "localhost")
151 port = int(get_conf("port", 8789))
152 reactor.connectTCP(host, port, factory)
153 else:
154 raise ValueError(f"Unknown pb connection type: {conn_type!r}")
155 d = factory.getRootObject()
156 d.addCallback(self._set_root)
157 if callback is not None:
158 d.addCallback(lambda __: callback())
159 d.addErrback(self.get_root_object_eb)
160 if errback is not None:
161 d.addErrback(lambda failure_: errback(failure_.value))
162 return d
163
164 def register_signal(self, functionName, handler, iface="core"):
165 self.signals_handler.register_signal(functionName, handler, iface)
166
167
168 def action_launch(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
169 d = self.root.callRemote("action_launch", callback_id, data, profile_key)
170 if callback is not None:
171 d.addCallback(callback)
172 if errback is None:
173 d.addErrback(self._generic_errback)
174 else:
175 d.addErrback(self._errback, ori_errback=errback)
176
177 def actions_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
178 d = self.root.callRemote("actions_get", profile_key)
179 if callback is not None:
180 d.addCallback(callback)
181 if errback is None:
182 d.addErrback(self._generic_errback)
183 else:
184 d.addErrback(self._errback, ori_errback=errback)
185
186 def config_get(self, section, name, callback=None, errback=None):
187 d = self.root.callRemote("config_get", section, name)
188 if callback is not None:
189 d.addCallback(callback)
190 if errback is None:
191 d.addErrback(self._generic_errback)
192 else:
193 d.addErrback(self._errback, ori_errback=errback)
194
195 def connect(self, profile_key="@DEFAULT@", password='', options={}, callback=None, errback=None):
196 d = self.root.callRemote("connect", profile_key, password, options)
197 if callback is not None:
198 d.addCallback(callback)
199 if errback is None:
200 d.addErrback(self._generic_errback)
201 else:
202 d.addErrback(self._errback, ori_errback=errback)
203
204 def contact_add(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
205 d = self.root.callRemote("contact_add", entity_jid, profile_key)
206 if callback is not None:
207 d.addCallback(lambda __: callback())
208 if errback is None:
209 d.addErrback(self._generic_errback)
210 else:
211 d.addErrback(self._errback, ori_errback=errback)
212
213 def contact_del(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
214 d = self.root.callRemote("contact_del", entity_jid, profile_key)
215 if callback is not None:
216 d.addCallback(lambda __: callback())
217 if errback is None:
218 d.addErrback(self._generic_errback)
219 else:
220 d.addErrback(self._errback, ori_errback=errback)
221
222 def contact_get(self, arg_0, profile_key="@DEFAULT@", callback=None, errback=None):
223 d = self.root.callRemote("contact_get", arg_0, profile_key)
224 if callback is not None:
225 d.addCallback(callback)
226 if errback is None:
227 d.addErrback(self._generic_errback)
228 else:
229 d.addErrback(self._errback, ori_errback=errback)
230
231 def contact_update(self, entity_jid, name, groups, profile_key="@DEFAULT@", callback=None, errback=None):
232 d = self.root.callRemote("contact_update", entity_jid, name, groups, profile_key)
233 if callback is not None:
234 d.addCallback(lambda __: callback())
235 if errback is None:
236 d.addErrback(self._generic_errback)
237 else:
238 d.addErrback(self._errback, ori_errback=errback)
239
240 def contacts_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
241 d = self.root.callRemote("contacts_get", profile_key)
242 if callback is not None:
243 d.addCallback(callback)
244 if errback is None:
245 d.addErrback(self._generic_errback)
246 else:
247 d.addErrback(self._errback, ori_errback=errback)
248
249 def contacts_get_from_group(self, group, profile_key="@DEFAULT@", callback=None, errback=None):
250 d = self.root.callRemote("contacts_get_from_group", group, profile_key)
251 if callback is not None:
252 d.addCallback(callback)
253 if errback is None:
254 d.addErrback(self._generic_errback)
255 else:
256 d.addErrback(self._errback, ori_errback=errback)
257
258 def devices_infos_get(self, bare_jid, profile_key, callback=None, errback=None):
259 d = self.root.callRemote("devices_infos_get", bare_jid, profile_key)
260 if callback is not None:
261 d.addCallback(callback)
262 if errback is None:
263 d.addErrback(self._generic_errback)
264 else:
265 d.addErrback(self._errback, ori_errback=errback)
266
267 def disco_find_by_features(self, namespaces, identities, bare_jid=False, service=True, roster=True, own_jid=True, local_device=False, profile_key="@DEFAULT@", callback=None, errback=None):
268 d = self.root.callRemote("disco_find_by_features", namespaces, identities, bare_jid, service, roster, own_jid, local_device, profile_key)
269 if callback is not None:
270 d.addCallback(callback)
271 if errback is None:
272 d.addErrback(self._generic_errback)
273 else:
274 d.addErrback(self._errback, ori_errback=errback)
275
276 def disco_infos(self, entity_jid, node=u'', use_cache=True, profile_key="@DEFAULT@", callback=None, errback=None):
277 d = self.root.callRemote("disco_infos", entity_jid, node, use_cache, profile_key)
278 if callback is not None:
279 d.addCallback(callback)
280 if errback is None:
281 d.addErrback(self._generic_errback)
282 else:
283 d.addErrback(self._errback, ori_errback=errback)
284
285 def disco_items(self, entity_jid, node=u'', use_cache=True, profile_key="@DEFAULT@", callback=None, errback=None):
286 d = self.root.callRemote("disco_items", entity_jid, node, use_cache, profile_key)
287 if callback is not None:
288 d.addCallback(callback)
289 if errback is None:
290 d.addErrback(self._generic_errback)
291 else:
292 d.addErrback(self._errback, ori_errback=errback)
293
294 def disconnect(self, profile_key="@DEFAULT@", callback=None, errback=None):
295 d = self.root.callRemote("disconnect", profile_key)
296 if callback is not None:
297 d.addCallback(lambda __: callback())
298 if errback is None:
299 d.addErrback(self._generic_errback)
300 else:
301 d.addErrback(self._errback, ori_errback=errback)
302
303 def encryption_namespace_get(self, arg_0, callback=None, errback=None):
304 d = self.root.callRemote("encryption_namespace_get", arg_0)
305 if callback is not None:
306 d.addCallback(callback)
307 if errback is None:
308 d.addErrback(self._generic_errback)
309 else:
310 d.addErrback(self._errback, ori_errback=errback)
311
312 def encryption_plugins_get(self, callback=None, errback=None):
313 d = self.root.callRemote("encryption_plugins_get")
314 if callback is not None:
315 d.addCallback(callback)
316 if errback is None:
317 d.addErrback(self._generic_errback)
318 else:
319 d.addErrback(self._errback, ori_errback=errback)
320
321 def encryption_trust_ui_get(self, to_jid, namespace, profile_key, callback=None, errback=None):
322 d = self.root.callRemote("encryption_trust_ui_get", to_jid, namespace, profile_key)
323 if callback is not None:
324 d.addCallback(callback)
325 if errback is None:
326 d.addErrback(self._generic_errback)
327 else:
328 d.addErrback(self._errback, ori_errback=errback)
329
330 def entities_data_get(self, jids, keys, profile, callback=None, errback=None):
331 d = self.root.callRemote("entities_data_get", jids, keys, profile)
332 if callback is not None:
333 d.addCallback(callback)
334 if errback is None:
335 d.addErrback(self._generic_errback)
336 else:
337 d.addErrback(self._errback, ori_errback=errback)
338
339 def entity_data_get(self, jid, keys, profile, callback=None, errback=None):
340 d = self.root.callRemote("entity_data_get", jid, keys, profile)
341 if callback is not None:
342 d.addCallback(callback)
343 if errback is None:
344 d.addErrback(self._generic_errback)
345 else:
346 d.addErrback(self._errback, ori_errback=errback)
347
348 def features_get(self, profile_key, callback=None, errback=None):
349 d = self.root.callRemote("features_get", profile_key)
350 if callback is not None:
351 d.addCallback(callback)
352 if errback is None:
353 d.addErrback(self._generic_errback)
354 else:
355 d.addErrback(self._errback, ori_errback=errback)
356
357 def history_get(self, from_jid, to_jid, limit, between=True, filters='', profile="@NONE@", callback=None, errback=None):
358 d = self.root.callRemote("history_get", from_jid, to_jid, limit, between, filters, profile)
359 if callback is not None:
360 d.addCallback(callback)
361 if errback is None:
362 d.addErrback(self._generic_errback)
363 else:
364 d.addErrback(self._errback, ori_errback=errback)
365
366 def image_check(self, arg_0, callback=None, errback=None):
367 d = self.root.callRemote("image_check", arg_0)
368 if callback is not None:
369 d.addCallback(callback)
370 if errback is None:
371 d.addErrback(self._generic_errback)
372 else:
373 d.addErrback(self._errback, ori_errback=errback)
374
375 def image_convert(self, source, dest, arg_2, extra, callback=None, errback=None):
376 d = self.root.callRemote("image_convert", source, dest, arg_2, extra)
377 if callback is not None:
378 d.addCallback(callback)
379 if errback is None:
380 d.addErrback(self._generic_errback)
381 else:
382 d.addErrback(self._errback, ori_errback=errback)
383
384 def image_generate_preview(self, image_path, profile_key, callback=None, errback=None):
385 d = self.root.callRemote("image_generate_preview", image_path, profile_key)
386 if callback is not None:
387 d.addCallback(callback)
388 if errback is None:
389 d.addErrback(self._generic_errback)
390 else:
391 d.addErrback(self._errback, ori_errback=errback)
392
393 def image_resize(self, image_path, width, height, callback=None, errback=None):
394 d = self.root.callRemote("image_resize", image_path, width, height)
395 if callback is not None:
396 d.addCallback(callback)
397 if errback is None:
398 d.addErrback(self._generic_errback)
399 else:
400 d.addErrback(self._errback, ori_errback=errback)
401
402 def is_connected(self, profile_key="@DEFAULT@", callback=None, errback=None):
403 d = self.root.callRemote("is_connected", profile_key)
404 if callback is not None:
405 d.addCallback(callback)
406 if errback is None:
407 d.addErrback(self._generic_errback)
408 else:
409 d.addErrback(self._errback, ori_errback=errback)
410
411 def main_resource_get(self, contact_jid, profile_key="@DEFAULT@", callback=None, errback=None):
412 d = self.root.callRemote("main_resource_get", contact_jid, profile_key)
413 if callback is not None:
414 d.addCallback(callback)
415 if errback is None:
416 d.addErrback(self._generic_errback)
417 else:
418 d.addErrback(self._errback, ori_errback=errback)
419
420 def menu_help_get(self, menu_id, language, callback=None, errback=None):
421 d = self.root.callRemote("menu_help_get", menu_id, language)
422 if callback is not None:
423 d.addCallback(callback)
424 if errback is None:
425 d.addErrback(self._generic_errback)
426 else:
427 d.addErrback(self._errback, ori_errback=errback)
428
429 def menu_launch(self, menu_type, path, data, security_limit, profile_key, callback=None, errback=None):
430 d = self.root.callRemote("menu_launch", menu_type, path, data, security_limit, profile_key)
431 if callback is not None:
432 d.addCallback(callback)
433 if errback is None:
434 d.addErrback(self._generic_errback)
435 else:
436 d.addErrback(self._errback, ori_errback=errback)
437
438 def menus_get(self, language, security_limit, callback=None, errback=None):
439 d = self.root.callRemote("menus_get", language, security_limit)
440 if callback is not None:
441 d.addCallback(callback)
442 if errback is None:
443 d.addErrback(self._generic_errback)
444 else:
445 d.addErrback(self._errback, ori_errback=errback)
446
447 def message_encryption_get(self, to_jid, profile_key, callback=None, errback=None):
448 d = self.root.callRemote("message_encryption_get", to_jid, profile_key)
449 if callback is not None:
450 d.addCallback(callback)
451 if errback is None:
452 d.addErrback(self._generic_errback)
453 else:
454 d.addErrback(self._errback, ori_errback=errback)
455
456 def message_encryption_start(self, to_jid, namespace='', replace=False, profile_key="@NONE@", callback=None, errback=None):
457 d = self.root.callRemote("message_encryption_start", to_jid, namespace, replace, profile_key)
458 if callback is not None:
459 d.addCallback(lambda __: callback())
460 if errback is None:
461 d.addErrback(self._generic_errback)
462 else:
463 d.addErrback(self._errback, ori_errback=errback)
464
465 def message_encryption_stop(self, to_jid, profile_key, callback=None, errback=None):
466 d = self.root.callRemote("message_encryption_stop", to_jid, profile_key)
467 if callback is not None:
468 d.addCallback(lambda __: callback())
469 if errback is None:
470 d.addErrback(self._generic_errback)
471 else:
472 d.addErrback(self._errback, ori_errback=errback)
473
474 def message_send(self, to_jid, message, subject={}, mess_type="auto", extra={}, profile_key="@NONE@", callback=None, errback=None):
475 d = self.root.callRemote("message_send", to_jid, message, subject, mess_type, extra, profile_key)
476 if callback is not None:
477 d.addCallback(lambda __: callback())
478 if errback is None:
479 d.addErrback(self._generic_errback)
480 else:
481 d.addErrback(self._errback, ori_errback=errback)
482
483 def namespaces_get(self, callback=None, errback=None):
484 d = self.root.callRemote("namespaces_get")
485 if callback is not None:
486 d.addCallback(callback)
487 if errback is None:
488 d.addErrback(self._generic_errback)
489 else:
490 d.addErrback(self._errback, ori_errback=errback)
491
492 def param_get_a(self, name, category, attribute="value", profile_key="@DEFAULT@", callback=None, errback=None):
493 d = self.root.callRemote("param_get_a", name, category, attribute, profile_key)
494 if callback is not None:
495 d.addCallback(callback)
496 if errback is None:
497 d.addErrback(self._generic_errback)
498 else:
499 d.addErrback(self._errback, ori_errback=errback)
500
501 def param_get_a_async(self, name, category, attribute="value", security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
502 d = self.root.callRemote("param_get_a_async", name, category, attribute, security_limit, profile_key)
503 if callback is not None:
504 d.addCallback(callback)
505 if errback is None:
506 d.addErrback(self._generic_errback)
507 else:
508 d.addErrback(self._errback, ori_errback=errback)
509
510 def param_set(self, name, value, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
511 d = self.root.callRemote("param_set", name, value, category, security_limit, profile_key)
512 if callback is not None:
513 d.addCallback(lambda __: callback())
514 if errback is None:
515 d.addErrback(self._generic_errback)
516 else:
517 d.addErrback(self._errback, ori_errback=errback)
518
519 def param_ui_get(self, security_limit=-1, app='', extra='', profile_key="@DEFAULT@", callback=None, errback=None):
520 d = self.root.callRemote("param_ui_get", security_limit, app, extra, profile_key)
521 if callback is not None:
522 d.addCallback(callback)
523 if errback is None:
524 d.addErrback(self._generic_errback)
525 else:
526 d.addErrback(self._errback, ori_errback=errback)
527
528 def params_categories_get(self, callback=None, errback=None):
529 d = self.root.callRemote("params_categories_get")
530 if callback is not None:
531 d.addCallback(callback)
532 if errback is None:
533 d.addErrback(self._generic_errback)
534 else:
535 d.addErrback(self._errback, ori_errback=errback)
536
537 def params_register_app(self, xml, security_limit=-1, app='', callback=None, errback=None):
538 d = self.root.callRemote("params_register_app", xml, security_limit, app)
539 if callback is not None:
540 d.addCallback(lambda __: callback())
541 if errback is None:
542 d.addErrback(self._generic_errback)
543 else:
544 d.addErrback(self._errback, ori_errback=errback)
545
546 def params_template_load(self, filename, callback=None, errback=None):
547 d = self.root.callRemote("params_template_load", filename)
548 if callback is not None:
549 d.addCallback(callback)
550 if errback is None:
551 d.addErrback(self._generic_errback)
552 else:
553 d.addErrback(self._errback, ori_errback=errback)
554
555 def params_template_save(self, filename, callback=None, errback=None):
556 d = self.root.callRemote("params_template_save", filename)
557 if callback is not None:
558 d.addCallback(callback)
559 if errback is None:
560 d.addErrback(self._generic_errback)
561 else:
562 d.addErrback(self._errback, ori_errback=errback)
563
564 def params_values_from_category_get_async(self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@", callback=None, errback=None):
565 d = self.root.callRemote("params_values_from_category_get_async", category, security_limit, app, extra, profile_key)
566 if callback is not None:
567 d.addCallback(callback)
568 if errback is None:
569 d.addErrback(self._generic_errback)
570 else:
571 d.addErrback(self._errback, ori_errback=errback)
572
573 def presence_set(self, to_jid='', show='', statuses={}, profile_key="@DEFAULT@", callback=None, errback=None):
574 d = self.root.callRemote("presence_set", to_jid, show, statuses, profile_key)
575 if callback is not None:
576 d.addCallback(lambda __: callback())
577 if errback is None:
578 d.addErrback(self._generic_errback)
579 else:
580 d.addErrback(self._errback, ori_errback=errback)
581
582 def presence_statuses_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
583 d = self.root.callRemote("presence_statuses_get", profile_key)
584 if callback is not None:
585 d.addCallback(callback)
586 if errback is None:
587 d.addErrback(self._generic_errback)
588 else:
589 d.addErrback(self._errback, ori_errback=errback)
590
591 def private_data_delete(self, namespace, key, arg_2, callback=None, errback=None):
592 d = self.root.callRemote("private_data_delete", namespace, key, arg_2)
593 if callback is not None:
594 d.addCallback(lambda __: callback())
595 if errback is None:
596 d.addErrback(self._generic_errback)
597 else:
598 d.addErrback(self._errback, ori_errback=errback)
599
600 def private_data_get(self, namespace, key, profile_key, callback=None, errback=None):
601 d = self.root.callRemote("private_data_get", namespace, key, profile_key)
602 if callback is not None:
603 d.addCallback(callback)
604 if errback is None:
605 d.addErrback(self._generic_errback)
606 else:
607 d.addErrback(self._errback, ori_errback=errback)
608
609 def private_data_set(self, namespace, key, data, profile_key, callback=None, errback=None):
610 d = self.root.callRemote("private_data_set", namespace, key, data, profile_key)
611 if callback is not None:
612 d.addCallback(lambda __: callback())
613 if errback is None:
614 d.addErrback(self._generic_errback)
615 else:
616 d.addErrback(self._errback, ori_errback=errback)
617
618 def profile_create(self, profile, password='', component='', callback=None, errback=None):
619 d = self.root.callRemote("profile_create", profile, password, component)
620 if callback is not None:
621 d.addCallback(lambda __: callback())
622 if errback is None:
623 d.addErrback(self._generic_errback)
624 else:
625 d.addErrback(self._errback, ori_errback=errback)
626
627 def profile_delete_async(self, profile, callback=None, errback=None):
628 d = self.root.callRemote("profile_delete_async", profile)
629 if callback is not None:
630 d.addCallback(lambda __: callback())
631 if errback is None:
632 d.addErrback(self._generic_errback)
633 else:
634 d.addErrback(self._errback, ori_errback=errback)
635
636 def profile_is_session_started(self, profile_key="@DEFAULT@", callback=None, errback=None):
637 d = self.root.callRemote("profile_is_session_started", profile_key)
638 if callback is not None:
639 d.addCallback(callback)
640 if errback is None:
641 d.addErrback(self._generic_errback)
642 else:
643 d.addErrback(self._errback, ori_errback=errback)
644
645 def profile_name_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
646 d = self.root.callRemote("profile_name_get", profile_key)
647 if callback is not None:
648 d.addCallback(callback)
649 if errback is None:
650 d.addErrback(self._generic_errback)
651 else:
652 d.addErrback(self._errback, ori_errback=errback)
653
654 def profile_set_default(self, profile, callback=None, errback=None):
655 d = self.root.callRemote("profile_set_default", profile)
656 if callback is not None:
657 d.addCallback(lambda __: callback())
658 if errback is None:
659 d.addErrback(self._generic_errback)
660 else:
661 d.addErrback(self._errback, ori_errback=errback)
662
663 def profile_start_session(self, password='', profile_key="@DEFAULT@", callback=None, errback=None):
664 d = self.root.callRemote("profile_start_session", password, profile_key)
665 if callback is not None:
666 d.addCallback(callback)
667 if errback is None:
668 d.addErrback(self._generic_errback)
669 else:
670 d.addErrback(self._errback, ori_errback=errback)
671
672 def profiles_list_get(self, clients=True, components=False, callback=None, errback=None):
673 d = self.root.callRemote("profiles_list_get", clients, components)
674 if callback is not None:
675 d.addCallback(callback)
676 if errback is None:
677 d.addErrback(self._generic_errback)
678 else:
679 d.addErrback(self._errback, ori_errback=errback)
680
681 def progress_get(self, id, profile, callback=None, errback=None):
682 d = self.root.callRemote("progress_get", id, profile)
683 if callback is not None:
684 d.addCallback(callback)
685 if errback is None:
686 d.addErrback(self._generic_errback)
687 else:
688 d.addErrback(self._errback, ori_errback=errback)
689
690 def progress_get_all(self, profile, callback=None, errback=None):
691 d = self.root.callRemote("progress_get_all", profile)
692 if callback is not None:
693 d.addCallback(callback)
694 if errback is None:
695 d.addErrback(self._generic_errback)
696 else:
697 d.addErrback(self._errback, ori_errback=errback)
698
699 def progress_get_all_metadata(self, profile, callback=None, errback=None):
700 d = self.root.callRemote("progress_get_all_metadata", profile)
701 if callback is not None:
702 d.addCallback(callback)
703 if errback is None:
704 d.addErrback(self._generic_errback)
705 else:
706 d.addErrback(self._errback, ori_errback=errback)
707
708 def ready_get(self, callback=None, errback=None):
709 d = self.root.callRemote("ready_get")
710 if callback is not None:
711 d.addCallback(lambda __: callback())
712 if errback is None:
713 d.addErrback(self._generic_errback)
714 else:
715 d.addErrback(self._errback, ori_errback=errback)
716
717 def roster_resync(self, profile_key="@DEFAULT@", callback=None, errback=None):
718 d = self.root.callRemote("roster_resync", profile_key)
719 if callback is not None:
720 d.addCallback(lambda __: callback())
721 if errback is None:
722 d.addErrback(self._generic_errback)
723 else:
724 d.addErrback(self._errback, ori_errback=errback)
725
726 def session_infos_get(self, profile_key, callback=None, errback=None):
727 d = self.root.callRemote("session_infos_get", profile_key)
728 if callback is not None:
729 d.addCallback(callback)
730 if errback is None:
731 d.addErrback(self._generic_errback)
732 else:
733 d.addErrback(self._errback, ori_errback=errback)
734
735 def sub_waiting_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
736 d = self.root.callRemote("sub_waiting_get", profile_key)
737 if callback is not None:
738 d.addCallback(callback)
739 if errback is None:
740 d.addErrback(self._generic_errback)
741 else:
742 d.addErrback(self._errback, ori_errback=errback)
743
744 def subscription(self, sub_type, entity, profile_key="@DEFAULT@", callback=None, errback=None):
745 d = self.root.callRemote("subscription", sub_type, entity, profile_key)
746 if callback is not None:
747 d.addCallback(lambda __: callback())
748 if errback is None:
749 d.addErrback(self._generic_errback)
750 else:
751 d.addErrback(self._errback, ori_errback=errback)
752
753 def version_get(self, callback=None, errback=None):
754 d = self.root.callRemote("version_get")
755 if callback is not None:
756 d.addCallback(callback)
757 if errback is None:
758 d.addErrback(self._generic_errback)
759 else:
760 d.addErrback(self._errback, ori_errback=errback)
761
762
763 class AIOSignalsHandler(SignalsHandler):
764
765 def register_signal(self, name, handler, iface="core"):
766 async_handler = lambda *args, **kwargs: defer.Deferred.fromFuture(
767 asyncio.ensure_future(handler(*args, **kwargs)))
768 return super().register_signal(name, async_handler, iface)
769
770
771 class AIOBridge(bridge):
772
773 def __init__(self):
774 self.signals_handler = AIOSignalsHandler()
775
776 def _errback(self, failure_):
777 """Convert Failure to BridgeException"""
778 raise BridgeException(
779 name=failure_.type.decode('utf-8'),
780 message=str(failure_.value)
781 )
782
783 def call(self, name, *args, **kwargs):
784 d = self.root.callRemote(name, *args, *kwargs)
785 d.addErrback(self._errback)
786 return d.asFuture(asyncio.get_event_loop())
787
788 async def bridge_connect(self):
789 d = super().bridge_connect(callback=None, errback=None)
790 return await d.asFuture(asyncio.get_event_loop())
791
792 def action_launch(self, callback_id, data, profile_key="@DEFAULT@"):
793 d = self.root.callRemote("action_launch", callback_id, data, profile_key)
794 d.addErrback(self._errback)
795 return d.asFuture(asyncio.get_event_loop())
796
797 def actions_get(self, profile_key="@DEFAULT@"):
798 d = self.root.callRemote("actions_get", profile_key)
799 d.addErrback(self._errback)
800 return d.asFuture(asyncio.get_event_loop())
801
802 def config_get(self, section, name):
803 d = self.root.callRemote("config_get", section, name)
804 d.addErrback(self._errback)
805 return d.asFuture(asyncio.get_event_loop())
806
807 def connect(self, profile_key="@DEFAULT@", password='', options={}):
808 d = self.root.callRemote("connect", profile_key, password, options)
809 d.addErrback(self._errback)
810 return d.asFuture(asyncio.get_event_loop())
811
812 def contact_add(self, entity_jid, profile_key="@DEFAULT@"):
813 d = self.root.callRemote("contact_add", entity_jid, profile_key)
814 d.addErrback(self._errback)
815 return d.asFuture(asyncio.get_event_loop())
816
817 def contact_del(self, entity_jid, profile_key="@DEFAULT@"):
818 d = self.root.callRemote("contact_del", entity_jid, profile_key)
819 d.addErrback(self._errback)
820 return d.asFuture(asyncio.get_event_loop())
821
822 def contact_get(self, arg_0, profile_key="@DEFAULT@"):
823 d = self.root.callRemote("contact_get", arg_0, profile_key)
824 d.addErrback(self._errback)
825 return d.asFuture(asyncio.get_event_loop())
826
827 def contact_update(self, entity_jid, name, groups, profile_key="@DEFAULT@"):
828 d = self.root.callRemote("contact_update", entity_jid, name, groups, profile_key)
829 d.addErrback(self._errback)
830 return d.asFuture(asyncio.get_event_loop())
831
832 def contacts_get(self, profile_key="@DEFAULT@"):
833 d = self.root.callRemote("contacts_get", profile_key)
834 d.addErrback(self._errback)
835 return d.asFuture(asyncio.get_event_loop())
836
837 def contacts_get_from_group(self, group, profile_key="@DEFAULT@"):
838 d = self.root.callRemote("contacts_get_from_group", group, profile_key)
839 d.addErrback(self._errback)
840 return d.asFuture(asyncio.get_event_loop())
841
842 def devices_infos_get(self, bare_jid, profile_key):
843 d = self.root.callRemote("devices_infos_get", bare_jid, profile_key)
844 d.addErrback(self._errback)
845 return d.asFuture(asyncio.get_event_loop())
846
847 def disco_find_by_features(self, namespaces, identities, bare_jid=False, service=True, roster=True, own_jid=True, local_device=False, profile_key="@DEFAULT@"):
848 d = self.root.callRemote("disco_find_by_features", namespaces, identities, bare_jid, service, roster, own_jid, local_device, profile_key)
849 d.addErrback(self._errback)
850 return d.asFuture(asyncio.get_event_loop())
851
852 def disco_infos(self, entity_jid, node=u'', use_cache=True, profile_key="@DEFAULT@"):
853 d = self.root.callRemote("disco_infos", entity_jid, node, use_cache, profile_key)
854 d.addErrback(self._errback)
855 return d.asFuture(asyncio.get_event_loop())
856
857 def disco_items(self, entity_jid, node=u'', use_cache=True, profile_key="@DEFAULT@"):
858 d = self.root.callRemote("disco_items", entity_jid, node, use_cache, profile_key)
859 d.addErrback(self._errback)
860 return d.asFuture(asyncio.get_event_loop())
861
862 def disconnect(self, profile_key="@DEFAULT@"):
863 d = self.root.callRemote("disconnect", profile_key)
864 d.addErrback(self._errback)
865 return d.asFuture(asyncio.get_event_loop())
866
867 def encryption_namespace_get(self, arg_0):
868 d = self.root.callRemote("encryption_namespace_get", arg_0)
869 d.addErrback(self._errback)
870 return d.asFuture(asyncio.get_event_loop())
871
872 def encryption_plugins_get(self):
873 d = self.root.callRemote("encryption_plugins_get")
874 d.addErrback(self._errback)
875 return d.asFuture(asyncio.get_event_loop())
876
877 def encryption_trust_ui_get(self, to_jid, namespace, profile_key):
878 d = self.root.callRemote("encryption_trust_ui_get", to_jid, namespace, profile_key)
879 d.addErrback(self._errback)
880 return d.asFuture(asyncio.get_event_loop())
881
882 def entities_data_get(self, jids, keys, profile):
883 d = self.root.callRemote("entities_data_get", jids, keys, profile)
884 d.addErrback(self._errback)
885 return d.asFuture(asyncio.get_event_loop())
886
887 def entity_data_get(self, jid, keys, profile):
888 d = self.root.callRemote("entity_data_get", jid, keys, profile)
889 d.addErrback(self._errback)
890 return d.asFuture(asyncio.get_event_loop())
891
892 def features_get(self, profile_key):
893 d = self.root.callRemote("features_get", profile_key)
894 d.addErrback(self._errback)
895 return d.asFuture(asyncio.get_event_loop())
896
897 def history_get(self, from_jid, to_jid, limit, between=True, filters='', profile="@NONE@"):
898 d = self.root.callRemote("history_get", from_jid, to_jid, limit, between, filters, profile)
899 d.addErrback(self._errback)
900 return d.asFuture(asyncio.get_event_loop())
901
902 def image_check(self, arg_0):
903 d = self.root.callRemote("image_check", arg_0)
904 d.addErrback(self._errback)
905 return d.asFuture(asyncio.get_event_loop())
906
907 def image_convert(self, source, dest, arg_2, extra):
908 d = self.root.callRemote("image_convert", source, dest, arg_2, extra)
909 d.addErrback(self._errback)
910 return d.asFuture(asyncio.get_event_loop())
911
912 def image_generate_preview(self, image_path, profile_key):
913 d = self.root.callRemote("image_generate_preview", image_path, profile_key)
914 d.addErrback(self._errback)
915 return d.asFuture(asyncio.get_event_loop())
916
917 def image_resize(self, image_path, width, height):
918 d = self.root.callRemote("image_resize", image_path, width, height)
919 d.addErrback(self._errback)
920 return d.asFuture(asyncio.get_event_loop())
921
922 def is_connected(self, profile_key="@DEFAULT@"):
923 d = self.root.callRemote("is_connected", profile_key)
924 d.addErrback(self._errback)
925 return d.asFuture(asyncio.get_event_loop())
926
927 def main_resource_get(self, contact_jid, profile_key="@DEFAULT@"):
928 d = self.root.callRemote("main_resource_get", contact_jid, profile_key)
929 d.addErrback(self._errback)
930 return d.asFuture(asyncio.get_event_loop())
931
932 def menu_help_get(self, menu_id, language):
933 d = self.root.callRemote("menu_help_get", menu_id, language)
934 d.addErrback(self._errback)
935 return d.asFuture(asyncio.get_event_loop())
936
937 def menu_launch(self, menu_type, path, data, security_limit, profile_key):
938 d = self.root.callRemote("menu_launch", menu_type, path, data, security_limit, profile_key)
939 d.addErrback(self._errback)
940 return d.asFuture(asyncio.get_event_loop())
941
942 def menus_get(self, language, security_limit):
943 d = self.root.callRemote("menus_get", language, security_limit)
944 d.addErrback(self._errback)
945 return d.asFuture(asyncio.get_event_loop())
946
947 def message_encryption_get(self, to_jid, profile_key):
948 d = self.root.callRemote("message_encryption_get", to_jid, profile_key)
949 d.addErrback(self._errback)
950 return d.asFuture(asyncio.get_event_loop())
951
952 def message_encryption_start(self, to_jid, namespace='', replace=False, profile_key="@NONE@"):
953 d = self.root.callRemote("message_encryption_start", to_jid, namespace, replace, profile_key)
954 d.addErrback(self._errback)
955 return d.asFuture(asyncio.get_event_loop())
956
957 def message_encryption_stop(self, to_jid, profile_key):
958 d = self.root.callRemote("message_encryption_stop", to_jid, profile_key)
959 d.addErrback(self._errback)
960 return d.asFuture(asyncio.get_event_loop())
961
962 def message_send(self, to_jid, message, subject={}, mess_type="auto", extra={}, profile_key="@NONE@"):
963 d = self.root.callRemote("message_send", to_jid, message, subject, mess_type, extra, profile_key)
964 d.addErrback(self._errback)
965 return d.asFuture(asyncio.get_event_loop())
966
967 def namespaces_get(self):
968 d = self.root.callRemote("namespaces_get")
969 d.addErrback(self._errback)
970 return d.asFuture(asyncio.get_event_loop())
971
972 def param_get_a(self, name, category, attribute="value", profile_key="@DEFAULT@"):
973 d = self.root.callRemote("param_get_a", name, category, attribute, profile_key)
974 d.addErrback(self._errback)
975 return d.asFuture(asyncio.get_event_loop())
976
977 def param_get_a_async(self, name, category, attribute="value", security_limit=-1, profile_key="@DEFAULT@"):
978 d = self.root.callRemote("param_get_a_async", name, category, attribute, security_limit, profile_key)
979 d.addErrback(self._errback)
980 return d.asFuture(asyncio.get_event_loop())
981
982 def param_set(self, name, value, category, security_limit=-1, profile_key="@DEFAULT@"):
983 d = self.root.callRemote("param_set", name, value, category, security_limit, profile_key)
984 d.addErrback(self._errback)
985 return d.asFuture(asyncio.get_event_loop())
986
987 def param_ui_get(self, security_limit=-1, app='', extra='', profile_key="@DEFAULT@"):
988 d = self.root.callRemote("param_ui_get", security_limit, app, extra, profile_key)
989 d.addErrback(self._errback)
990 return d.asFuture(asyncio.get_event_loop())
991
992 def params_categories_get(self):
993 d = self.root.callRemote("params_categories_get")
994 d.addErrback(self._errback)
995 return d.asFuture(asyncio.get_event_loop())
996
997 def params_register_app(self, xml, security_limit=-1, app=''):
998 d = self.root.callRemote("params_register_app", xml, security_limit, app)
999 d.addErrback(self._errback)
1000 return d.asFuture(asyncio.get_event_loop())
1001
1002 def params_template_load(self, filename):
1003 d = self.root.callRemote("params_template_load", filename)
1004 d.addErrback(self._errback)
1005 return d.asFuture(asyncio.get_event_loop())
1006
1007 def params_template_save(self, filename):
1008 d = self.root.callRemote("params_template_save", filename)
1009 d.addErrback(self._errback)
1010 return d.asFuture(asyncio.get_event_loop())
1011
1012 def params_values_from_category_get_async(self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"):
1013 d = self.root.callRemote("params_values_from_category_get_async", category, security_limit, app, extra, profile_key)
1014 d.addErrback(self._errback)
1015 return d.asFuture(asyncio.get_event_loop())
1016
1017 def presence_set(self, to_jid='', show='', statuses={}, profile_key="@DEFAULT@"):
1018 d = self.root.callRemote("presence_set", to_jid, show, statuses, profile_key)
1019 d.addErrback(self._errback)
1020 return d.asFuture(asyncio.get_event_loop())
1021
1022 def presence_statuses_get(self, profile_key="@DEFAULT@"):
1023 d = self.root.callRemote("presence_statuses_get", profile_key)
1024 d.addErrback(self._errback)
1025 return d.asFuture(asyncio.get_event_loop())
1026
1027 def private_data_delete(self, namespace, key, arg_2):
1028 d = self.root.callRemote("private_data_delete", namespace, key, arg_2)
1029 d.addErrback(self._errback)
1030 return d.asFuture(asyncio.get_event_loop())
1031
1032 def private_data_get(self, namespace, key, profile_key):
1033 d = self.root.callRemote("private_data_get", namespace, key, profile_key)
1034 d.addErrback(self._errback)
1035 return d.asFuture(asyncio.get_event_loop())
1036
1037 def private_data_set(self, namespace, key, data, profile_key):
1038 d = self.root.callRemote("private_data_set", namespace, key, data, profile_key)
1039 d.addErrback(self._errback)
1040 return d.asFuture(asyncio.get_event_loop())
1041
1042 def profile_create(self, profile, password='', component=''):
1043 d = self.root.callRemote("profile_create", profile, password, component)
1044 d.addErrback(self._errback)
1045 return d.asFuture(asyncio.get_event_loop())
1046
1047 def profile_delete_async(self, profile):
1048 d = self.root.callRemote("profile_delete_async", profile)
1049 d.addErrback(self._errback)
1050 return d.asFuture(asyncio.get_event_loop())
1051
1052 def profile_is_session_started(self, profile_key="@DEFAULT@"):
1053 d = self.root.callRemote("profile_is_session_started", profile_key)
1054 d.addErrback(self._errback)
1055 return d.asFuture(asyncio.get_event_loop())
1056
1057 def profile_name_get(self, profile_key="@DEFAULT@"):
1058 d = self.root.callRemote("profile_name_get", profile_key)
1059 d.addErrback(self._errback)
1060 return d.asFuture(asyncio.get_event_loop())
1061
1062 def profile_set_default(self, profile):
1063 d = self.root.callRemote("profile_set_default", profile)
1064 d.addErrback(self._errback)
1065 return d.asFuture(asyncio.get_event_loop())
1066
1067 def profile_start_session(self, password='', profile_key="@DEFAULT@"):
1068 d = self.root.callRemote("profile_start_session", password, profile_key)
1069 d.addErrback(self._errback)
1070 return d.asFuture(asyncio.get_event_loop())
1071
1072 def profiles_list_get(self, clients=True, components=False):
1073 d = self.root.callRemote("profiles_list_get", clients, components)
1074 d.addErrback(self._errback)
1075 return d.asFuture(asyncio.get_event_loop())
1076
1077 def progress_get(self, id, profile):
1078 d = self.root.callRemote("progress_get", id, profile)
1079 d.addErrback(self._errback)
1080 return d.asFuture(asyncio.get_event_loop())
1081
1082 def progress_get_all(self, profile):
1083 d = self.root.callRemote("progress_get_all", profile)
1084 d.addErrback(self._errback)
1085 return d.asFuture(asyncio.get_event_loop())
1086
1087 def progress_get_all_metadata(self, profile):
1088 d = self.root.callRemote("progress_get_all_metadata", profile)
1089 d.addErrback(self._errback)
1090 return d.asFuture(asyncio.get_event_loop())
1091
1092 def ready_get(self):
1093 d = self.root.callRemote("ready_get")
1094 d.addErrback(self._errback)
1095 return d.asFuture(asyncio.get_event_loop())
1096
1097 def roster_resync(self, profile_key="@DEFAULT@"):
1098 d = self.root.callRemote("roster_resync", profile_key)
1099 d.addErrback(self._errback)
1100 return d.asFuture(asyncio.get_event_loop())
1101
1102 def session_infos_get(self, profile_key):
1103 d = self.root.callRemote("session_infos_get", profile_key)
1104 d.addErrback(self._errback)
1105 return d.asFuture(asyncio.get_event_loop())
1106
1107 def sub_waiting_get(self, profile_key="@DEFAULT@"):
1108 d = self.root.callRemote("sub_waiting_get", profile_key)
1109 d.addErrback(self._errback)
1110 return d.asFuture(asyncio.get_event_loop())
1111
1112 def subscription(self, sub_type, entity, profile_key="@DEFAULT@"):
1113 d = self.root.callRemote("subscription", sub_type, entity, profile_key)
1114 d.addErrback(self._errback)
1115 return d.asFuture(asyncio.get_event_loop())
1116
1117 def version_get(self):
1118 d = self.root.callRemote("version_get")
1119 d.addErrback(self._errback)
1120 return d.asFuture(asyncio.get_event_loop())