Bump to 1.3.1
[slixmpp.git] / sleekxmpp / plugins / xep_0066 / oob.py
blob959c15a25a4db9baf4d4ad5cf119b7bbbd9af57f
1 """
2 SleekXMPP: The Sleek XMPP Library
3 Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
4 This file is part of SleekXMPP.
6 See the file LICENSE for copying permission.
7 """
9 import logging
11 from sleekxmpp.stanza import Message, Presence, Iq
12 from sleekxmpp.exceptions import XMPPError
13 from sleekxmpp.xmlstream import register_stanza_plugin
14 from sleekxmpp.xmlstream.handler import Callback
15 from sleekxmpp.xmlstream.matcher import StanzaPath
16 from sleekxmpp.plugins import BasePlugin
17 from sleekxmpp.plugins.xep_0066 import stanza
20 log = logging.getLogger(__name__)
23 class XEP_0066(BasePlugin):
25 """
26 XEP-0066: Out of Band Data
28 Out of Band Data is a basic method for transferring files between
29 XMPP agents. The URL of the resource in question is sent to the receiving
30 entity, which then downloads the resource before responding to the OOB
31 request. OOB is also used as a generic means to transmit URLs in other
32 stanzas to indicate where to find additional information.
34 Also see <http://www.xmpp.org/extensions/xep-0066.html>.
36 Events:
37 oob_transfer -- Raised when a request to download a resource
38 has been received.
40 Methods:
41 send_oob -- Send a request to another entity to download a file
42 or other addressable resource.
43 """
45 name = 'xep_0066'
46 description = 'XEP-0066: Out of Band Data'
47 dependencies = set(['xep_0030'])
48 stanza = stanza
50 def plugin_init(self):
51 """Start the XEP-0066 plugin."""
53 self.url_handlers = {'global': self._default_handler,
54 'jid': {}}
56 register_stanza_plugin(Iq, stanza.OOBTransfer)
57 register_stanza_plugin(Message, stanza.OOB)
58 register_stanza_plugin(Presence, stanza.OOB)
60 self.xmpp.register_handler(
61 Callback('OOB Transfer',
62 StanzaPath('iq@type=set/oob_transfer'),
63 self._handle_transfer))
65 def plugin_end(self):
66 self.xmpp.remove_handler('OOB Transfer')
67 self.xmpp['xep_0030'].del_feature(feature=stanza.OOBTransfer.namespace)
68 self.xmpp['xep_0030'].del_feature(feature=stanza.OOB.namespace)
70 def session_bind(self, jid):
71 self.xmpp['xep_0030'].add_feature(stanza.OOBTransfer.namespace)
72 self.xmpp['xep_0030'].add_feature(stanza.OOB.namespace)
74 def register_url_handler(self, jid=None, handler=None):
75 """
76 Register a handler to process download requests, either for all
77 JIDs or a single JID.
79 Arguments:
80 jid -- If None, then set the handler as a global default.
81 handler -- If None, then remove the existing handler for the
82 given JID, or reset the global handler if the JID
83 is None.
84 """
85 if jid is None:
86 if handler is not None:
87 self.url_handlers['global'] = handler
88 else:
89 self.url_handlers['global'] = self._default_handler
90 else:
91 if handler is not None:
92 self.url_handlers['jid'][jid] = handler
93 else:
94 del self.url_handlers['jid'][jid]
96 def send_oob(self, to, url, desc=None, ifrom=None, **iqargs):
97 """
98 Initiate a basic file transfer by sending the URL of
99 a file or other resource.
101 Arguments:
102 url -- The URL of the resource to transfer.
103 desc -- An optional human readable description of the item
104 that is to be transferred.
105 ifrom -- Specifiy the sender's JID.
106 block -- If true, block and wait for the stanzas' reply.
107 timeout -- The time in seconds to block while waiting for
108 a reply. If None, then wait indefinitely.
109 callback -- Optional callback to execute when a reply is
110 received instead of blocking and waiting for
111 the reply.
113 iq = self.xmpp.Iq()
114 iq['type'] = 'set'
115 iq['to'] = to
116 iq['from'] = ifrom
117 iq['oob_transfer']['url'] = url
118 iq['oob_transfer']['desc'] = desc
119 return iq.send(**iqargs)
121 def _run_url_handler(self, iq):
123 Execute the appropriate handler for a transfer request.
125 Arguments:
126 iq -- The Iq stanza containing the OOB transfer request.
128 if iq['to'] in self.url_handlers['jid']:
129 return self.url_handlers['jid'][iq['to']](iq)
130 else:
131 if self.url_handlers['global']:
132 self.url_handlers['global'](iq)
133 else:
134 raise XMPPError('service-unavailable')
136 def _default_handler(self, iq):
138 As a safe default, don't actually download files.
140 Register a new handler using self.register_url_handler to
141 screen requests and download files.
143 Arguments:
144 iq -- The Iq stanza containing the OOB transfer request.
146 raise XMPPError('service-unavailable')
148 def _handle_transfer(self, iq):
150 Handle receiving an out-of-band transfer request.
152 Arguments:
153 iq -- An Iq stanza containing an OOB transfer request.
155 log.debug('Received out-of-band data request for %s from %s:' % (
156 iq['oob_transfer']['url'], iq['from']))
157 self._run_url_handler(iq)
158 iq.reply().send()