comparison libervia/backend/bridge/bridge_constructor/constructors/embedded/embedded_template.py @ 4071:4b842c1fb686

refactoring: renamed `sat` package to `libervia.backend`
author Goffi <goffi@goffi.org>
date Fri, 02 Jun 2023 11:49:51 +0200
parents sat/bridge/bridge_constructor/constructors/embedded/embedded_template.py@524856bd7b19
children 0d7bb4df2343
comparison
equal deleted inserted replaced
4070:d10748475025 4071:4b842c1fb686
1 #!/usr/bin/env python3
2
3
4 # Libervia: an XMPP client
5 # Copyright (C) 2009-2021 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 libervia.backend.core.log import getLogger
21
22 log = getLogger(__name__)
23 from libervia.backend.core import exceptions
24
25
26 class _Bridge(object):
27 def __init__(self):
28 log.debug("Init embedded bridge...")
29 self._methods_cbs = {}
30 self._signals_cbs = {"core": {}, "plugin": {}}
31
32 def bridge_connect(self, callback, errback):
33 callback()
34
35 def register_method(self, name, callback):
36 log.debug("registering embedded bridge method [{}]".format(name))
37 if name in self._methods_cbs:
38 raise exceptions.ConflictError("method {} is already regitered".format(name))
39 self._methods_cbs[name] = callback
40
41 def register_signal(self, functionName, handler, iface="core"):
42 iface_dict = self._signals_cbs[iface]
43 if functionName in iface_dict:
44 raise exceptions.ConflictError(
45 "signal {name} is already regitered for interface {iface}".format(
46 name=functionName, iface=iface
47 )
48 )
49 iface_dict[functionName] = handler
50
51 def call_method(self, name, out_sign, async_, args, kwargs):
52 callback = kwargs.pop("callback", None)
53 errback = kwargs.pop("errback", None)
54 if async_:
55 d = self._methods_cbs[name](*args, **kwargs)
56 if callback is not None:
57 d.addCallback(callback if out_sign else lambda __: callback())
58 if errback is None:
59 d.addErrback(lambda failure_: log.error(failure_))
60 else:
61 d.addErrback(errback)
62 return d
63 else:
64 try:
65 ret = self._methods_cbs[name](*args, **kwargs)
66 except Exception as e:
67 if errback is not None:
68 errback(e)
69 else:
70 raise e
71 else:
72 if callback is None:
73 return ret
74 else:
75 if out_sign:
76 callback(ret)
77 else:
78 callback()
79
80 def send_signal(self, name, args, kwargs):
81 try:
82 cb = self._signals_cbs["plugin"][name]
83 except KeyError:
84 log.debug("ignoring signal {}: no callback registered".format(name))
85 else:
86 cb(*args, **kwargs)
87
88 def add_method(self, name, int_suffix, in_sign, out_sign, method, async_=False, doc={}):
89 # FIXME: doc parameter is kept only temporary, the time to remove it from calls
90 log.debug("Adding method [{}] to embedded bridge".format(name))
91 self.register_method(name, method)
92 setattr(
93 self.__class__,
94 name,
95 lambda self_, *args, **kwargs: self.call_method(
96 name, out_sign, async_, args, kwargs
97 ),
98 )
99
100 def add_signal(self, name, int_suffix, signature, doc={}):
101 setattr(
102 self.__class__,
103 name,
104 lambda self_, *args, **kwargs: self.send_signal(name, args, kwargs),
105 )
106
107 ## signals ##
108
109
110 ##SIGNALS_PART##
111 ## methods ##
112
113 ##METHODS_PART##
114
115 # we want the same instance for both core and frontend
116 bridge = None
117
118
119 def bridge():
120 global bridge
121 if bridge is None:
122 bridge = _Bridge()
123 return bridge