Mercurial > libervia-backend
comparison src/bridge/bridge_constructor/dbus_core_template.py @ 595:1f160467f5de
Fix pep8 support in src/bridge.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 18 Jan 2013 17:55:35 +0100 |
parents | 952322b1d490 |
children | 84a6e83157c2 |
comparison
equal
deleted
inserted
replaced
594:e629371a28d3 | 595:1f160467f5de |
---|---|
16 GNU Affero General Public License for more details. | 16 GNU Affero General Public License for more details. |
17 | 17 |
18 You should have received a copy of the GNU Affero General Public License | 18 You should have received a copy of the GNU Affero General Public License |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 """ | 20 """ |
21 | |
22 | 21 |
23 from bridge import Bridge | 22 from bridge import Bridge |
24 import dbus | 23 import dbus |
25 import dbus.service | 24 import dbus.service |
26 import dbus.mainloop.glib | 25 import dbus.mainloop.glib |
27 import inspect | 26 import inspect |
28 from logging import debug, info, error | 27 from logging import debug, info, error |
29 from twisted.internet.defer import Deferred | 28 from twisted.internet.defer import Deferred |
30 | 29 |
31 const_INT_PREFIX = "org.goffi.SAT" #Interface prefix | 30 const_INT_PREFIX = "org.goffi.SAT" # Interface prefix |
32 const_ERROR_PREFIX = const_INT_PREFIX+".error" | 31 const_ERROR_PREFIX = const_INT_PREFIX + ".error" |
33 const_OBJ_PATH = '/org/goffi/SAT/bridge' | 32 const_OBJ_PATH = '/org/goffi/SAT/bridge' |
34 const_CORE_SUFFIX = ".core" | 33 const_CORE_SUFFIX = ".core" |
35 const_PLUGIN_SUFFIX = ".plugin" | 34 const_PLUGIN_SUFFIX = ".plugin" |
36 | 35 |
36 | |
37 class ParseError(Exception): | 37 class ParseError(Exception): |
38 pass | 38 pass |
39 | 39 |
40 | |
40 class MethodNotRegistered(dbus.DBusException): | 41 class MethodNotRegistered(dbus.DBusException): |
41 _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered" | 42 _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered" |
42 | 43 |
44 | |
43 class InternalError(dbus.DBusException): | 45 class InternalError(dbus.DBusException): |
44 _dbus_error_name = const_ERROR_PREFIX + ".InternalError" | 46 _dbus_error_name = const_ERROR_PREFIX + ".InternalError" |
45 | 47 |
48 | |
46 class AsyncNotDeferred(dbus.DBusException): | 49 class AsyncNotDeferred(dbus.DBusException): |
47 _dbus_error_name = const_ERROR_PREFIX + ".AsyncNotDeferred" | 50 _dbus_error_name = const_ERROR_PREFIX + ".AsyncNotDeferred" |
48 | 51 |
52 | |
49 class DeferredNotAsync(dbus.DBusException): | 53 class DeferredNotAsync(dbus.DBusException): |
50 _dbus_error_name = const_ERROR_PREFIX + ".DeferredNotAsync" | 54 _dbus_error_name = const_ERROR_PREFIX + ".DeferredNotAsync" |
51 | 55 |
56 | |
52 class GenericException(dbus.DBusException): | 57 class GenericException(dbus.DBusException): |
53 def __init__(self, twisted_error): | 58 def __init__(self, twisted_error): |
54 super(GenericException,self).__init__() | 59 super(GenericException, self).__init__() |
55 mess = twisted_error.getErrorMessage() | 60 mess = twisted_error.getErrorMessage() |
56 self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(twisted_error.__class__)) | 61 self._dbus_error_name = const_ERROR_PREFIX + "." + (mess or str(twisted_error.__class__)) |
62 | |
57 | 63 |
58 class DbusObject(dbus.service.Object): | 64 class DbusObject(dbus.service.Object): |
59 | 65 |
60 def __init__(self, bus, path): | 66 def __init__(self, bus, path): |
61 dbus.service.Object.__init__(self, bus, path) | 67 dbus.service.Object.__init__(self, bus, path) |
62 debug("Init DbusObject...") | 68 debug("Init DbusObject...") |
63 self.cb={} | 69 self.cb = {} |
64 | 70 |
65 def register(self, name, cb): | 71 def register(self, name, cb): |
66 self.cb[name]=cb | 72 self.cb[name] = cb |
67 | 73 |
68 def _callback(self, name, *args, **kwargs): | 74 def _callback(self, name, *args, **kwargs): |
69 """call the callback if it exists, raise an exception else | 75 """call the callback if it exists, raise an exception else |
70 if the callback return a deferred, use async methods""" | 76 if the callback return a deferred, use async methods""" |
71 if not name in self.cb: | 77 if not name in self.cb: |
84 result = self.cb[name](*args, **kwargs) | 90 result = self.cb[name](*args, **kwargs) |
85 if async: | 91 if async: |
86 if not isinstance(result, Deferred): | 92 if not isinstance(result, Deferred): |
87 error("Asynchronous method [%s] does not return a Deferred." % name) | 93 error("Asynchronous method [%s] does not return a Deferred." % name) |
88 raise AsyncNotDeferred | 94 raise AsyncNotDeferred |
89 result.addCallback(lambda result: callback() if result==None else callback(result)) | 95 result.addCallback(lambda result: callback() if result is None else callback(result)) |
90 result.addErrback(lambda err:errback(GenericException(err))) | 96 result.addErrback(lambda err: errback(GenericException(err))) |
91 else: | 97 else: |
92 if isinstance(result, Deferred): | 98 if isinstance(result, Deferred): |
93 error("Synchronous method [%s] return a Deferred." % name) | 99 error("Synchronous method [%s] return a Deferred." % name) |
94 raise DeferredNotAsync | 100 raise DeferredNotAsync |
95 return result | 101 return result |
96 | |
97 ### signals ### | 102 ### signals ### |
98 | 103 |
99 @dbus.service.signal(const_INT_PREFIX+const_PLUGIN_SUFFIX, | 104 @dbus.service.signal(const_INT_PREFIX + const_PLUGIN_SUFFIX, |
100 signature='') | 105 signature='') |
101 def dummySignal(self): | 106 def dummySignal(self): |
102 #FIXME: workaround for addSignal (doesn't work if one method doensn't | 107 #FIXME: workaround for addSignal (doesn't work if one method doensn't |
103 # already exist for plugins), probably missing some initialisation, need | 108 # already exist for plugins), probably missing some initialisation, need |
104 # further investigations | 109 # further investigations |
105 pass | 110 pass |
106 | 111 |
107 ##SIGNALS_PART## | 112 ##SIGNALS_PART## |
108 | |
109 ### methods ### | 113 ### methods ### |
110 | 114 |
111 ##METHODS_PART## | 115 ##METHODS_PART## |
112 | |
113 def __attributes(self, in_sign): | 116 def __attributes(self, in_sign): |
114 """Return arguments to user given a in_sign | 117 """Return arguments to user given a in_sign |
115 @param in_sign: in_sign in the short form (using s,a,i,b etc) | 118 @param in_sign: in_sign in the short form (using s,a,i,b etc) |
116 @return: list of arguments that correspond to a in_sign (e.g.: "sss" return "arg1, arg2, arg3")""" | 119 @return: list of arguments that correspond to a in_sign (e.g.: "sss" return "arg1, arg2, arg3")""" |
117 i=0 | 120 i = 0 |
118 idx=0 | 121 idx = 0 |
119 attr=[] | 122 attr = [] |
120 while i<len(in_sign): | 123 while i < len(in_sign): |
121 if in_sign[i] not in ['b','y','n','i','x','q','u','t','d','s','a']: | 124 if in_sign[i] not in ['b', 'y', 'n', 'i', 'x', 'q', 'u', 't', 'd', 's', 'a']: |
122 raise ParseError("Unmanaged attribute type [%c]" % in_sign[i]) | 125 raise ParseError("Unmanaged attribute type [%c]" % in_sign[i]) |
123 | 126 |
124 attr.append("arg_%i" % idx) | 127 attr.append("arg_%i" % idx) |
125 idx+=1 | 128 idx += 1 |
126 | 129 |
127 if in_sign[i] == 'a': | 130 if in_sign[i] == 'a': |
128 i+=1 | 131 i += 1 |
129 if in_sign[i]!='{' and in_sign[i]!='(': #FIXME: must manage tuples out of arrays | 132 if in_sign[i] != '{' and in_sign[i] != '(': # FIXME: must manage tuples out of arrays |
130 i+=1 | 133 i += 1 |
131 continue #we have a simple type for the array | 134 continue # we have a simple type for the array |
132 opening_car = in_sign[i] | 135 opening_car = in_sign[i] |
133 assert(opening_car in ['{','(']) | 136 assert(opening_car in ['{', '(']) |
134 closing_car = '}' if opening_car == '{' else ')' | 137 closing_car = '}' if opening_car == '{' else ')' |
135 opening_count = 1 | 138 opening_count = 1 |
136 while (True): #we have a dict or a list of tuples | 139 while (True): # we have a dict or a list of tuples |
137 i+=1 | 140 i += 1 |
138 if i>=len(in_sign): | 141 if i >= len(in_sign): |
139 raise ParseError("missing }") | 142 raise ParseError("missing }") |
140 if in_sign[i] == opening_car: | 143 if in_sign[i] == opening_car: |
141 opening_count+=1 | 144 opening_count += 1 |
142 if in_sign[i] == closing_car: | 145 if in_sign[i] == closing_car: |
143 opening_count-=1 | 146 opening_count -= 1 |
144 if opening_count == 0: | 147 if opening_count == 0: |
145 break | 148 break |
146 i+=1 | 149 i += 1 |
147 return attr | 150 return attr |
148 | 151 |
149 def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False): | 152 def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False): |
150 """Dynamically add a method to Dbus Bridge""" | 153 """Dynamically add a method to Dbus Bridge""" |
151 inspect_args = inspect.getargspec(method) | 154 inspect_args = inspect.getargspec(method) |
156 if inspect.ismethod(method): | 159 if inspect.ismethod(method): |
157 #if we have a method, we don't want the first argument (usually 'self') | 160 #if we have a method, we don't want the first argument (usually 'self') |
158 del(_arguments[0]) | 161 del(_arguments[0]) |
159 | 162 |
160 #first arguments are for the _callback method | 163 #first arguments are for the _callback method |
161 arguments_callback = ', '.join([repr(name)] + ((_arguments + ['callback=callback','errback=errback']) if async else _arguments)) | 164 arguments_callback = ', '.join([repr(name)] + ((_arguments + ['callback=callback', 'errback=errback']) if async else _arguments)) |
162 | 165 |
163 if async: | 166 if async: |
164 _arguments.extend(['callback','errback']) | 167 _arguments.extend(['callback', 'errback']) |
165 _defaults.extend([None, None]) | 168 _defaults.extend([None, None]) |
166 | 169 |
167 | |
168 #now we create a second list with default values | 170 #now we create a second list with default values |
169 for i in range(1, len(_defaults)+1): | 171 for i in range(1, len(_defaults) + 1): |
170 _arguments[-i] = "%s = %s" % (_arguments[-i], repr(_defaults[-i])) | 172 _arguments[-i] = "%s = %s" % (_arguments[-i], repr(_defaults[-i])) |
171 | 173 |
172 arguments_defaults = ', '.join(_arguments) | 174 arguments_defaults = ', '.join(_arguments) |
173 | 175 |
174 code = compile ('def %(name)s (self,%(arguments_defaults)s): return self._callback(%(arguments_callback)s)' % | 176 code = compile('def %(name)s (self,%(arguments_defaults)s): return self._callback(%(arguments_callback)s)' % |
175 {'name':name, 'arguments_defaults':arguments_defaults, 'arguments_callback':arguments_callback}, '<DBus bridge>','exec') | 177 {'name': name, 'arguments_defaults': arguments_defaults, 'arguments_callback': arguments_callback}, '<DBus bridge>', 'exec') |
176 exec (code) #FIXME: to the same thing in a cleaner way, without compile/exec | 178 exec (code) # FIXME: to the same thing in a cleaner way, without compile/exec |
177 method = locals()[name] | 179 method = locals()[name] |
178 async_callbacks = ('callback', 'errback') if async else None | 180 async_callbacks = ('callback', 'errback') if async else None |
179 setattr(DbusObject, name, dbus.service.method( | 181 setattr(DbusObject, name, dbus.service.method( |
180 const_INT_PREFIX+int_suffix, in_signature=in_sign, out_signature=out_sign, | 182 const_INT_PREFIX + int_suffix, in_signature=in_sign, out_signature=out_sign, |
181 async_callbacks=async_callbacks)(method)) | 183 async_callbacks=async_callbacks)(method)) |
182 function = getattr(self, name) | 184 function = getattr(self, name) |
183 func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface] | 185 func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface] |
184 func_table[function.__name__] = function #Needed for introspection | 186 func_table[function.__name__] = function # Needed for introspection |
185 | 187 |
186 def addSignal(self, name, int_suffix, signature, doc={}): | 188 def addSignal(self, name, int_suffix, signature, doc={}): |
187 """Dynamically add a signal to Dbus Bridge""" | 189 """Dynamically add a signal to Dbus Bridge""" |
188 attributes = ', '.join(self.__attributes(signature)) | 190 attributes = ', '.join(self.__attributes(signature)) |
189 #TODO: use doc parameter to name attributes | 191 #TODO: use doc parameter to name attributes |
190 | 192 |
191 #code = compile ('def '+name+' (self,'+attributes+'): debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the debug is too annoying with xmllog | 193 #code = compile ('def '+name+' (self,'+attributes+'): debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the debug is too annoying with xmllog |
192 code = compile ('def '+name+' (self,'+attributes+'): pass', '<DBus bridge>','exec') | 194 code = compile('def ' + name + ' (self,' + attributes + '): pass', '<DBus bridge>', 'exec') |
193 exec (code) | 195 exec (code) |
194 signal = locals()[name] | 196 signal = locals()[name] |
195 setattr(DbusObject, name, dbus.service.signal( | 197 setattr(DbusObject, name, dbus.service.signal( |
196 const_INT_PREFIX+int_suffix, signature=signature)(signal)) | 198 const_INT_PREFIX + int_suffix, signature=signature)(signal)) |
197 function = getattr(self, name) | 199 function = getattr(self, name) |
198 func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface] | 200 func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface] |
199 func_table[function.__name__] = function #Needed for introspection | 201 func_table[function.__name__] = function # Needed for introspection |
202 | |
200 | 203 |
201 class DBusBridge(Bridge): | 204 class DBusBridge(Bridge): |
202 def __init__(self): | 205 def __init__(self): |
203 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) | 206 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |
204 Bridge.__init__(self) | 207 Bridge.__init__(self) |
205 info ("Init DBus...") | 208 info("Init DBus...") |
206 self.session_bus = dbus.SessionBus() | 209 self.session_bus = dbus.SessionBus() |
207 self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus) | 210 self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus) |
208 self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH) | 211 self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH) |
209 | 212 |
210 ##DIRECT_CALLS## | 213 ##DIRECT_CALLS## |
211 | |
212 def register(self, name, callback): | 214 def register(self, name, callback): |
213 debug("registering DBus bridge method [%s]", name) | 215 debug("registering DBus bridge method [%s]", name) |
214 self.dbus_bridge.register(name, callback) | 216 self.dbus_bridge.register(name, callback) |
215 | 217 |
216 def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}): | 218 def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}): |
221 self.register(name, method) | 223 self.register(name, method) |
222 | 224 |
223 def addSignal(self, name, int_suffix, signature, doc={}): | 225 def addSignal(self, name, int_suffix, signature, doc={}): |
224 self.dbus_bridge.addSignal(name, int_suffix, signature, doc) | 226 self.dbus_bridge.addSignal(name, int_suffix, signature, doc) |
225 setattr(DBusBridge, name, getattr(self.dbus_bridge, name)) | 227 setattr(DBusBridge, name, getattr(self.dbus_bridge, name)) |
226 |