comparison sat/bridge/bridge_constructor/constructors/pb/pb_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/pb/pb_frontend_template.py@0046283a285d
children 56f94936df1e
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.log import getLogger
21 log = getLogger(__name__)
22 from sat.core import exceptions
23 from twisted.spread import pb
24 from twisted.internet import reactor
25
26
27 class SignalsHandler(pb.Referenceable):
28
29 def __getattr__(self, name):
30 if name.startswith("remote_"):
31 log.debug(u"calling an unregistered signal: {name}".format(
32 name = name[7:]))
33 return lambda *args, **kwargs: None
34
35 else:
36 raise AttributeError(name)
37
38 def register_signal(self, name, handler, iface="core"):
39 log.debug("registering signal {name}".format(name=name))
40 method_name = "remote_" + name
41 try:
42 self.__getattribute__(self, method_name)
43 except AttributeError:
44 pass
45 else:
46 raise exceptions.InternalError(u"{name} signal handler has been registered twice".format(
47 name = method_name))
48 setattr(self, method_name, handler)
49
50
51 class Bridge(object):
52
53 def __init__(self):
54 self.signals_handler = SignalsHandler()
55
56 def __getattr__(self, name):
57 return lambda *args, **kwargs: self.call(name, args, kwargs)
58
59 def remoteCallback(self, result, callback):
60 """call callback with argument or None
61
62 if result is not None not argument is used,
63 else result is used as argument
64 @param result: remote call result
65 @param callback(callable): method to call on result
66 """
67 if result is None:
68 callback()
69 else:
70 callback(result)
71
72 def call(self, name, args, kwargs):
73 """call a remote method
74
75 @param name(str): name of the bridge method
76 @param args(list): arguments
77 may contain callback and errback as last 2 items
78 @param kwargs(dict): keyword arguments
79 may contain callback and errback
80 """
81 callback = errback = None
82 if kwargs:
83 try:
84 callback = kwargs.pop('callback')
85 except KeyError:
86 pass
87 try:
88 errback = kwargs.pop('errback')
89 except KeyError:
90 pass
91 elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]):
92 errback = args.pop()
93 callback = args.pop()
94 d = self.root.callRemote(name, *args, **kwargs)
95 if callback is not None:
96 d.addCallback(self.remoteCallback, callback)
97 if errback is not None:
98 d.addErrback(errback)
99
100 def _initBridgeEb(self, failure):
101 log.error(u"Can't init bridge: {msg}".format(msg=failure))
102
103 def _set_root(self, root):
104 """set remote root object
105
106 bridge will then be initialised
107 """
108 self.root = root
109 d = root.callRemote("initBridge", self.signals_handler)
110 d.addErrback(self._initBridgeEb)
111 return d
112
113 def _generic_errback(self, failure):
114 log.error(u"bridge failure: {}".format(failure))
115
116 def bridgeConnect(self, callback, errback):
117 factory = pb.PBClientFactory()
118 reactor.connectTCP("localhost", 8789, factory)
119 d = factory.getRootObject()
120 d.addCallback(self._set_root)
121 d.addCallback(lambda dummy: callback())
122 d.addErrback(errback)
123
124 def register_signal(self, functionName, handler, iface="core"):
125 self.signals_handler.register_signal(functionName, handler, iface)
126
127 ##METHODS_PART##