# Slixmpp: The Slick XMPP Library# Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout# This file is part of Slixmpp.# See the file LICENSE for copying permission.importloggingfromslixmpp.stanzaimportMessage,Presence,Iqfromslixmpp.exceptionsimportXMPPErrorfromslixmpp.xmlstreamimportregister_stanza_pluginfromslixmpp.xmlstream.handlerimportCallbackfromslixmpp.xmlstream.matcherimportStanzaPathfromslixmpp.pluginsimportBasePluginfromslixmpp.plugins.xep_0066importstanzalog=logging.getLogger(__name__)
[docs]classXEP_0066(BasePlugin):""" XEP-0066: Out of Band Data Out of Band Data is a basic method for transferring files between XMPP agents. The URL of the resource in question is sent to the receiving entity, which then downloads the resource before responding to the OOB request. OOB is also used as a generic means to transmit URLs in other stanzas to indicate where to find additional information. Also see <http://www.xmpp.org/extensions/xep-0066.html>. Events: oob_transfer -- Raised when a request to download a resource has been received. """name='xep_0066'description='XEP-0066: Out of Band Data'dependencies={'xep_0030'}stanza=stanzadefplugin_init(self):"""Start the XEP-0066 plugin."""self.url_handlers={'global':self._default_handler,'jid':{}}register_stanza_plugin(Iq,stanza.OOBTransfer)register_stanza_plugin(Message,stanza.OOB)register_stanza_plugin(Presence,stanza.OOB)self.xmpp.register_handler(Callback('OOB Transfer',StanzaPath('iq@type=set/oob_transfer'),self._handle_transfer))defplugin_end(self):self.xmpp.remove_handler('OOB Transfer')self.xmpp['xep_0030'].del_feature(feature=stanza.OOBTransfer.namespace)self.xmpp['xep_0030'].del_feature(feature=stanza.OOB.namespace)defsession_bind(self,jid):self.xmpp['xep_0030'].add_feature(stanza.OOBTransfer.namespace)self.xmpp['xep_0030'].add_feature(stanza.OOB.namespace)
[docs]defregister_url_handler(self,jid=None,handler=None):""" Register a handler to process download requests, either for all JIDs or a single JID. :param jid: If None, then set the handler as a global default. :param handler: If None, then remove the existing handler for the given JID, or reset the global handler if the JID is None. """ifjidisNone:ifhandlerisnotNone:self.url_handlers['global']=handlerelse:self.url_handlers['global']=self._default_handlerelse:ifhandlerisnotNone:self.url_handlers['jid'][jid]=handlerelse:delself.url_handlers['jid'][jid]
[docs]defsend_oob(self,to,url,desc=None,ifrom=None,**iqargs):""" Initiate a basic file transfer by sending the URL of a file or other resource. :param url: The URL of the resource to transfer. :param desc: An optional human readable description of the item that is to be transferred. """iq=self.xmpp.Iq()iq['type']='set'iq['to']=toiq['from']=ifromiq['oob_transfer']['url']=urliq['oob_transfer']['desc']=descreturniq.send(**iqargs)
def_run_url_handler(self,iq):""" Execute the appropriate handler for a transfer request. :param iq: The Iq stanza containing the OOB transfer request. """ifiq['to']inself.url_handlers['jid']:returnself.url_handlers['jid'][iq['to']](iq)else:ifself.url_handlers['global']:self.url_handlers['global'](iq)else:raiseXMPPError('service-unavailable')def_default_handler(self,iq):""" As a safe default, don't actually download files. Register a new handler using self.register_url_handler to screen requests and download files. :param iq: The Iq stanza containing the OOB transfer request. """raiseXMPPError('service-unavailable')def_handle_transfer(self,iq):""" Handle receiving an out-of-band transfer request. :param iq: An Iq stanza containing an OOB transfer request. """log.debug('Received out-of-band data request for %s from %s:'%(iq['oob_transfer']['url'],iq['from']))self._run_url_handler(iq)iq.reply().send()