comparison plugins/plugin_xep_0065.py @ 64:d46f849664aa

SàT: multi-profile, plugins updated - core: 2 new convenient methods: getJidNStream and getClient - new param in plugin info: "handler" to know if there is a handler to plug on profiles clients - plugins with handler now use an other class which is returned to profile client with the new method "getHandler" and pluged when connecting
author Goffi <goffi@goffi.org>
date Sat, 30 Jan 2010 16:17:33 +1100
parents 9764e027ecc0
children 86f1f7f6d332
comparison
equal deleted inserted replaced
63:0db25931b60d 64:d46f849664aa
83 "name": "XEP 0065 Plugin", 83 "name": "XEP 0065 Plugin",
84 "import_name": "XEP_0065", 84 "import_name": "XEP_0065",
85 "type": "XEP", 85 "type": "XEP",
86 "protocols": ["XEP-0065"], 86 "protocols": ["XEP-0065"],
87 "main": "XEP_0065", 87 "main": "XEP_0065",
88 "handler": "yes",
88 "description": """Implementation of SOCKS5 Bytestreams""" 89 "description": """Implementation of SOCKS5 Bytestreams"""
89 } 90 }
90 91
91 STATE_INITIAL = 0 92 STATE_INITIAL = 0
92 STATE_AUTH = 1 93 STATE_AUTH = 1
310 return 311 return
311 312
312 debug("Saving file in %s.", self.data["dest_path"]) 313 debug("Saving file in %s.", self.data["dest_path"])
313 self.dest_file = open(self.data["dest_path"], 'w') 314 self.dest_file = open(self.data["dest_path"], 'w')
314 self.state = STATE_TARGET_READY 315 self.state = STATE_TARGET_READY
315 self.activateCB(self.target_jid, self.initiator_jid, self.sid, self.IQ_id) 316 self.activateCB(self.target_jid, self.initiator_jid, self.sid, self.IQ_id, self.xmlstream)
316 317
317 318
318 except struct.error, why: 319 except struct.error, why:
319 return None 320 return None
320 321
448 449
449 def clientConnectionLost(self, connector, reason): 450 def clientConnectionLost(self, connector, reason):
450 debug ("Socks 5 client connection lost (reason: %s)", reason) 451 debug ("Socks 5 client connection lost (reason: %s)", reason)
451 452
452 453
453 class XEP_0065(XMPPHandler): 454 class XEP_0065():
454 implements(iwokkel.IDisco)
455 455
456 params = """ 456 params = """
457 <params> 457 <params>
458 <general> 458 <general>
459 <category name="File Transfert"> 459 <category name="File Transfert">
478 478
479 port = int(self.host.memory.getParamA("Port", "File Transfert")) 479 port = int(self.host.memory.getParamA("Port", "File Transfert"))
480 info("Launching Socks5 Stream server on port %d", port) 480 info("Launching Socks5 Stream server on port %d", port)
481 reactor.listenTCP(port, self.server_factory) 481 reactor.listenTCP(port, self.server_factory)
482 482
483 def getHandler(self):
484 return XEP_0065_handler(self)
485
483 def getExternalIP(self): 486 def getExternalIP(self):
484 """Return IP visible from outside, by asking to a website""" 487 """Return IP visible from outside, by asking to a website"""
485 return getPage("http://www.goffi.org/sat_tools/get_ip.php") 488 return getPage("http://www.goffi.org/sat_tools/get_ip.php")
486
487 def connectionInitialized(self):
488 self.xmlstream.addObserver(BS_REQUEST, self.getFile)
489
490
491 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
492 return [disco.DiscoFeature(NS_BS)]
493
494 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
495 return []
496
497 489
498 def setData(self, data, id): 490 def setData(self, data, id):
499 self.data = data 491 self.data = data
500 self.transfert_id = id 492 self.transfert_id = id
501 493
505 self.server_factory.protocol.mode = "initiator" 497 self.server_factory.protocol.mode = "initiator"
506 self.server_factory.protocol.filepath = filepath 498 self.server_factory.protocol.filepath = filepath
507 self.server_factory.protocol.filesize = size 499 self.server_factory.protocol.filesize = size
508 self.server_factory.protocol.transfert_id = id 500 self.server_factory.protocol.transfert_id = id
509 501
510 def getFile(self, iq): 502 def getFile(self, iq, profile_key='@DEFAULT@'):
511 """Get file using byte stream""" 503 """Get file using byte stream"""
504 client = self.host.getClient(profile_key)
505 assert(client)
512 iq.handled = True 506 iq.handled = True
513 SI_elem = iq.firstChildElement() 507 SI_elem = iq.firstChildElement()
514 IQ_id = iq['id'] 508 IQ_id = iq['id']
515 for element in SI_elem.elements(): 509 for element in SI_elem.elements():
516 if element.name == "streamhost": 510 if element.name == "streamhost":
517 info ("Stream proposed: host=[%s] port=[%s]", element['host'], element['port']) 511 info ("Stream proposed: host=[%s] port=[%s]", element['host'], element['port'])
518 factory = self.client_factory 512 factory = self.client_factory
519 self.server_factory.protocol.mode = "target" 513 self.server_factory.protocol.mode = "target"
520 factory.protocol.host = self.host #needed for progress CB 514 factory.protocol.host = self.host #needed for progress CB
515 factory.protocol.xmlstream = client.xmlstream
521 factory.protocol.data = self.data 516 factory.protocol.data = self.data
522 factory.protocol.transfert_id = self.transfert_id 517 factory.protocol.transfert_id = self.transfert_id
523 factory.protocol.filesize = self.data["size"] 518 factory.protocol.filesize = self.data["size"]
524 factory.protocol.sid = SI_elem['sid'] 519 factory.protocol.sid = SI_elem['sid']
525 factory.protocol.initiator_jid = element['jid'] 520 factory.protocol.initiator_jid = element['jid']
526 factory.protocol.target_jid = self.host.me.full() 521 factory.protocol.target_jid = client.jid.full()
527 factory.protocol.IQ_id = IQ_id 522 factory.protocol.IQ_id = IQ_id
528 factory.protocol.activateCB = self.activateStream 523 factory.protocol.activateCB = self.activateStream
529 reactor.connectTCP(element['host'], int(element['port']), factory) 524 reactor.connectTCP(element['host'], int(element['port']), factory)
530 525
531 def activateStream(self, from_jid, to_jid, sid, IQ_id): 526 def activateStream(self, from_jid, to_jid, sid, IQ_id, xmlstream):
532 debug("activating stream") 527 debug("activating stream")
533 result = domish.Element(('', 'iq')) 528 result = domish.Element(('', 'iq'))
534 result['type'] = 'result' 529 result['type'] = 'result'
535 result['id'] = IQ_id 530 result['id'] = IQ_id
536 result['from'] = from_jid 531 result['from'] = from_jid
537 result['to'] = to_jid 532 result['to'] = to_jid
538 query = result.addElement('query', 'http://jabber.org/protocol/bytestreams') 533 query = result.addElement('query', 'http://jabber.org/protocol/bytestreams')
539 query['sid'] = sid 534 query['sid'] = sid
540 streamhost = query.addElement('streamhost-used') 535 streamhost = query.addElement('streamhost-used')
541 streamhost['jid'] = to_jid #FIXME: use real streamhost 536 streamhost['jid'] = to_jid #FIXME: use real streamhost
542 self.host.xmlstream.send(result) 537 xmlstream.send(result)
543 538
539 class XEP_0065_handler(XMPPHandler):
540 implements(iwokkel.IDisco)
541
542 def __init__(self, plugin_parent):
543 self.plugin_parent = plugin_parent
544 self.host = plugin_parent.host
545
546 def connectionInitialized(self):
547 self.xmlstream.addObserver(BS_REQUEST, self.plugin_parent.getFile)
548
549
550 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
551 return [disco.DiscoFeature(NS_BS)]
552
553 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
554 return []