comparison sat_bridge/DBus.py @ 7:c14a3a7018a5

added dynamic exportation of Dbus bridge method (usefull for plugins)
author Goffi <goffi@goffi.org>
date Sat, 24 Oct 2009 01:05:17 +0200
parents a06a151fc31f
children 14d7861ca59e
comparison
equal deleted inserted replaced
6:5799493fa548 7:c14a3a7018a5
25 import dbus.service 25 import dbus.service
26 import dbus.mainloop.glib 26 import dbus.mainloop.glib
27 import pdb 27 import pdb
28 from logging import debug, info, error 28 from logging import debug, info, error
29 29
30 CONST_INT_PREFIX = "org.goffi.SAT" #Interface prefix
31
30 class DbusObject(dbus.service.Object): 32 class DbusObject(dbus.service.Object):
31 33
32 def __init__(self, bus, path): 34 def __init__(self, bus, path):
33 dbus.service.Object.__init__(self, bus, path) 35 dbus.service.Object.__init__(self, bus, path)
34 debug("Init DbusObject...") 36 debug("Init DbusObject...")
37 def register(self, name, cb): 39 def register(self, name, cb):
38 self.cb[name]=cb 40 self.cb[name]=cb
39 41
40 ### signals ### 42 ### signals ###
41 43
42 @dbus.service.signal("org.goffi.SAT.communication", 44 @dbus.service.signal(CONST_INT_PREFIX+".communication",
43 signature='sa{ss}as') 45 signature='sa{ss}as')
44 def newContact(self, contact, attributes, groups): 46 def newContact(self, contact, attributes, groups):
45 debug("new contact signal (%s) sended", contact) 47 debug("new contact signal (%s) sended", contact)
46 48
47 @dbus.service.signal("org.goffi.SAT.communication", 49 @dbus.service.signal(CONST_INT_PREFIX+".communication",
48 signature='ssss') 50 signature='ssss')
49 def newMessage(self, from_jid, msg, type='chat', to=''): 51 def newMessage(self, from_jid, msg, type='chat', to=''):
50 debug("new message signal (from:%s msg:%s type:%s to:%s) sended", from_jid, msg, type, to) 52 debug("new message signal (from:%s msg:%s type:%s to:%s) sended", from_jid, msg, type, to)
51 53
52 @dbus.service.signal("org.goffi.SAT.communication", 54 @dbus.service.signal(CONST_INT_PREFIX+".communication",
53 signature='ssssi') 55 signature='ssssi')
54 def presenceUpdate(self, jid, type, show, status, priority): 56 def presenceUpdate(self, jid, type, show, status, priority):
55 debug("presence update signal (from:%s type: %s show:%s status:\"%s\" priority:%d) sended" , jid, type, show, status, priority) 57 debug("presence update signal (from:%s type: %s show:%s status:\"%s\" priority:%d) sended" , jid, type, show, status, priority)
56 58
57 @dbus.service.signal("org.goffi.SAT.communication", 59 @dbus.service.signal(CONST_INT_PREFIX+".communication",
58 signature='sss') 60 signature='sss')
59 def paramUpdate(self, name, value, namespace): 61 def paramUpdate(self, name, value, namespace):
60 debug("param update signal: %s=%s in namespace %s", name, value, namespace) 62 debug("param update signal: %s=%s in namespace %s", name, value, namespace)
61 63
62 @dbus.service.signal("org.goffi.SAT.communication", 64 @dbus.service.signal(CONST_INT_PREFIX+".communication",
63 signature='s') 65 signature='s')
64 def contactDeleted(self, jid): 66 def contactDeleted(self, jid):
65 debug("contact deleted signal: %s", jid) 67 debug("contact deleted signal: %s", jid)
66 68
67 @dbus.service.signal("org.goffi.SAT.request", 69 @dbus.service.signal(CONST_INT_PREFIX+".request",
68 signature='ssa{ss}') 70 signature='ssa{ss}')
69 def askConfirmation(self, type, id, data): 71 def askConfirmation(self, type, id, data):
70 debug("asking for confirmation: id = [%s] type = %s data = %s", id, type, data) 72 debug("asking for confirmation: id = [%s] type = %s data = %s", id, type, data)
71 73
72 74
73 75
74 ### methods ### 76 ### methods ###
75 77
76 @dbus.service.method("org.goffi.SAT.communication", 78 @dbus.service.method(CONST_INT_PREFIX+".communication",
77 in_signature='', out_signature='') 79 in_signature='', out_signature='')
78 def connect(self): 80 def connect(self):
79 info ("Connection asked") 81 info ("Connection asked")
80 return self.cb["connect"]() 82 return self.cb["connect"]()
81 83
82 @dbus.service.method("org.goffi.SAT.communication", 84 @dbus.service.method(CONST_INT_PREFIX+".communication",
83 in_signature='', out_signature='') 85 in_signature='', out_signature='')
84 def disconnect(self): 86 def disconnect(self):
85 info ("Disconnection asked") 87 info ("Disconnection asked")
86 return self.cb["disconnect"]() 88 return self.cb["disconnect"]()
87 89
88 @dbus.service.method("org.goffi.SAT.communication", 90 @dbus.service.method(CONST_INT_PREFIX+".communication",
89 in_signature='', out_signature='a(sa{ss}as)') 91 in_signature='', out_signature='a(sa{ss}as)')
90 def getContacts(self): 92 def getContacts(self):
91 debug("getContacts...") 93 debug("getContacts...")
92 return self.cb["getContacts"]() 94 return self.cb["getContacts"]()
93 95
94 @dbus.service.method("org.goffi.SAT.communication", 96 @dbus.service.method(CONST_INT_PREFIX+".communication",
95 in_signature='', out_signature='a(ssssi)') 97 in_signature='', out_signature='a(ssssi)')
96 def getPresenceStatus(self): 98 def getPresenceStatus(self):
97 debug("getPresenceStatus...") 99 debug("getPresenceStatus...")
98 return self.cb["getPresenceStatus"]() 100 return self.cb["getPresenceStatus"]()
99 101
100 @dbus.service.method("org.goffi.SAT.communication", 102 @dbus.service.method(CONST_INT_PREFIX+".communication",
101 in_signature='ss', out_signature='') 103 in_signature='ss', out_signature='')
102 def sendMessage(self, to, message): 104 def sendMessage(self, to, message):
103 debug("sendMessage...") 105 debug("sendMessage...")
104 self.cb["sendMessage"](to, message) 106 self.cb["sendMessage"](to, message)
105 107
106 @dbus.service.method("org.goffi.SAT.communication", 108 @dbus.service.method(CONST_INT_PREFIX+".communication",
107 in_signature='ss', out_signature='s')
108 def sendFile(self, to, path):
109 debug("sendFile...")
110 return self.cb["sendFile"](to, path)
111
112 @dbus.service.method("org.goffi.SAT.communication",
113 in_signature='ssssi', out_signature='') 109 in_signature='ssssi', out_signature='')
114 def setPresence(self, to="", type="", show="", status="", priority=0): 110 def setPresence(self, to="", type="", show="", status="", priority=0):
115 self.cb["setPresence"](to, type, show, status, priority) 111 self.cb["setPresence"](to, type, show, status, priority)
116 112
117 113 @dbus.service.method(CONST_INT_PREFIX+".communication",
118 @dbus.service.method("org.goffi.SAT.communication",
119 in_signature='sss', out_signature='') 114 in_signature='sss', out_signature='')
120 def setParam(self, name, value, namespace="default"): 115 def setParam(self, name, value, namespace="default"):
121 self.cb["setParam"](name, str(value), namespace) 116 self.cb["setParam"](name, str(value), namespace)
122 117
123 @dbus.service.method("org.goffi.SAT.communication", 118 @dbus.service.method(CONST_INT_PREFIX+".communication",
124 in_signature='ss', out_signature='(ss)') 119 in_signature='ss', out_signature='(ss)')
125 def getParam(self, name, namespace="default"): 120 def getParam(self, name, namespace="default"):
126 return self.cb["getParam"](name, namespace) 121 return self.cb["getParam"](name, namespace)
127 122
128 @dbus.service.method("org.goffi.SAT.communication", 123 @dbus.service.method(CONST_INT_PREFIX+".communication",
129 in_signature='s', out_signature='a(sss)') 124 in_signature='s', out_signature='a(sss)')
130 def getParams(self, namespace): 125 def getParams(self, namespace):
131 return self.cb["getParams"](namespace) 126 return self.cb["getParams"](namespace)
132 127
133 @dbus.service.method("org.goffi.SAT.communication", 128 @dbus.service.method(CONST_INT_PREFIX+".communication",
134 in_signature='', out_signature='as') 129 in_signature='', out_signature='as')
135 def getParamsCategories(self): 130 def getParamsCategories(self):
136 return self.cb["getParamsCategories"]() 131 return self.cb["getParamsCategories"]()
137 132
138 @dbus.service.method("org.goffi.SAT.communication", 133 @dbus.service.method(CONST_INT_PREFIX+".communication",
139 in_signature='ssi', out_signature='a{i(ss)}') 134 in_signature='ssi', out_signature='a{i(ss)}')
140 def getHistory(self, from_jid, to_jid, size): 135 def getHistory(self, from_jid, to_jid, size):
141 debug("History asked for %s", to_jid) 136 debug("History asked for %s", to_jid)
142 return self.cb["getHistory"](from_jid, to_jid, size) 137 return self.cb["getHistory"](from_jid, to_jid, size)
143 138
144 @dbus.service.method("org.goffi.SAT.communication", 139 @dbus.service.method(CONST_INT_PREFIX+".communication",
145 in_signature='s', out_signature='') 140 in_signature='s', out_signature='')
146 def addContact(self, jid): 141 def addContact(self, jid):
147 debug("Subscription asked for %s", jid) 142 debug("Subscription asked for %s", jid)
148 return self.cb["addContact"](jid) 143 return self.cb["addContact"](jid)
149 144
150 @dbus.service.method("org.goffi.SAT.communication", 145 @dbus.service.method(CONST_INT_PREFIX+".communication",
151 in_signature='s', out_signature='') 146 in_signature='s', out_signature='')
152 def delContact(self, jid): 147 def delContact(self, jid):
153 debug("Unsubscription asked for %s", jid) 148 debug("Unsubscription asked for %s", jid)
154 return self.cb["delContact"](jid) 149 return self.cb["delContact"](jid)
155 150
156 @dbus.service.method("org.goffi.SAT.communication", 151 @dbus.service.method(CONST_INT_PREFIX+".communication",
157 in_signature='', out_signature='b') 152 in_signature='', out_signature='b')
158 def isConnected(self): 153 def isConnected(self):
159 debug("Connection status requested") 154 debug("Connection status requested")
160 return self.cb["isConnected"]() 155 return self.cb["isConnected"]()
161 156
162 @dbus.service.method("org.goffi.SAT.request", 157 @dbus.service.method(CONST_INT_PREFIX+".request",
163 in_signature='sba{ss}', out_signature='') 158 in_signature='sba{ss}', out_signature='')
164 def confirmationAnswer(self, id, accepted, data): 159 def confirmationAnswer(self, id, accepted, data):
165 debug("Answer for confirmation [%s]: %s", id, "Accepted" if accepted else "Refused") 160 debug("Answer for confirmation [%s]: %s", id, "Accepted" if accepted else "Refused")
166 return self.cb["confirmationAnswer"](id, accepted, data) 161 return self.cb["confirmationAnswer"](id, accepted, data)
167 162
168 @dbus.service.method("org.goffi.SAT.request", 163 @dbus.service.method(CONST_INT_PREFIX+".request",
169 in_signature='s', out_signature='a{ss}') 164 in_signature='s', out_signature='a{ss}')
170 def getProgress(self, id): 165 def getProgress(self, id):
171 #debug("Progress asked for %s", id) 166 #debug("Progress asked for %s", id)
172 return self.cb["getProgress"](id) 167 return self.cb["getProgress"](id)
168
169 def _attribute_string(self, in_sign):
170 i=0
171 idx=0
172 attr_string=""
173 while i<len(in_sign):
174 if in_sign[i] not in ['b','y','n','i','x','q','u','t','d','s','a']:
175 raise Exception #FIXME: create an exception here (unmanaged attribute type)
176
177 attr_string += ("" if idx==0 else ",") + ("arg_%i" % idx)
178 idx+=1
179
180 if in_sign[i] == 'a':
181 while (True):
182 i+=1
183 if i>=len(in_sign):
184 raise Exception #FIXME: create an exception here (the '}' is not presend)
185 if in_sign[i] == '}':
186 break
187 i+=1
188 return attr_string
189
190
191
192 def addMethod(self, name, int_suffix, in_sign, out_sign):
193 """Dynamically add a method to Dbus Bridge"""
194 #FIXME: Better way ???
195 attributes = self._attribute_string(in_sign)
196
197 code = compile ('def '+name+' (self,'+attributes+'): return self.cb["'+name+'"]('+attributes+')', '<DBus bridge>','exec')
198 exec (code)
199 method = locals()[name]
200 setattr(DbusObject, name, dbus.service.method(
201 CONST_INT_PREFIX+int_suffix, in_signature=in_sign, out_signature=out_sign)(method))
173 202
174 class DBusBridge(Bridge): 203 class DBusBridge(Bridge):
175 def __init__(self): 204 def __init__(self):
176 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 205 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
177 Bridge.__init__(self) 206 Bridge.__init__(self)
178 info ("Init DBus...") 207 info ("Init DBus...")
179 self.session_bus = dbus.SessionBus() 208 self.session_bus = dbus.SessionBus()
180 self.dbus_name = dbus.service.BusName("org.goffi.SAT", self.session_bus) 209 self.dbus_name = dbus.service.BusName(CONST_INT_PREFIX, self.session_bus)
181 self.dbus_bridge = DbusObject(self.session_bus, '/org/goffi/SAT/bridge') 210 self.dbus_bridge = DbusObject(self.session_bus, '/org/goffi/SAT/bridge')
182 211
183 def newContact(self, contact, attributes, groups): 212 def newContact(self, contact, attributes, groups):
184 self.dbus_bridge.newContact(contact, attributes, groups) 213 self.dbus_bridge.newContact(contact, attributes, groups)
185 214
201 230
202 def askConfirmation(self, type, id, data): 231 def askConfirmation(self, type, id, data):
203 self.dbus_bridge.askConfirmation(type, id, data) 232 self.dbus_bridge.askConfirmation(type, id, data)
204 233
205 def register(self, name, callback): 234 def register(self, name, callback):
206 debug("enregistrement de %s",name) 235 debug("registering DBus bridge method [%s]",name)
207 self.dbus_bridge.register(name, callback) 236 self.dbus_bridge.register(name, callback)
208 237
238 def addMethod(self, name, int_suffix, in_sign, out_sign, method):
239 """Dynamically add a method to Dbus Bridge"""
240 print ("Adding method [%s] to DBus bridge" % name)
241 self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign)
242 self.register(name, method)
243