Merge branch 'remove-unused-obsolete-things' into 'master'

Remove unused and obsolete things, and make other things private

See merge request poezio/slixmpp!117
This commit is contained in:
mathieui 2021-02-04 19:24:29 +01:00
commit d3fb993b29
5 changed files with 20 additions and 219 deletions

View file

@ -9,7 +9,5 @@ Getting Started (with examples)
component
presence
muc
proxy
scheduler
iq

View file

@ -1,40 +0,0 @@
.. _proxy:
=========================
Enable HTTP Proxy Support
=========================
.. note::
If you have any issues working through this quickstart guide
join the chat room at `slixmpp@muc.poez.io
<xmpp:slixmpp@muc.poez.io?join>`_.
In some instances, you may wish to route XMPP traffic through
an HTTP proxy, probably to get around restrictive firewalls.
Slixmpp provides support for basic HTTP proxying with DIGEST
authentication.
Enabling proxy support is done in two steps. The first is to instruct Slixmpp
to use a proxy, and the second is to configure the proxy details:
.. code-block:: python
xmpp = ClientXMPP(...)
xmpp.use_proxy = True
xmpp.proxy_config = {
'host': 'proxy.example.com',
'port': 5555,
'username': 'example_user',
'password': '******'
}
The ``'username'`` and ``'password'`` fields are optional if the proxy does not
require authentication.
The Final Product
-----------------
.. include:: ../../examples/proxy_echo_client.py
:literal:

View file

@ -1,135 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
from getpass import getpass
from argparse import ArgumentParser
import slixmpp
class EchoBot(slixmpp.ClientXMPP):
"""
A simple Slixmpp bot that will echo messages it
receives, along with a short thank you message.
"""
def __init__(self, jid, password):
slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
self.add_event_handler("session_start", self.start)
# The message event is triggered whenever a message
# stanza is received. Be aware that that includes
# MUC messages and error messages.
self.add_event_handler("message", self.message)
async def start(self, event):
"""
Process the session_start event.
Typical actions for the session_start event are
requesting the roster and broadcasting an initial
presence stanza.
Arguments:
event -- An empty dictionary. The session_start
event does not provide any additional
data.
"""
self.send_presence()
await self.get_roster()
def message(self, msg):
"""
Process incoming message stanzas. Be aware that this also
includes MUC messages and error messages. It is usually
a good idea to check the messages's type before processing
or sending replies.
Arguments:
msg -- The received message stanza. See the documentation
for stanza objects and the Message stanza to see
how it may be used.
"""
msg.reply("Thanks for sending\n%(body)s" % msg).send()
if __name__ == '__main__':
# Setup the command line arguments.
parser = ArgumentParser()
# Output verbosity options.
parser.add_argument("-q", "--quiet", help="set logging to ERROR",
action="store_const", dest="loglevel",
const=logging.ERROR, default=logging.INFO)
parser.add_argument("-d", "--debug", help="set logging to DEBUG",
action="store_const", dest="loglevel",
const=logging.DEBUG, default=logging.INFO)
# JID and password options.
parser.add_argument("-j", "--jid", dest="jid",
help="JID to use")
parser.add_argument("-p", "--password", dest="password",
help="password to use")
parser.add_argument("--phost", dest="proxy_host",
help="Proxy hostname")
parser.add_argument("--pport", dest="proxy_port",
help="Proxy port")
parser.add_argument("--puser", dest="proxy_user",
help="Proxy username")
parser.add_argument("--ppass", dest="proxy_pass",
help="Proxy password")
args = parser.parse_args()
# Setup logging.
logging.basicConfig(level=args.loglevel,
format='%(levelname)-8s %(message)s')
if args.jid is None:
args.jid = input("Username: ")
if args.password is None:
args.password = getpass("Password: ")
if args.proxy_host is None:
args.proxy_host = input("Proxy host: ")
if args.proxy_port is None:
args.proxy_port = input("Proxy port: ")
if args.proxy_user is None:
args.proxy_user = input("Proxy username: ")
if args.proxy_pass is None and args.proxy_user:
args.proxy_pass = getpass("Proxy password: ")
# Setup the EchoBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
xmpp = EchoBot(args.jid, args.password)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
xmpp.use_proxy = True
xmpp.proxy_config = {
'host': args.proxy_host,
'port': int(args.proxy_port),
'username': args.proxy_user,
'password': args.proxy_pass}
# Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect()
xmpp.process()

View file

@ -19,15 +19,6 @@ class MatchXPath(MatcherBase):
The XPath matcher selects stanzas whose XML contents matches a given
XPath expression.
.. warning::
Using this matcher may not produce expected behavior when using
attribute selectors. For Python 2.6 and 3.1, the ElementTree
:meth:`~xml.etree.ElementTree.Element.find()` method does
not support the use of attribute selectors. If you need to
support Python 2.6 or 3.1, it might be more useful to use a
:class:`~slixmpp.xmlstream.matcher.stanzapath.StanzaPath` matcher.
If the value of :data:`IGNORE_NS` is set to ``True``, then XPath
expressions will be matched without using namespaces.
"""
@ -42,12 +33,6 @@ class MatchXPath(MatcherBase):
If the value of :data:`IGNORE_NS` is set to ``True``, then XPath
expressions will be matched without using namespaces.
.. warning::
In Python 2.6 and 3.1 the ElementTree
:meth:`~xml.etree.ElementTree.Element.find()` method does not
support attribute selectors in the XPath expression.
:param xml: The :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
stanza to compare against.
"""

View file

@ -16,10 +16,12 @@ from typing import (
Any,
Callable,
Iterable,
Iterator,
List,
Optional,
Set,
Union,
Tuple,
)
import functools
@ -88,7 +90,9 @@ class XMLStream(asyncio.BaseProtocol):
# The socket that is used internally by the transport object
self.socket = None
self.connect_loop_wait = 0
# The backoff of the connect routine (increases exponentially
# after each failure)
self._connect_loop_wait = 0
self.parser = None
self.xml_depth = 0
@ -157,10 +161,6 @@ class XMLStream(asyncio.BaseProtocol):
#: non-SSL traffic and another for SSL traffic.
self.use_ssl = False
#: If set to ``True``, attempt to connect through an HTTP
#: proxy based on the settings in :attr:`proxy_config`.
self.use_proxy = False
#: If set to ``True``, attempt to use IPv6.
self.use_ipv6 = True
@ -173,13 +173,6 @@ class XMLStream(asyncio.BaseProtocol):
#: to ``False``.
self.use_cdata = False
#: An optional dictionary of proxy settings. It may provide:
#: :host: The host offering proxy services.
#: :port: The port for the proxy service.
#: :username: Optional username for accessing the proxy.
#: :password: Optional password for accessing the proxy.
self.proxy_config = {}
#: The default namespace of the stream content, not of the
#: stream wrapper itself.
self.default_ns = ''
@ -221,7 +214,7 @@ class XMLStream(asyncio.BaseProtocol):
self._current_connection_attempt = None
#: A list of DNS results that have not yet been tried.
self.dns_answers = None
self._dns_answers: Optional[Iterator[Tuple[str, str, int]]] = None
#: The service name to check with DNS SRV records. For
#: example, setting this to ``'xmpp-client'`` would query the
@ -295,7 +288,7 @@ class XMLStream(asyncio.BaseProtocol):
self.disconnect_reason = None
self.cancel_connection_attempt()
self.connect_loop_wait = 0
self._connect_loop_wait = 0
if host and port:
self.address = (host, int(port))
try:
@ -320,11 +313,11 @@ class XMLStream(asyncio.BaseProtocol):
async def _connect_routine(self):
self.event_when_connected = "connected"
if self.connect_loop_wait > 0:
self.event('reconnect_delay', self.connect_loop_wait)
await asyncio.sleep(self.connect_loop_wait, loop=self.loop)
if self._connect_loop_wait > 0:
self.event('reconnect_delay', self._connect_loop_wait)
await asyncio.sleep(self._connect_loop_wait, loop=self.loop)
record = await self.pick_dns_answer(self.default_domain)
record = await self._pick_dns_answer(self.default_domain)
if record is not None:
host, address, dns_port = record
port = dns_port if dns_port else self.address[1]
@ -333,7 +326,7 @@ class XMLStream(asyncio.BaseProtocol):
else:
# No DNS records left, stop iterating
# and try (host, port) as a last resort
self.dns_answers = None
self._dns_answers = None
if self.use_ssl:
ssl_context = self.get_ssl_context()
@ -348,7 +341,7 @@ class XMLStream(asyncio.BaseProtocol):
self.address[1],
ssl=ssl_context,
server_hostname=self.default_domain if self.use_ssl else None)
self.connect_loop_wait = 0
self._connect_loop_wait = 0
except Socket.gaierror as e:
self.event('connection_failed',
'No DNS record available for %s' % self.default_domain)
@ -357,7 +350,7 @@ class XMLStream(asyncio.BaseProtocol):
self.event("connection_failed", e)
if self._current_connection_attempt is None:
return
self.connect_loop_wait = self.connect_loop_wait * 2 + 1
self._connect_loop_wait = self._connect_loop_wait * 2 + 1
self._current_connection_attempt = asyncio.ensure_future(
self._connect_routine(),
loop=self.loop,
@ -401,7 +394,7 @@ class XMLStream(asyncio.BaseProtocol):
self._current_connection_attempt = None
self.init_parser()
self.send_raw(self.stream_header)
self.dns_answers = None
self._dns_answers = None
def data_received(self, data):
"""Called when incoming data is received on the socket.
@ -786,7 +779,7 @@ class XMLStream(asyncio.BaseProtocol):
idx += 1
return False
async def get_dns_records(self, domain, port=None):
async def get_dns_records(self, domain: str, port: Optional[int] = None) -> List[Tuple[str, str, int]]:
"""Get the DNS records for a domain.
:param domain: The domain in question.
@ -806,7 +799,7 @@ class XMLStream(asyncio.BaseProtocol):
loop=self.loop)
return result
async def pick_dns_answer(self, domain, port=None):
async def _pick_dns_answer(self, domain: str, port: Optional[int] = None) -> Optional[Tuple[str, str, int]]:
"""Pick a server and port from DNS answers.
Gets DNS answers if none available.
@ -815,12 +808,12 @@ class XMLStream(asyncio.BaseProtocol):
:param domain: The domain in question.
:param port: If the results don't include a port, use this one.
"""
if self.dns_answers is None:
if self._dns_answers is None:
dns_records = await self.get_dns_records(domain, port)
self.dns_answers = iter(dns_records)
self._dns_answers = iter(dns_records)
try:
return next(self.dns_answers)
return next(self._dns_answers)
except StopIteration:
return