mirror of
https://github.com/correl/SleekXMPP.git
synced 2024-11-23 19:19:53 +00:00
Updated last bit of core files to use new API format.
This commit is contained in:
parent
79ac60b6e8
commit
a720c3348b
2 changed files with 141 additions and 143 deletions
|
@ -1,9 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
SleekXMPP: The Sleek XMPP Library
|
sleekxmpp.clientxmpp
|
||||||
Copyright (C) 2010 Nathanael C. Fritz
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
This file is part of SleekXMPP.
|
|
||||||
|
|
||||||
See the file LICENSE for copying permission.
|
This module provides XMPP functionality that
|
||||||
|
is specific to client connections.
|
||||||
|
|
||||||
|
Part of SleekXMPP: The Sleek XMPP Library
|
||||||
|
|
||||||
|
:copyright: (c) 2011 Nathanael C. Fritz
|
||||||
|
:license: MIT, see LICENSE for more details
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
@ -41,37 +47,30 @@ log = logging.getLogger(__name__)
|
||||||
class ClientXMPP(BaseXMPP):
|
class ClientXMPP(BaseXMPP):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
SleekXMPP's client class. ( Use only for good, not for evil.)
|
SleekXMPP's client class. (Use only for good, not for evil.)
|
||||||
|
|
||||||
Typical Use:
|
Typical use pattern:
|
||||||
xmpp = ClientXMPP('user@server.tld/resource', 'password')
|
|
||||||
xmpp.process(block=False) // when block is True, it blocks the current
|
|
||||||
// thread. False by default.
|
|
||||||
|
|
||||||
Attributes:
|
.. code-block:: python
|
||||||
|
|
||||||
Methods:
|
xmpp = ClientXMPP('user@server.tld/resource', 'password')
|
||||||
connect -- Overrides XMLStream.connect.
|
# ... Register plugins and event handlers ...
|
||||||
del_roster_item -- Delete a roster item.
|
xmpp.connect()
|
||||||
get_roster -- Retrieve the roster from the server.
|
xmpp.process(block=False) # block=True will block the current
|
||||||
register_feature -- Register a stream feature.
|
# thread. By default, block=False
|
||||||
update_roster -- Update a roster item.
|
|
||||||
|
:param jid: The JID of the XMPP user account.
|
||||||
|
:param password: The password for the XMPP user account.
|
||||||
|
:param ssl: **Deprecated.**
|
||||||
|
:param plugin_config: A dictionary of plugin configurations.
|
||||||
|
:param plugin_whitelist: A list of approved plugins that
|
||||||
|
will be loaded when calling
|
||||||
|
:meth:`~sleekxmpp.basexmpp.BaseXMPP.register_plugins()`.
|
||||||
|
:param escape_quotes: **Deprecated.**
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, jid, password, ssl=False, plugin_config={},
|
def __init__(self, jid, password, ssl=False, plugin_config={},
|
||||||
plugin_whitelist=[], escape_quotes=True, sasl_mech=None):
|
plugin_whitelist=[], escape_quotes=True, sasl_mech=None):
|
||||||
"""
|
|
||||||
Create a new SleekXMPP client.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
jid -- The JID of the XMPP user account.
|
|
||||||
password -- The password for the XMPP user account.
|
|
||||||
ssl -- Deprecated.
|
|
||||||
plugin_config -- A dictionary of plugin configurations.
|
|
||||||
plugin_whitelist -- A list of approved plugins that will be loaded
|
|
||||||
when calling register_plugins.
|
|
||||||
escape_quotes -- Deprecated.
|
|
||||||
"""
|
|
||||||
BaseXMPP.__init__(self, jid, 'jabber:client')
|
BaseXMPP.__init__(self, jid, 'jabber:client')
|
||||||
|
|
||||||
self.set_jid(jid)
|
self.set_jid(jid)
|
||||||
|
@ -121,21 +120,19 @@ class ClientXMPP(BaseXMPP):
|
||||||
|
|
||||||
def connect(self, address=tuple(), reattempt=True,
|
def connect(self, address=tuple(), reattempt=True,
|
||||||
use_tls=True, use_ssl=False):
|
use_tls=True, use_ssl=False):
|
||||||
"""
|
"""Connect to the XMPP server.
|
||||||
Connect to the XMPP server.
|
|
||||||
|
|
||||||
When no address is given, a SRV lookup for the server will
|
When no address is given, a SRV lookup for the server will
|
||||||
be attempted. If that fails, the server user in the JID
|
be attempted. If that fails, the server user in the JID
|
||||||
will be used.
|
will be used.
|
||||||
|
|
||||||
Arguments:
|
:param address -- A tuple containing the server's host and port.
|
||||||
address -- A tuple containing the server's host and port.
|
:param reattempt: If ``True``, repeat attempting to connect if an
|
||||||
reattempt -- If True, reattempt the connection if an
|
error occurs. Defaults to ``True``.
|
||||||
error occurs. Defaults to True.
|
:param use_tls: Indicates if TLS should be used for the
|
||||||
use_tls -- Indicates if TLS should be used for the
|
connection. Defaults to ``True``.
|
||||||
connection. Defaults to True.
|
:param use_ssl: Indicates if the older SSL connection method
|
||||||
use_ssl -- Indicates if the older SSL connection method
|
should be used. Defaults to ``False``.
|
||||||
should be used. Defaults to False.
|
|
||||||
"""
|
"""
|
||||||
self.session_started_event.clear()
|
self.session_started_event.clear()
|
||||||
if not address:
|
if not address:
|
||||||
|
@ -146,13 +143,10 @@ class ClientXMPP(BaseXMPP):
|
||||||
reattempt=reattempt)
|
reattempt=reattempt)
|
||||||
|
|
||||||
def get_dns_records(self, domain, port=None):
|
def get_dns_records(self, domain, port=None):
|
||||||
"""
|
"""Get the DNS records for a domain, including SRV records.
|
||||||
Get the DNS records for a domain.
|
|
||||||
Overriddes XMLStream.get_dns_records to use SRV.
|
|
||||||
|
|
||||||
Arguments:
|
:param domain: The domain in question.
|
||||||
domain -- The domain in question.
|
:param port: If the results don't include a port, use this one.
|
||||||
port -- If the results don't include a port, use this one.
|
|
||||||
"""
|
"""
|
||||||
if port is None:
|
if port is None:
|
||||||
port = self.default_port
|
port = self.default_port
|
||||||
|
@ -177,17 +171,15 @@ class ClientXMPP(BaseXMPP):
|
||||||
return [((domain, port), 0, 0)]
|
return [((domain, port), 0, 0)]
|
||||||
|
|
||||||
def register_feature(self, name, handler, restart=False, order=5000):
|
def register_feature(self, name, handler, restart=False, order=5000):
|
||||||
"""
|
"""Register a stream feature handler.
|
||||||
Register a stream feature.
|
|
||||||
|
|
||||||
Arguments:
|
:param name: The name of the stream feature.
|
||||||
name -- The name of the stream feature.
|
:param handler: The function to execute if the feature is received.
|
||||||
handler -- The function to execute if the feature is received.
|
:param restart: Indicates if feature processing should halt with
|
||||||
restart -- Indicates if feature processing should halt with
|
this feature. Defaults to ``False``.
|
||||||
this feature. Defaults to False.
|
:param order: The relative ordering in which the feature should
|
||||||
order -- The relative ordering in which the feature should
|
be negotiated. Lower values will be attempted
|
||||||
be negotiated. Lower values will be attempted
|
earlier when available.
|
||||||
earlier when available.
|
|
||||||
"""
|
"""
|
||||||
self._stream_feature_handlers[name] = (handler, restart)
|
self._stream_feature_handlers[name] = (handler, restart)
|
||||||
self._stream_feature_order.append((order, name))
|
self._stream_feature_order.append((order, name))
|
||||||
|
@ -195,53 +187,51 @@ class ClientXMPP(BaseXMPP):
|
||||||
|
|
||||||
def update_roster(self, jid, name=None, subscription=None, groups=[],
|
def update_roster(self, jid, name=None, subscription=None, groups=[],
|
||||||
block=True, timeout=None, callback=None):
|
block=True, timeout=None, callback=None):
|
||||||
"""
|
"""Add or change a roster item.
|
||||||
Add or change a roster item.
|
|
||||||
|
|
||||||
Arguments:
|
:param jid: The JID of the entry to modify.
|
||||||
jid -- The JID of the entry to modify.
|
:param name: The user's nickname for this JID.
|
||||||
name -- The user's nickname for this JID.
|
:param subscription: The subscription status. May be one of
|
||||||
subscription -- The subscription status. May be one of
|
``'to'``, ``'from'``, ``'both'``, or
|
||||||
'to', 'from', 'both', or 'none'. If set
|
``'none'``. If set to ``'remove'``,
|
||||||
to 'remove', the entry will be deleted.
|
the entry will be deleted.
|
||||||
groups -- The roster groups that contain this item.
|
:param groups: The roster groups that contain this item.
|
||||||
block -- Specify if the roster request will block
|
:param block: Specify if the roster request will block
|
||||||
until a response is received, or a timeout
|
until a response is received, or a timeout
|
||||||
occurs. Defaults to True.
|
occurs. Defaults to ``True``.
|
||||||
timeout -- The length of time (in seconds) to wait
|
:param timeout: The length of time (in seconds) to wait
|
||||||
for a response before continuing if blocking
|
for a response before continuing if blocking
|
||||||
is used. Defaults to self.response_timeout.
|
is used. Defaults to
|
||||||
callback -- Optional reference to a stream handler function.
|
:attr:`~sleekxmpp.xmlstream.xmlstream.XMLStream.response_timeout`.
|
||||||
Will be executed when the roster is received.
|
:param callback: Optional reference to a stream handler function.
|
||||||
Implies block=False.
|
Will be executed when the roster is received.
|
||||||
|
Implies ``block=False``.
|
||||||
"""
|
"""
|
||||||
return self.client_roster.update(jid, name, subscription, groups,
|
return self.client_roster.update(jid, name, subscription, groups,
|
||||||
block, timeout, callback)
|
block, timeout, callback)
|
||||||
|
|
||||||
def del_roster_item(self, jid):
|
def del_roster_item(self, jid):
|
||||||
"""
|
"""Remove an item from the roster.
|
||||||
Remove an item from the roster by setting its subscription
|
|
||||||
status to 'remove'.
|
This is done by setting its subscription status to ``'remove'``.
|
||||||
|
|
||||||
Arguments:
|
:param jid: The JID of the item to remove.
|
||||||
jid -- The JID of the item to remove.
|
|
||||||
"""
|
"""
|
||||||
return self.client_roster.remove(jid)
|
return self.client_roster.remove(jid)
|
||||||
|
|
||||||
def get_roster(self, block=True, timeout=None, callback=None):
|
def get_roster(self, block=True, timeout=None, callback=None):
|
||||||
"""
|
"""Request the roster from the server.
|
||||||
Request the roster from the server.
|
|
||||||
|
|
||||||
Arguments:
|
:param block: Specify if the roster request will block until a
|
||||||
block -- Specify if the roster request will block until a
|
response is received, or a timeout occurs.
|
||||||
response is received, or a timeout occurs.
|
Defaults to ``True``.
|
||||||
Defaults to True.
|
:param timeout: The length of time (in seconds) to wait for a response
|
||||||
timeout -- The length of time (in seconds) to wait for a response
|
|
||||||
before continuing if blocking is used.
|
before continuing if blocking is used.
|
||||||
Defaults to self.response_timeout.
|
Defaults to
|
||||||
callback -- Optional reference to a stream handler function. Will
|
:attr:`~sleekxmpp.xmlstream.xmlstream.XMLStream.response_timeout`.
|
||||||
be executed when the roster is received.
|
:param callback: Optional reference to a stream handler function. Will
|
||||||
Implies block=False.
|
be executed when the roster is received.
|
||||||
|
Implies ``block=False``.
|
||||||
"""
|
"""
|
||||||
iq = self.Iq()
|
iq = self.Iq()
|
||||||
iq['type'] = 'get'
|
iq['type'] = 'get'
|
||||||
|
@ -260,11 +250,9 @@ class ClientXMPP(BaseXMPP):
|
||||||
self.features = set()
|
self.features = set()
|
||||||
|
|
||||||
def _handle_stream_features(self, features):
|
def _handle_stream_features(self, features):
|
||||||
"""
|
"""Process the received stream features.
|
||||||
Process the received stream features.
|
|
||||||
|
|
||||||
Arguments:
|
:param features: The features stanza.
|
||||||
features -- The features stanza.
|
|
||||||
"""
|
"""
|
||||||
for order, name in self._stream_feature_order:
|
for order, name in self._stream_feature_order:
|
||||||
if name in features['features']:
|
if name in features['features']:
|
||||||
|
@ -275,13 +263,12 @@ class ClientXMPP(BaseXMPP):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _handle_roster(self, iq, request=False):
|
def _handle_roster(self, iq, request=False):
|
||||||
"""
|
"""Update the roster after receiving a roster stanza.
|
||||||
Update the roster after receiving a roster stanza.
|
|
||||||
|
|
||||||
Arguments:
|
:param iq: The roster stanza.
|
||||||
iq -- The roster stanza.
|
:param request: Indicates if this stanza is a response
|
||||||
request -- Indicates if this stanza is a response
|
to a request for the roster, and not an
|
||||||
to a request for the roster.
|
empty acknowledgement from the server.
|
||||||
"""
|
"""
|
||||||
if iq['type'] == 'set' or (iq['type'] == 'result' and request):
|
if iq['type'] == 'set' or (iq['type'] == 'result' and request):
|
||||||
for jid in iq['roster']['items']:
|
for jid in iq['roster']['items']:
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
SleekXMPP: The Sleek XMPP Library
|
sleekxmpp.clientxmpp
|
||||||
Copyright (C) 2010 Nathanael C. Fritz
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
This file is part of SleekXMPP.
|
|
||||||
|
|
||||||
See the file LICENSE for copying permission.
|
This module provides XMPP functionality that
|
||||||
|
is specific to external server component connections.
|
||||||
|
|
||||||
|
Part of SleekXMPP: The Sleek XMPP Library
|
||||||
|
|
||||||
|
:copyright: (c) 2011 Nathanael C. Fritz
|
||||||
|
:license: MIT, see LICENSE for more details
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
@ -32,28 +38,22 @@ class ComponentXMPP(BaseXMPP):
|
||||||
|
|
||||||
Use only for good, not for evil.
|
Use only for good, not for evil.
|
||||||
|
|
||||||
Methods:
|
:param jid: The JID of the component.
|
||||||
connect -- Overrides XMLStream.connect.
|
:param secret: The secret or password for the component.
|
||||||
incoming_filter -- Overrides XMLStream.incoming_filter.
|
:param host: The server accepting the component.
|
||||||
start_stream_handler -- Overrides XMLStream.start_stream_handler.
|
:param port: The port used to connect to the server.
|
||||||
|
:param plugin_config: A dictionary of plugin configurations.
|
||||||
|
:param plugin_whitelist: A list of approved plugins that
|
||||||
|
will be loaded when calling
|
||||||
|
:meth:`~sleekxmpp.basexmpp.BaseXMPP.register_plugins()`.
|
||||||
|
:param use_jc_ns: Indicates if the ``'jabber:client'`` namespace
|
||||||
|
should be used instead of the standard
|
||||||
|
``'jabber:component:accept'`` namespace.
|
||||||
|
Defaults to ``False``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, jid, secret, host, port,
|
def __init__(self, jid, secret, host=None, port=None,
|
||||||
plugin_config={}, plugin_whitelist=[], use_jc_ns=False):
|
plugin_config={}, plugin_whitelist=[], use_jc_ns=False):
|
||||||
"""
|
|
||||||
Arguments:
|
|
||||||
jid -- The JID of the component.
|
|
||||||
secret -- The secret or password for the component.
|
|
||||||
host -- The server accepting the component.
|
|
||||||
port -- The port used to connect to the server.
|
|
||||||
plugin_config -- A dictionary of plugin configurations.
|
|
||||||
plugin_whitelist -- A list of desired plugins to load
|
|
||||||
when using register_plugins.
|
|
||||||
use_js_ns -- Indicates if the 'jabber:client' namespace
|
|
||||||
should be used instead of the standard
|
|
||||||
'jabber:component:accept' namespace.
|
|
||||||
Defaults to False.
|
|
||||||
"""
|
|
||||||
if use_jc_ns:
|
if use_jc_ns:
|
||||||
default_ns = 'jabber:client'
|
default_ns = 'jabber:client'
|
||||||
else:
|
else:
|
||||||
|
@ -81,26 +81,42 @@ class ComponentXMPP(BaseXMPP):
|
||||||
self.add_event_handler('presence_probe',
|
self.add_event_handler('presence_probe',
|
||||||
self._handle_probe)
|
self._handle_probe)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self, host=None, port=None, use_ssl=False,
|
||||||
"""
|
use_tls=True, reattempt=True):
|
||||||
Connect to the server.
|
"""Connect to the server.
|
||||||
|
|
||||||
Overrides XMLStream.connect.
|
Setting ``reattempt`` to ``True`` will cause connection attempts to
|
||||||
|
be made every second until a successful connection is established.
|
||||||
|
|
||||||
|
:param host: The name of the desired server for the connection.
|
||||||
|
Defaults to :attr:`server_host`.
|
||||||
|
:param port: Port to connect to on the server.
|
||||||
|
Defauts to :attr:`server_port`.
|
||||||
|
:param use_ssl: Flag indicating if SSL should be used by connecting
|
||||||
|
directly to a port using SSL.
|
||||||
|
:param use_tls: Flag indicating if TLS should be used, allowing for
|
||||||
|
connecting to a port without using SSL immediately and
|
||||||
|
later upgrading the connection.
|
||||||
|
:param reattempt: Flag indicating if the socket should reconnect
|
||||||
|
after disconnections.
|
||||||
"""
|
"""
|
||||||
log.debug("Connecting to %s:%s", self.server_host,
|
if host is None:
|
||||||
self.server_port)
|
host = self.server_host
|
||||||
return XMLStream.connect(self, self.server_host,
|
if port is None:
|
||||||
self.server_port)
|
port = self.server_port
|
||||||
|
log.debug("Connecting to %s:%s", host, port)
|
||||||
|
return XMLStream.connect(self, host=host, port=port,
|
||||||
|
use_ssl=use_ssl,
|
||||||
|
use_tls=use_tls,
|
||||||
|
reattempt=reattempt)
|
||||||
|
|
||||||
def incoming_filter(self, xml):
|
def incoming_filter(self, xml):
|
||||||
"""
|
"""
|
||||||
Pre-process incoming XML stanzas by converting any 'jabber:client'
|
Pre-process incoming XML stanzas by converting any
|
||||||
namespaced elements to the component's default namespace.
|
``'jabber:client'`` namespaced elements to the component's
|
||||||
|
default namespace.
|
||||||
|
|
||||||
Overrides XMLStream.incoming_filter.
|
:param xml: The XML stanza to pre-process.
|
||||||
|
|
||||||
Arguments:
|
|
||||||
xml -- The XML stanza to pre-process.
|
|
||||||
"""
|
"""
|
||||||
if xml.tag.startswith('{jabber:client}'):
|
if xml.tag.startswith('{jabber:client}'):
|
||||||
xml.tag = xml.tag.replace('jabber:client', self.default_ns)
|
xml.tag = xml.tag.replace('jabber:client', self.default_ns)
|
||||||
|
@ -117,10 +133,7 @@ class ComponentXMPP(BaseXMPP):
|
||||||
Once the streams are established, attempt to handshake
|
Once the streams are established, attempt to handshake
|
||||||
with the server to be accepted as a component.
|
with the server to be accepted as a component.
|
||||||
|
|
||||||
Overrides BaseXMPP.start_stream_handler.
|
:param xml: The incoming stream's root element.
|
||||||
|
|
||||||
Arguments:
|
|
||||||
xml -- The incoming stream's root element.
|
|
||||||
"""
|
"""
|
||||||
BaseXMPP.start_stream_handler(self, xml)
|
BaseXMPP.start_stream_handler(self, xml)
|
||||||
|
|
||||||
|
@ -136,11 +149,9 @@ class ComponentXMPP(BaseXMPP):
|
||||||
self.send_xml(handshake, now=True)
|
self.send_xml(handshake, now=True)
|
||||||
|
|
||||||
def _handle_handshake(self, xml):
|
def _handle_handshake(self, xml):
|
||||||
"""
|
"""The handshake has been accepted.
|
||||||
The handshake has been accepted.
|
|
||||||
|
|
||||||
Arguments:
|
:param xml: The reply handshake stanza.
|
||||||
xml -- The reply handshake stanza.
|
|
||||||
"""
|
"""
|
||||||
self.session_started_event.set()
|
self.session_started_event.set()
|
||||||
self.event("session_start")
|
self.event("session_start")
|
||||||
|
|
Loading…
Reference in a new issue