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