Mercurial > libervia-backend
comparison sat.tac @ 16:0a024d5e0cd0
New account creation (in-band registration)
- new method "sendAnswer" in bridge for asyncronous result communication
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 02 Nov 2009 00:45:03 +0100 |
parents | 218ec9984fa5 |
children | 74a39f40eb6d |
comparison
equal
deleted
inserted
replaced
15:218ec9984fa5 | 16:0a024d5e0cd0 |
---|---|
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU 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 | 21 |
22 client_name = u'SàT (Salut à toi)' | 22 client_name = u'SàT (Salut à toi)' |
23 client_version = '0.0.1' | 23 client_version = '0.0.1D' #Please add 'D' at the end for dev versions |
24 | 24 |
25 from twisted.application import internet, service | 25 from twisted.application import internet, service |
26 from twisted.internet import glib2reactor, protocol, task | 26 from twisted.internet import glib2reactor, protocol, task |
27 glib2reactor.install() | 27 glib2reactor.install() |
28 | 28 |
30 from twisted.words.xish import domish | 30 from twisted.words.xish import domish |
31 | 31 |
32 from twisted.internet import reactor | 32 from twisted.internet import reactor |
33 import pdb | 33 import pdb |
34 | 34 |
35 from wokkel import client, disco, xmppim, generic | 35 from wokkel import client, disco, xmppim, generic, compat |
36 | 36 |
37 from sat_bridge.DBus import DBusBridge | 37 from sat_bridge.DBus import DBusBridge |
38 import logging | 38 import logging |
39 from logging import debug, info, error | 39 from logging import debug, info, error |
40 | 40 |
53 ### logging configuration FIXME: put this elsewhere ### | 53 ### logging configuration FIXME: put this elsewhere ### |
54 logging.basicConfig(level=logging.DEBUG, | 54 logging.basicConfig(level=logging.DEBUG, |
55 format='%(message)s') | 55 format='%(message)s') |
56 ### | 56 ### |
57 | 57 |
58 | |
59 sat_id = 0 | |
60 | |
61 def sat_next_id(): | |
62 global sat_id | |
63 sat_id+=1 | |
64 return "sat_id_"+str(sat_id) | |
58 | 65 |
59 class SatXMPPClient(client.XMPPClient): | 66 class SatXMPPClient(client.XMPPClient): |
60 | 67 |
61 def __init__(self, jid, password, host=None, port=5222): | 68 def __init__(self, jid, password, host=None, port=5222): |
62 client.XMPPClient.__init__(self, jid, password, host, port) | 69 client.XMPPClient.__init__(self, jid, password, host, port) |
185 | 192 |
186 def iqFallback(self, iq): | 193 def iqFallback(self, iq): |
187 #pdb.set_trace() | 194 #pdb.set_trace() |
188 print "iqFallback: xml = [%s], handled=%s" % (iq.toXml(), "True" if iq.handled else "False") | 195 print "iqFallback: xml = [%s], handled=%s" % (iq.toXml(), "True" if iq.handled else "False") |
189 generic.FallbackHandler.iqFallback(self, iq) | 196 generic.FallbackHandler.iqFallback(self, iq) |
190 | 197 |
198 class RegisteringAuthenticator(xmlstream.ConnectAuthenticator): | |
199 | |
200 def __init__(self, host, jabber_host, user_login, user_pass, answer_id): | |
201 xmlstream.ConnectAuthenticator.__init__(self, jabber_host) | |
202 self.host = host | |
203 self.jabber_host = jabber_host | |
204 self.user_login = user_login | |
205 self.user_pass = user_pass | |
206 self.answer_id = answer_id | |
207 | |
208 def connectionMade(self): | |
209 print "connectionMade" | |
210 | |
211 self.xmlstream.namespace = "jabber:client" | |
212 self.xmlstream.sendHeader() | |
213 | |
214 iq = compat.IQ(self.xmlstream, 'set') | |
215 iq["to"] = self.jabber_host | |
216 query = iq.addElement(('jabber:iq:register', 'query')) | |
217 _user = query.addElement('username') | |
218 _user.addContent(self.user_login) | |
219 _pass = query.addElement('password') | |
220 _pass.addContent(self.user_pass) | |
221 reg = iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure) | |
222 | |
223 def registrationAnswer(self, answer): | |
224 debug ("registration answer: %s" % answer.toXml()) | |
225 answer_type = "success" | |
226 answer_data={"human":"Registration successfull"} | |
227 self.host.bridge.sendAnswer(answer_type, self.answer_id, answer_data) | |
228 self.xmlstream.sendFooter() | |
229 | |
230 def registrationFailure(self, error): | |
231 info ("Registration failure: %s" %str(error)) | |
232 answer_type = "error" | |
233 answer_data={"human":"Registration failed"} | |
234 if error.value.condition == 'conflict': | |
235 answer_data['reason'] = 'conflict' | |
236 else: | |
237 answer_data['reason'] = 'unknown' | |
238 self.host.bridge.sendAnswer(answer_type, self.answer_id, answer_data) | |
239 self.xmlstream.sendFooter() | |
240 | |
191 | 241 |
192 class SAT(service.Service): | 242 class SAT(service.Service): |
193 | 243 |
194 def __init__(self): | 244 def __init__(self): |
195 #self.reactor=reactor | 245 #self.reactor=reactor |
199 self._waiting_conf = {} #callback called when a confirmation is received | 249 self._waiting_conf = {} #callback called when a confirmation is received |
200 self._progress_cb_map = {} #callback called when a progress is requested (key = progress id) | 250 self._progress_cb_map = {} #callback called when a progress is requested (key = progress id) |
201 self.plugins = {} | 251 self.plugins = {} |
202 | 252 |
203 self.bridge=DBusBridge() | 253 self.bridge=DBusBridge() |
254 self.bridge.register("registerNewAccount", self.registerNewAccount) | |
204 self.bridge.register("connect", self.connect) | 255 self.bridge.register("connect", self.connect) |
205 self.bridge.register("disconnect", self.disconnect) | 256 self.bridge.register("disconnect", self.disconnect) |
206 self.bridge.register("getContacts", self.memory.getContacts) | 257 self.bridge.register("getContacts", self.memory.getContacts) |
207 self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus) | 258 self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus) |
208 self.bridge.register("sendMessage", self.sendMessage) | 259 self.bridge.register("sendMessage", self.sendMessage) |
217 self.bridge.register("isConnected", self.isConnected) | 268 self.bridge.register("isConnected", self.isConnected) |
218 self.bridge.register("confirmationAnswer", self.confirmationAnswer) | 269 self.bridge.register("confirmationAnswer", self.confirmationAnswer) |
219 self.bridge.register("getProgress", self.getProgress) | 270 self.bridge.register("getProgress", self.getProgress) |
220 | 271 |
221 self._import_plugins() | 272 self._import_plugins() |
222 #self.connect() | |
223 | 273 |
224 | 274 |
225 def _import_plugins(self): | 275 def _import_plugins(self): |
226 """Import all plugins found in plugins directory""" | 276 """Import all plugins found in plugins directory""" |
227 #TODO: manage dependencies | 277 #TODO: manage dependencies |
232 __import__(plug_path) | 282 __import__(plug_path) |
233 mod = sys.modules[plug_path] | 283 mod = sys.modules[plug_path] |
234 plug_info = mod.PLUGIN_INFO | 284 plug_info = mod.PLUGIN_INFO |
235 info ("importing plugin: %s", plug_info['name']) | 285 info ("importing plugin: %s", plug_info['name']) |
236 self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) | 286 self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) |
287 #TODO: test xmppclient presence and register handler parent | |
237 | 288 |
238 def connect(self): | 289 def connect(self): |
290 """Connect to jabber server""" | |
291 | |
239 if (self.isConnected()): | 292 if (self.isConnected()): |
240 info("already connected !") | 293 info("already connected !") |
241 return | 294 return |
242 print "connecting..." | 295 print "connecting..." |
243 self.me = jid.JID(self.memory.getParamV("JabberID", "Connection")) | 296 self.me = jid.JID(self.memory.getParamV("JabberID", "Connection")) |
262 | 315 |
263 debug ("setting plugins parents") | 316 debug ("setting plugins parents") |
264 for plugin in self.plugins.iteritems(): | 317 for plugin in self.plugins.iteritems(): |
265 if isinstance(plugin[1], XMPPHandler): | 318 if isinstance(plugin[1], XMPPHandler): |
266 plugin[1].setHandlerParent(self.xmppclient) | 319 plugin[1].setHandlerParent(self.xmppclient) |
267 | 320 |
268 self.xmppclient.startService() | 321 self.xmppclient.startService() |
269 | 322 |
270 def disconnect(self): | 323 def disconnect(self): |
324 """disconnect from jabber server""" | |
271 if (not self.isConnected()): | 325 if (not self.isConnected()): |
272 info("not connected !") | 326 info("not connected !") |
273 return | 327 return |
274 info("Disconnecting...") | 328 info("Disconnecting...") |
275 self.xmppclient.stopService() | 329 self.xmppclient.stopService() |
305 self.roster.requestRoster() | 359 self.roster.requestRoster() |
306 | 360 |
307 self.presence.available() | 361 self.presence.available() |
308 | 362 |
309 self.disco.requestInfo(jid.JID(self.memory.getParamV("Server", "Connection"))).addCallback(self.serverDisco) | 363 self.disco.requestInfo(jid.JID(self.memory.getParamV("Server", "Connection"))).addCallback(self.serverDisco) |
310 | 364 |
311 | 365 ## Misc methods ## |
366 | |
367 def registerNewAccount(self, login, password, server, port = 5222): | |
368 """Connect to a server and create a new account using in-band registration""" | |
369 | |
370 next_id = sat_next_id() #the id is used to send server's answer | |
371 serverRegistrer = xmlstream.XmlStreamFactory(RegisteringAuthenticator(self, server, login, password, next_id)) | |
372 connector = reactor.connectTCP(server, port, serverRegistrer) | |
373 serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect() | |
374 | |
375 return next_id | |
376 | |
377 ## Client management ## | |
378 | |
379 def setParam(self, name, value, namespace): | |
380 """set wanted paramater and notice observers""" | |
381 info ("setting param: %s=%s in namespace %s", name, value, namespace) | |
382 self.memory.setParam(name, value, namespace) | |
383 self.bridge.paramUpdate(name, value, namespace) | |
384 | |
385 def failed(self,xmlstream): | |
386 debug("failed: %s", xmlstream.getErrorMessage()) | |
387 debug("failed: %s", dir(xmlstream)) | |
388 | |
389 def isConnected(self): | |
390 try: | |
391 if self.xmppclient.isConnected(): | |
392 return True | |
393 except AttributeError: | |
394 #xmppclient not available | |
395 pass | |
396 return False | |
397 | |
398 ## jabber methods ## | |
399 | |
312 def sendMessage(self,to,msg,type='chat'): | 400 def sendMessage(self,to,msg,type='chat'): |
313 #FIXME: check validity of recipient | 401 #FIXME: check validity of recipient |
314 debug("Sending jabber message to %s...", to) | 402 debug("Sending jabber message to %s...", to) |
315 message = domish.Element(('jabber:client','message')) | 403 message = domish.Element(('jabber:client','message')) |
316 message["to"] = jid.JID(to).full() | 404 message["to"] = jid.JID(to).full() |
319 message.addElement("body", "jabber:client", msg) | 407 message.addElement("body", "jabber:client", msg) |
320 self.xmlstream.send(message) | 408 self.xmlstream.send(message) |
321 self.memory.addToHistory(self.me, self.me, jid.JID(to), message["type"], unicode(msg)) | 409 self.memory.addToHistory(self.me, self.me, jid.JID(to), message["type"], unicode(msg)) |
322 self.bridge.newMessage(message['from'], unicode(msg), to=message['to']) #We send back the message, so all clients are aware of it | 410 self.bridge.newMessage(message['from'], unicode(msg), to=message['to']) #We send back the message, so all clients are aware of it |
323 | 411 |
324 def setParam(self, name, value, namespace): | |
325 """set wanted paramater and notice observers""" | |
326 info ("setting param: %s=%s in namespace %s", name, value, namespace) | |
327 self.memory.setParam(name, value, namespace) | |
328 self.bridge.paramUpdate(name, value, namespace) | |
329 | |
330 def failed(self,xmlstream): | |
331 debug("failed: %s", xmlstream.getErrorMessage()) | |
332 debug("failed: %s", dir(xmlstream)) | |
333 | |
334 def isConnected(self): | |
335 try: | |
336 if self.xmppclient.isConnected(): | |
337 return True | |
338 except AttributeError: | |
339 #xmppclient not available | |
340 pass | |
341 return False | |
342 | |
343 ## jabber methods ## | |
344 | 412 |
345 def setPresence(self, to="", type="", show="", status="", priority=0): | 413 def setPresence(self, to="", type="", show="", status="", priority=0): |
346 """Send our presence information""" | 414 """Send our presence information""" |
347 if not type in ["", "unavailable", "subscribed", "subscribe", | 415 if not type in ["", "unavailable", "subscribed", "subscribe", |
348 "unsubscribe", "unsubscribed", "prob", "error"]: | 416 "unsubscribe", "unsubscribed", "prob", "error"]: |