class DiscoManager(object): implements(IFeaturesProvider) def __init__(self, client): self.client = client def get_features(self): """Return namespace which should the client include in its reply to a disco#info query.""" return ["jubatu:games"] def query_get_server(self): stream = self.client.get_stream() discoIq = Iq(None, self.client.jid, self.client.jid.domain, "get", stream.generate_id()) discoIq.new_query('http://jabber.org/protocol/disco#info') stream.set_response_handlers(discoIq, self.on_get_result, self.on_get_error) stream.send(discoIq) def query_get(self, jid, handler): stream = self.client.get_stream() iq = Iq(to_jid=jid, stanza_type="get") q = iq.new_query(VCARD_NS, "vCard") stream.set_response_handlers(iq, self.on_get_result, self.on_get_error) stream.send(iq) self.handler = handler def query_set(self, vcard): stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, None, None, "set", new_id) node = iq.new_query(VCARD_NS, "vCard") vcard.as_xml(node) stream.set_response_handlers(iq, self.on_set_result, self.on_set_error) stream.send(iq) def on_get_result(self, stanza): try: node = stanza.get_query() if node: vcard = VCard(node) else: vcard = None except (ValueError, ), e: vcard = None if vcard is None: #self.error(u"Invalid vCard received from "+stanza.get_from().as_unicode()) return else: """TODO""" self.handler.on_vcard(vcard)
class VersionHandler(object): """Provides handler for a version query. This class will answer version query and announce 'jabber:iq:version' namespace in the client's disco#info results.""" implements(IIqHandlersProvider, IFeaturesProvider) def __init__(self, client): """Just remember who created this.""" self.client = client def get_features(self): """Return namespace which should the client include in its reply to a disco#info query.""" return ["jabber:iq:version"] def get_iq_get_handlers(self): """Return list of tuples (element_name, namespace, handler) describing handlers of <iq type='get'/> stanzas""" return [ ("query", "jabber:iq:version", self.get_version), ] def get_iq_set_handlers(self): """Return empty list, as this class provides no <iq type='set'/> stanza handler.""" return [] def get_version(self, iq): """Handler for jabber:iq:version queries. jabber:iq:version queries are not supported directly by PyXMPP, so the XML node is accessed directly through the libxml2 API. This should be used very carefully!""" iq = iq.make_result_response() q = iq.new_query("jabber:iq:version") q.newTextChild(q.ns(), "name", "Echo component") q.newTextChild(q.ns(), "version", "1.0") return iq def unload(self): self.log.debug("pyLoad XMPP: unloading") self.disconnect() def deactivate(self): self.unload()
class SocksStreamHandler(object): implements(IIqHandlersProvider, IFeaturesProvider) def __init__(self, client): """Just remember who created this.""" self.client = client def get_features(self): """Return namespace which should the client include in its reply to a disco#info query.""" return ["http://jabber.org/protocol/bytestreams"] def get_iq_get_handlers(self): """Return list of tuples (element_name, namespace, handler) describing handlers of <iq type='get'/> stanzas""" return [ ("query", "http://jabber.org/protocol/bytestreams", self.get_version), ] def get_iq_set_handlers(self): """Return empty list, as this class provides no <iq type='set'/> stanza handler.""" return []
class XMPPInterface(IRCInterface, JabberClient): __name = "XMPPInterface" __type = "addon" __version = "0.11" __config = [ ("jid", "str", "Jabber ID", "*****@*****.**"), ("pw", "str", "Password", ""), ("tls", "bool", "Use TLS", False), ("owners", "str", "List of JIDs accepting commands from", "[email protected];[email protected]"), ("info_file", "bool", "Inform about every file finished", False), ("info_pack", "bool", "Inform about every package finished", True), ("captcha", "bool", "Send captcha requests", True) ] __description = """Connect to jabber and let owner perform different tasks""" __license = "GPLv3" __authors = [("RaNaN", "*****@*****.**")] implements(IMessageHandlersProvider) def __init__(self, core, manager): IRCInterface.__init__(self, core, manager) self.jid = JID(self.getConfig('jid')) password = self.getConfig('pw') # if bare JID is provided add a resource -- it is required if not self.jid.resource: self.jid = JID(self.jid.node, self.jid.domain, "pyLoad") if self.getConfig('tls'): tls_settings = streamtls.TLSSettings(require=True, verify_peer=False) auth = ("sasl:PLAIN", "sasl:DIGEST-MD5") else: tls_settings = None auth = ("sasl:DIGEST-MD5", "digest") # setup client with provided connection information # and identity data JabberClient.__init__(self, self.jid, password, disco_name="pyLoad XMPP Client", disco_type="bot", tls_settings=tls_settings, auth_methods=auth) self.interface_providers = [ VersionHandler(self), self, ] def activate(self): self.new_package = {} self.start() def packageFinished(self, pypack): try: if self.getConfig('info_pack'): self.announce(_("Package finished: %s") % pypack.name) except Exception: pass def downloadFinished(self, pyfile): try: if self.getConfig('info_file'): self.announce( _("Download finished: %(name)s @ %(plugin)s") % { "name": pyfile.name, "plugin": pyfile.pluginname }) except Exception: pass def run(self): # connect to IRC etc. self.connect() try: self.loop() except Exception, ex: self.logError(ex)
class EchoHandler(object): """Provides the actual 'echo' functionality. Handlers for presence and message stanzas are implemented here. """ implements(IMessageHandlersProvider, IPresenceHandlersProvider) def __init__(self, client): """Just remember who created this.""" self.client = client def get_message_handlers(self): """Return list of (message_type, message_handler) tuples. The handlers returned will be called when matching message is received in a client session.""" return [ ("normal", self.message), ] def get_presence_handlers(self): """Return list of (presence_type, presence_handler) tuples. The handlers returned will be called when matching presence stanza is received in a client session.""" return [ (None, self.presence), ("unavailable", self.presence), ("subscribe", self.presence_control), ("subscribed", self.presence_control), ("unsubscribe", self.presence_control), ("unsubscribed", self.presence_control), ] def message(self,stanza): """Message handler for the component. Echoes the message back if its type is not 'error' or 'headline', also sets own presence status to the message body. Please note that all message types but 'error' will be passed to the handler for 'normal' message unless some dedicated handler process them. :returns: `True` to indicate, that the stanza should not be processed any further.""" subject=stanza.get_subject() body=stanza.get_body() t=stanza.get_type() m = 0 print u'Message from %s received.' % (unicode(stanza.get_from(),)), if subject: print u'Subject: "%s".' % (subject,), if body: print u'Body: "%s".' % (body,), if t: print u'Type: "%s".' % (t,) else: print u'Type: "normal".' if stanza.get_type()=="headline": # 'headline' messages should never be replied to return True # record instance tag if body[:9] == u'?OTR:AAMD': (self.instance_tag, self.our_tag) = self.parse_aamc(body[len("?OTR:AAMD"):]) print "parsed instance tag: %s and our tag %s" % (self.instance_tag.encode("hex"), self.our_tag.encode("hex") ) self.send_insane_otr(stanza, 1024*1024*20, self.instance_tag, self.our_tag) return m def b64maxlen(self, chars): return 1 + (4 * chars / 3) def parse_aamc(self, msg): maxlen = self.b64maxlen(8) # 4 byte integer print "maxlen %u" % (maxlen) tmp = msg[0:maxlen] padding = "" if maxlen % 4 > 1: padding = "="*(4-(maxlen % 4)) tmp += padding print "decoding: "+tmp packed = base64.b64decode(tmp) # return unpack("I", packed[0:4]) return (packed[0:4], packed[4:8]) # their tag, our tag def initial_body(self, instance_tag, our_tag): ret = "?OTR:AAMD"; raw = b'' print "packing initial block with instance tag: %s and our tag: %s" % (instance_tag.encode("hex"), our_tag.encode("hex")) #dirty hack raw += our_tag # sender_nstance_id raw += instance_tag # receiver_id raw += "D" # dummy flags raw += pack("I", 0x1) # sender key id raw += pack("I", 0x2) # recipient key id raw += pack("!I", 10) # len next_y raw += "B"*10 # next_y # we don't know how mpi works but it seems ok ;) raw += "12345678" # reveal sig dummy # yeah overflow! raw += pack("I", 0xFFFFFFFF); # datalen ret += base64.b64encode(raw+"A"*(57-len(raw))) return ret def send_insane_otr(self, stanza, frag_size, instance_tag, our_tag): print "G-FUNK!" # this should result in about 0xFFFFFFFF times "A" base64 encoded len_msg = 5726623060 # fix frag size for base64 frag_size = (frag_size / 4) * 4 frag_msg = "QUFB"*(frag_size / 4) n = len_msg / frag_size # does not evenly divide? if len_msg % frag_size > 0: n += 1 k = 1 n += 1 # initialbody adds another frame initialbody = "?OTR,%hu,%hu,%s," % (k , n , self.initial_body(instance_tag, our_tag)) print "first fragment: "+initialbody m = Message( to_jid=stanza.get_from(), from_jid=stanza.get_to(), stanza_type=stanza.get_type(), subject="foo", body=initialbody) self.client.stream.send(m) k += 1 print "frag size: %s, len_msg: %u, num_frags: %u" % (frag_size, len_msg, n) cur_pos = 0 while(cur_pos < len_msg): body = "?OTR,%hu,%hu,%s," % (k , n , frag_msg) m = Message( to_jid=stanza.get_from(), from_jid=stanza.get_to(), stanza_type=stanza.get_type(), subject="foo", body=body) print "cur_pos %u of %u" % (cur_pos, len_msg) self.client.stream.send(m) k += 1 cur_pos = frag_size * (k-2) time.sleep(0.9) print "FINAL FRAG: cur_pos %u of %u" % (cur_pos, len_msg) def presence(self,stanza): """Handle 'available' (without 'type') and 'unavailable' <presence/>.""" msg=u"%s has become " % (stanza.get_from()) t=stanza.get_type() if t=="unavailable": msg+=u"unavailable" else: msg+=u"available" show=stanza.get_show() if show: msg+=u"(%s)" % (show,) status=stanza.get_status() if status: msg+=u": "+status print msg def presence_control(self,stanza): """Handle subscription control <presence/> stanzas -- acknowledge them.""" msg=unicode(stanza.get_from()) t=stanza.get_type() if t=="subscribe": msg+=u" has requested presence subscription." elif t=="subscribed": msg+=u" has accepted our presence subscription request." elif t=="unsubscribe": msg+=u" has canceled his subscription of our." elif t=="unsubscribed": msg+=u" has canceled our subscription of his presence." print msg return stanza.make_accept_response()
class IMConnection(wx.EvtHandler, JabberClient): implements(IMessageHandlersProvider, IPresenceHandlersProvider, IIqHandlersProvider) def __init__(self, parent): wx.EvtHandler.__init__(self) self.data_in_handler = DataInHandler(self) self.data_out_handler = DataOutHandler(self) logger = logging.getLogger("pyxmpp.Stream.in") logger.setLevel(logging.DEBUG) logger.addHandler(self.data_in_handler) logger = logging.getLogger("pyxmpp.Stream.out") logger.setLevel(logging.DEBUG) logger.addHandler(self.data_out_handler) self.keepalive = 30 tls = pyxmpp.TLSSettings(require=True, verify_peer=False) JabberClient.__init__(self, None, None, keepalive=self.keepalive, disco_name=u'Jubatu', disco_category=u'client', disco_type=u'gaming', tls_settings=tls, auth_methods=['sasl:PLAIN']) self.isDetached = False self.disco_mgr = discomgr.DiscoManager(self) self.file_transfer_mgr = filemgr.FileTransferManager( self, glob.config['Chat']['save_folder']) self.storage_mgr = storage.StorageManager(self) self.vard_mgr = vcardmgr.VcardManager(self) self.interface_providers = [ self, VersionHandler(self), self.disco_mgr, self.file_transfer_mgr, self.file_transfer_mgr.ibb, ] self.parent = parent self.evtHandler = self.parent.GetEventHandler() #---------------------------------------------------------------------------------------------------------------------------------# def get_iq_get_handlers(self): return [] def get_iq_set_handlers(self): return [] def get_message_handlers(self): return [ ("normal", self.message_received), ] def get_presence_handlers(self): return [ (None, self.presence_update), ("unavailable", self.presence_update), ("subscribe", self.presence_control), ("subscribed", self.presence_control), ("unsubscribe", self.presence_control), ("unsubscribed", self.presence_control), ] #---------------------------------------------------------------------------------------------------------------------------------# def setUserAccount(self, jidstr, password, resource='pyxmpp'): jid = JID(jidstr) self.jid = JID(jid.node, jid.domain, resource) self.password = password if not self.server: host = socket.gethostbyname(jid.domain) self.setServer(host) def setServer(self, server, port=0): self.server = server if port != 0: self.port = port else: self.port = 5222 def addRoster(self, jidstr, nickname, groupname): jid = JID(jidstr) if nickname == '': nickname = None if groupname == '': group = () else: group = (groupname, ) try: item = self.roster[jid] except Exception, e: item = None if not item: item = self.roster.add_item(jid, name=nickname, groups=group) iq = item.make_roster_push() self.stream.send(iq) self.sendSubscribe(jid, "") else: if item.groups: if groupname != '': item.goups.append(groupname) else: if groupname != '': item.goups = (groupname, ) iq = item.make_roster_push() self.stream.send(iq)
class EchoHandler(object): """Provides the actual 'echo' functionality. Handlers for presence and message stanzas are implemented here. """ implements(IMessageHandlersProvider, IPresenceHandlersProvider) def __init__(self, client): """Just remember who created this.""" self.client = client def get_message_handlers(self): """Return list of (message_type, message_handler) tuples. The handlers returned will be called when matching message is received in a client session.""" return [ ("normal", self.message), ] def get_presence_handlers(self): """Return list of (presence_type, presence_handler) tuples. The handlers returned will be called when matching presence stanza is received in a client session.""" return [ (None, self.presence), ("unavailable", self.presence), ("subscribe", self.presence_control), ("subscribed", self.presence_control), ("unsubscribe", self.presence_control), ("unsubscribed", self.presence_control), ] def message(self, stanza): """Message handler for the component. Echoes the message back if its type is not 'error' or 'headline', also sets own presence status to the message body. Please note that all message types but 'error' will be passed to the handler for 'normal' message unless some dedicated handler process them. :returns: `True` to indicate, that the stanza should not be processed any further.""" subject = stanza.get_subject() body = stanza.get_body() t = stanza.get_type() print u'Message from %s received.' % (unicode(stanza.get_from(), )), if subject: print u'Subject: "%s".' % (subject, ), if body: print u'Body: "%s".' % (body, ), if t: print u'Type: "%s".' % (t, ) else: print u'Type: "normal".' if stanza.get_type() == "headline": # 'headline' messages should never be replied to return True if subject: subject = u"Re: " + subject if body: print "Sending text to cleverbot" driver_cleverbot.get("http://www.cleverbot.com?" + \ urllib.urlencode({'say': body, 'b': 'Say'})) print "Waiting for cleverbot response" resp = wait_for_clever_response(driver_cleverbot) if resp is not None: print "Cleverbot says", resp.text body = resp.text m = Message(to_jid=stanza.get_from(), from_jid=stanza.get_to(), stanza_type=stanza.get_type(), subject=subject, body=body) if body: p = Presence(status=body) return [m, p] return m def presence(self, stanza): """Handle 'available' (without 'type') and 'unavailable' <presence/>.""" msg = u"%s has become " % (stanza.get_from()) t = stanza.get_type() if t == "unavailable": msg += u"unavailable" else: msg += u"available" show = stanza.get_show() if show: msg += u"(%s)" % (show, ) status = stanza.get_status() if status: msg += u": " + status print msg def presence_control(self, stanza): """Handle subscription control <presence/> stanzas -- acknowledge them.""" msg = unicode(stanza.get_from()) t = stanza.get_type() if t == "subscribe": msg += u" has requested presence subscription." elif t == "subscribed": msg += u" has accepted our presence subscription request." elif t == "unsubscribe": msg += u" has canceled his subscription of our." elif t == "unsubscribed": msg += u" has canceled our subscription of his presence." print msg return stanza.make_accept_response()
class IBB(object) : implements(IIqHandlersProvider) def __init__(self, client, manager): self.NS = IBB_NS self.client = client self.session_mgr = manager self.init_sessions = {} self.active_sessions = {} #---------------------------------------------------------------------------------------------------------------------------------# def send_open_request(self, session) : ''' <iq type='set' from='[email protected]/orchard' to='[email protected]/balcony' id='inband_1'> <open sid='mySID' block-size='4096' xmlns='http://jabber.org/protocol/ibb'/> </iq> ''' stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, session.jid, session.to_jid, "set", new_id) node = iq.add_new_content(IBB_NS, 'open') node.setProp('sid', session.sid) node.setProp('block-size', str(session.block_size)) stream.set_response_handlers(iq, self.received_open_success, self.received_open_error) stream.send(iq) self.init_sessions[new_id] = session def received_open_success(self, stanza) : ''' <iq type='result' from='[email protected]/balcony' to='[email protected]/orchard' id='inband_1'/> ''' from_jid = stanza.get_from() id = stanza.get_id() if id not in self.init_sessions : return session = self.init_sessions.pop(id) session.open_success(self) def received_open_error(self, stanza) : ''' <iq type='error' from='[email protected]/balcony' to='[email protected]/orchard' id='inband_1'/> <error code='501' type='cancel'> <feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </iq> ''' from_jid = stanza.get_from() id = stanza.get_id() if id not in self.init_sessions : return session = self.init_sessions[id] session = self.init_sessions.pop(id) session.open_error() def send_close_request(self, session) : ''' <iq type='set' from='[email protected]/orchard' to='[email protected]/balcony' id='inband_2'> <close xmlns='http://jabber.org/protocol/ibb' sid='mySID'/> </iq> ''' stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, session.jid, session.to_jid, "set", new_id) node = iq.add_new_content(IBB_NS, 'close') node.setProp('sid', session.sid) stream.set_response_handlers(iq, self.received_close_success, self.received_close_error) stream.send(iq) self.active_sessions[new_id] = session def received_close_success(self, stanza) : #print stanza.serialize() from_jid = stanza.get_from() id = stanza.get_id() session = self.active_sessions.pop(id) #session.close() def received_close_error(self, stanza) : print stanza.serialize() def send_data_request(self, session, data) : ''' <iq from='[email protected]/orchard' to='[email protected]/balcony' type='set' id='ibb1'> <data xmlns='http://jabber.org/protocol/ibb' sid='mySID' seq='0'> qANQR1DBwU4DX7jmYZnncmUQB/9KuKBddzQH+tZ1ZywKK0yHKnq57kWq+RFtQdCJ WpdWpR0uQsuJe7+vh3NWn59/gTc5MDlX8dS9p0ovStmNcyLhxVgmqS8ZKhsblVeu IpQ0JgavABqibJolc3BKrVtVV1igKiX/N7Pi8RtY1K18toaMDhdEfhBRzO/XB0+P AQhYlRjNacGcslkhXqNjK5Va4tuOAPy2n1Q8UUrHbUd0g+xJ9Bm0G0LZXyvCWyKH kuNEHFQiLuCY6Iv0myq6iX6tjuHehZlFSh80b5BVV9tNLwNR5Eqz1klxMhoghJOA </data> </iq> ''' stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, session.jid, session.to_jid, "set", new_id) node = iq.add_new_content(IBB_NS, 'data') node.setProp('sid', session.sid) node.setProp('seq', str(session.seq)) node.setContent(base64.b64encode(data)) stream.set_response_handlers(iq, self.received_data_success, self.received_data_error) stream.send(iq) self.active_sessions[new_id] = session def received_data_success(self, stanza) : #print stanza.serialize() sid = stanza.get_id() print 'send_data_successed :', sid from_jid = stanza.get_from() session = self.active_sessions.pop(sid) #session = self.session_mgr.get_session(from_jid, sid) session.send_next(self) def received_data_error(self, stanza) : #print stanza.serialize() print 'send_data_error' from_jid = stanza.get_from() sid = stanza.get_id() session = self.active_sessions.pop(sid) #session = self.session_mgr.get_session(from_jid, sid) session.send_error() #---------------------------------------------------------------------------------------------------------------------------------# def received_open_request(self, stanza) : from_jid = stanza.get_from() sid = from_utf8(stanza.get_query().prop('sid')) print "open sid:", sid session = self.session_mgr.get_session(from_jid, sid) if session : session.received_open() iq = stanza.make_result_response() else : iq = stanza.make_error_response('unexpected-request') self.client.get_stream().send(iq) def received_close_request(self, stanza) : from_jid = stanza.get_from() sid = from_utf8(stanza.get_query().prop('sid')) session = self.session_mgr.get_session(from_jid, sid) if session : session.received_close() iq = stanza.make_result_response() else : iq = stanza.make_error_response('unexpected-request') self.client.get_stream().send(iq) def received_data(self, stanza) : from_jid = stanza.get_from() iq = stanza.get_query() sid = from_utf8(iq.prop('sid')) data = base64.b64decode(iq.getContent()) seq = from_utf8(iq.prop('seq')) print "get data seq : ", seq session = self.session_mgr.get_session(from_jid, sid) if session : session.received_data(data, seq) iq = stanza.make_result_response() else : iq = stanza.make_error_response('unexpected-request') self.client.get_stream().send(iq) #---------------------------------------------------------------------------------------------------------------------------------# def get_iq_set_handlers(self): return [ ("open", IBB_NS, self.received_open_request), ("close", IBB_NS, self.received_close_request), ("data", IBB_NS, self.received_data), ] def get_iq_get_handlers(self): return []
class FileTransferManager(object) : implements(IIqHandlersProvider) def __init__(self, client, save_folder): self.client = client self.save_folder = save_folder self.ibb = IBB(client, self) self.sessions = {} #---------------------------------------------------------------------------------------------------------------------------------# def new_send_session(self, to_jid, file_name) : file_info = os.path.split(file_name) session = FileSendSession(self, self.client.jid, to_jid, file_info[0], file_info[1]) return session def send_si_request(self, session) : ''' <iq type='set' id='offer1' to='[email protected]/resource'> <si xmlns='http://jabber.org/protocol/si' id='a0' mime-type='text/plain' profile='http://jabber.org/protocol/si/profile/file-transfer'> <file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='test.txt' size='1022' hash='552da749930852c69ae5d2141d3766b1' date='1969-07-21T02:56:15Z'> <desc>This is a test. If this were a real file...</desc> </file> <feature xmlns='http://jabber.org/protocol/feature-neg'> <x xmlns='jabber:x:data' type='form'> <field var='stream-method' type='list-single'> <option><value>>>http://jabber.org/protocol/bytestreams</value></option> <option><value>>>http://jabber.org/protocol/ibb</value></option> </field> </x> </feature> </si> </iq> ''' stream = self.client.get_stream() #new_id = stream.generate_id() iq = Iq(None, session.jid, session.to_jid, "set", session.sid) si_node = iq.add_new_content(SI_NS, 'si') si_node.setProp("id", session.sid) si_node.setProp("mime-type", 'application/octet-stream') si_node.setProp("profile", FILE_TRANSFER_NS) file_node = si_node.newChild(None,"file",None) file_node.setProp("xmlns", FILE_TRANSFER_NS) file_node.setProp("name", to_utf8(session.file_name)) file_node.setProp("size", to_utf8(session.file_size)) feature_node = si_node.newChild(None, "feature", None) feature_node.setProp("xmlns", FEATURE_NS) form = Form() form.add_field( name = 'stream-method', field_type = 'list-single', #options = [Option('http://jabber.org/protocol/bytestreams', None), Option('http://jabber.org/protocol/ibb', None)]) options = [Option('http://jabber.org/protocol/ibb', None)]) form.as_xml(feature_node) stream.set_response_handlers(iq, self.received_si_success, self.received_si_error) stream.send(iq) self.sessions[session.sid] = session def received_si_success(self, stanza) : id = stanza.get_id() session = self.sessions[id] session.transfer = self.ibb #session.transfer = self.socks5 session.open_request() def received_si_error(self, stanza) : id = stanza.get_id() del self.sessions[id] #---------------------------------------------------------------------------------------------------------------------------------# def received_si_request(self, stanza) : ''' should response : <iq type='result' to='[email protected]/resource' id='offer1'> <si xmlns='http://jabber.org/protocol/si'> <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'/> <feature xmlns='http://jabber.org/protocol/feature-neg'> <x xmlns='jabber:x:data' type='submit'> <field var='stream-method'> <value>http://jabber.org/protocol/bytestreams</value> </field> </x> </feature> </si> </iq> ''' from_jid = stanza.get_from() sinode = stanza.get_query() sid = from_utf8(sinode.prop('id')) node = sinode.children while node : if node.ns() : ns = get_node_ns_uri(node) if ns == FILE_TRANSFER_NS : filenode = node elif ns == FEATURE_NS : featurenode = node node = node.next filename = from_utf8(filenode.prop('name')) filesize = int(filenode.prop('size')) session = FileReceiveSession(self, sid, self.client.jid, from_jid, self.save_folder, filename, filesize, self.ibb) session.stanza = stanza.copy() self.sessions[str(session)] = session evt = FileTransferEvent(self, session, 'open') self.client.evtHandler.ProcessEvent(evt) def send_si_response(self, session, accepted) : stanza = session.stanza session.stanza = None if accepted : iq = stanza.make_result_response() si_node = iq.add_new_content(SI_NS, 'si') file_node = si_node.newChild(None,"file",None) file_node.setProp("xmlns", FILE_TRANSFER_NS) feature_node = si_node.newChild(None, "feature", None) feature_node.setProp("xmlns", FEATURE_NS) form = Form('submit') form.add_field(name = 'stream-method', options = [Option(session.transfer.NS, None)]) #options = [Option('http://jabber.org/protocol/ibb', None)]) form.as_xml(feature_node) else : iq = stanza.make_error_response('not-acceptable') self.client.get_stream().send(iq) #print iq.serialize() #---------------------------------------------------------------------------------------------------------------------------------# def get_iq_set_handlers(self): return [ ("si", "http://jabber.org/protocol/si", self.received_si_request) ] def get_iq_get_handlers(self): return [] #---------------------------------------------------------------------------------------------------------------------------------# def get_session(self, to_jid, sid) : if sid in self.sessions : return self.sessions[sid] key = '%s-%s' % (to_jid.bare().as_unicode(), sid) if key in self.sessions : return self.sessions[key] else : return None def remove_session(self, session) : key = str(session) if key in self.sessions : del self.sessions[key] else : print "error in remove session : ", key def new_sid(self) : return "send-%i" % (time.time(),)
class MsgHandler(object): """Handlers for presence and message stanzas are implemented here. """ implements(IMessageHandlersProvider, IPresenceHandlersProvider) def __init__(self, client): """Just remember who created this.""" self.client = client def get_message_handlers(self): """Return list of (message_type, message_handler) tuples. The handlers returned will be called when matching message is received in a client session.""" return [ ("normal", self.message), ] def get_presence_handlers(self): """Return list of (presence_type, presence_handler) tuples. The handlers returned will be called when matching presence stanza is received in a client session.""" return [ (None, self.presence), ("unavailable", self.presence), ("subscribe", self.presence_control), ("subscribed", self.presence_control), ("unsubscribe", self.presence_control), ("unsubscribed", self.presence_control), ] # def message(self,stanza): # """Message handler for the component. # Echoes the message back if its type is not 'error' or # 'headline', also sets own presence status to the message body. Please # note that all message types but 'error' will be passed to the handler # for 'normal' message unless some dedicated handler process them. # :returns: `True` to indicate, that the stanza should not be processed # any further.""" # subject=stanza.get_subject() # body=stanza.get_body() # t=stanza.get_type() # print u'Message from %s received.' % (unicode(stanza.get_from(),)), # if subject: # print u'Subject: "%s".' % (subject,), # if body: # print u'Body: "%s".' % (body,), # if t: # print u'Type: "%s".' % (t,) # else: # print u'Type: "normal".' # if stanza.get_type()=="headline": # # 'headline' messages should never be replied to # return True # if subject: # subject=u"Re: "+subject # m=Message( # to_jid=stanza.get_from(), # from_jid=stanza.get_to(), # stanza_type=stanza.get_type(), # subject=subject, # body=body) # if body: # p = Presence(status=body) # return [m, p] # return m def message(self, stanza): if stanza.get_type() == 'chat': im_tcp_tunneler.handle_message(stanza.get_from_jid().as_unicode(), stanza.get_to_jid().as_unicode(), stanza.get_body()) return True def presence(self, stanza): """Handle 'available' (without 'type') and 'unavailable' <presence/>.""" msg = u"%s has become " % (stanza.get_from()) t = stanza.get_type() if t == "unavailable": msg += u"unavailable" else: msg += u"available" show = stanza.get_show() if show: msg += u"(%s)" % (show, ) status = stanza.get_status() if status: msg += u": " + status print msg def presence_control(self, stanza): """Handle subscription control <presence/> stanzas -- acknowledge them.""" msg = unicode(stanza.get_from()) t = stanza.get_type() if t == "subscribe": msg += u" has requested presence subscription." elif t == "subscribed": msg += u" has accepted our presence subscription request." elif t == "unsubscribe": msg += u" has canceled his subscription of our." elif t == "unsubscribed": msg += u" has canceled our subscription of his presence." print msg return stanza.make_accept_response()