summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp/xmlstream')
-rw-r--r--sleekxmpp/xmlstream/__init__.py2
-rw-r--r--sleekxmpp/xmlstream/handler/waiter.py9
-rw-r--r--sleekxmpp/xmlstream/jid.py149
-rw-r--r--sleekxmpp/xmlstream/scheduler.py10
-rw-r--r--sleekxmpp/xmlstream/tostring.py32
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py17
6 files changed, 43 insertions, 176 deletions
diff --git a/sleekxmpp/xmlstream/__init__.py b/sleekxmpp/xmlstream/__init__.py
index 67b20c56..5a1ea1be 100644
--- a/sleekxmpp/xmlstream/__init__.py
+++ b/sleekxmpp/xmlstream/__init__.py
@@ -6,7 +6,7 @@
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream.jid import JID
+from sleekxmpp.jid import JID
from sleekxmpp.xmlstream.scheduler import Scheduler
from sleekxmpp.xmlstream.stanzabase import StanzaBase, ElementBase, ET
from sleekxmpp.xmlstream.stanzabase import register_stanza_plugin
diff --git a/sleekxmpp/xmlstream/handler/waiter.py b/sleekxmpp/xmlstream/handler/waiter.py
index 899df17c..66e14496 100644
--- a/sleekxmpp/xmlstream/handler/waiter.py
+++ b/sleekxmpp/xmlstream/handler/waiter.py
@@ -10,11 +10,8 @@
"""
import logging
-try:
- import queue
-except ImportError:
- import Queue as queue
+from sleekxmpp.util import Queue, QueueEmpty
from sleekxmpp.xmlstream.handler.base import BaseHandler
@@ -37,7 +34,7 @@ class Waiter(BaseHandler):
def __init__(self, name, matcher, stream=None):
BaseHandler.__init__(self, name, matcher, stream=stream)
- self._payload = queue.Queue()
+ self._payload = Queue()
def prerun(self, payload):
"""Store the matched stanza when received during processing.
@@ -74,7 +71,7 @@ class Waiter(BaseHandler):
try:
stanza = self._payload.get(True, 1)
break
- except queue.Empty:
+ except QueueEmpty:
elapsed_time += 1
if elapsed_time >= timeout:
log.warning("Timed out waiting for %s", self.name)
diff --git a/sleekxmpp/xmlstream/jid.py b/sleekxmpp/xmlstream/jid.py
index 1582164a..2b59db47 100644
--- a/sleekxmpp/xmlstream/jid.py
+++ b/sleekxmpp/xmlstream/jid.py
@@ -1,148 +1,5 @@
-# -*- coding: utf-8 -*-
-"""
- sleekxmpp.xmlstream.jid
- ~~~~~~~~~~~~~~~~~~~~~~~
+import logging
- This module allows for working with Jabber IDs (JIDs) by
- providing accessors for the various components of a JID.
+logging.warning('Deprecated: sleekxmpp.xmlstream.jid is moving to sleekxmpp.jid')
- Part of SleekXMPP: The Sleek XMPP Library
-
- :copyright: (c) 2011 Nathanael C. Fritz
- :license: MIT, see LICENSE for more details
-"""
-
-from __future__ import unicode_literals
-
-
-class JID(object):
-
- """
- A representation of a Jabber ID, or JID.
-
- Each JID may have three components: a user, a domain, and an optional
- resource. For example: user@domain/resource
-
- When a resource is not used, the JID is called a bare JID.
- The JID is a full JID otherwise.
-
- **JID Properties:**
- :jid: Alias for ``full``.
- :full: The value of the full JID.
- :bare: The value of the bare JID.
- :user: The username portion of the JID.
- :domain: The domain name portion of the JID.
- :server: Alias for ``domain``.
- :resource: The resource portion of the JID.
-
- :param string jid: A string of the form ``'[user@]domain[/resource]'``.
- """
-
- def __init__(self, jid):
- """Initialize a new JID"""
- self.reset(jid)
-
- def reset(self, jid):
- """Start fresh from a new JID string.
-
- :param string jid: A string of the form ``'[user@]domain[/resource]'``.
- """
- if isinstance(jid, JID):
- jid = jid.full
- self._full = self._jid = jid
- self._domain = None
- self._resource = None
- self._user = None
- self._bare = None
-
- def __getattr__(self, name):
- """Handle getting the JID values, using cache if available.
-
- :param name: One of: user, server, domain, resource,
- full, or bare.
- """
- if name == 'resource':
- if self._resource is None and '/' in self._jid:
- self._resource = self._jid.split('/', 1)[-1]
- return self._resource or ""
- elif name == 'user':
- if self._user is None:
- if '@' in self._jid:
- self._user = self._jid.split('@', 1)[0]
- else:
- self._user = self._user
- return self._user or ""
- elif name in ('server', 'domain', 'host'):
- if self._domain is None:
- self._domain = self._jid.split('@', 1)[-1].split('/', 1)[0]
- return self._domain or ""
- elif name in ('full', 'jid'):
- return self._jid or ""
- elif name == 'bare':
- if self._bare is None:
- self._bare = self._jid.split('/', 1)[0]
- return self._bare or ""
-
- def __setattr__(self, name, value):
- """Edit a JID by updating it's individual values, resetting the
- generated JID in the end.
-
- Arguments:
- name -- The name of the JID part. One of: user, domain,
- server, resource, full, jid, or bare.
- value -- The new value for the JID part.
- """
- if name in ('resource', 'user', 'domain'):
- object.__setattr__(self, "_%s" % name, value)
- self.regenerate()
- elif name in ('server', 'domain', 'host'):
- self.domain = value
- elif name in ('full', 'jid'):
- self.reset(value)
- self.regenerate()
- elif name == 'bare':
- if '@' in value:
- u, d = value.split('@', 1)
- object.__setattr__(self, "_user", u)
- object.__setattr__(self, "_domain", d)
- else:
- object.__setattr__(self, "_user", '')
- object.__setattr__(self, "_domain", value)
- self.regenerate()
- else:
- object.__setattr__(self, name, value)
-
- def regenerate(self):
- """Generate a new JID based on current values, useful after editing."""
- jid = ""
- if self.user:
- jid = "%s@" % self.user
- jid += self.domain
- if self.resource:
- jid += "/%s" % self.resource
- self.reset(jid)
-
- def __str__(self):
- """Use the full JID as the string value."""
- return self.full
-
- def __repr__(self):
- return self.full
-
- def __eq__(self, other):
- """
- Two JIDs are considered equal if they have the same full JID value.
- """
- other = JID(other)
- return self.full == other.full
-
- def __ne__(self, other):
- """Two JIDs are considered unequal if they are not equal."""
- return not self == other
-
- def __hash__(self):
- """Hash a JID based on the string version of its full JID."""
- return hash(self.full)
-
- def __copy__(self):
- return JID(self.jid)
+from sleekxmpp.jid import JID
diff --git a/sleekxmpp/xmlstream/scheduler.py b/sleekxmpp/xmlstream/scheduler.py
index f68af081..d98dc6c8 100644
--- a/sleekxmpp/xmlstream/scheduler.py
+++ b/sleekxmpp/xmlstream/scheduler.py
@@ -15,10 +15,8 @@
import time
import threading
import logging
-try:
- import queue
-except ImportError:
- import Queue as queue
+
+from sleekxmpp.util import Queue, QueueEmpty
log = logging.getLogger(__name__)
@@ -102,7 +100,7 @@ class Scheduler(object):
def __init__(self, parentstop=None):
#: A queue for storing tasks
- self.addq = queue.Queue()
+ self.addq = Queue()
#: A list of tasks in order of execution time.
self.schedule = []
@@ -157,7 +155,7 @@ class Scheduler(object):
elapsed < wait:
newtask = self.addq.get(True, 0.1)
elapsed += 0.1
- except queue.Empty:
+ except QueueEmpty:
cleanup = []
self.schedule_lock.acquire()
for task in self.schedule:
diff --git a/sleekxmpp/xmlstream/tostring.py b/sleekxmpp/xmlstream/tostring.py
index 2480f9b2..f22e7770 100644
--- a/sleekxmpp/xmlstream/tostring.py
+++ b/sleekxmpp/xmlstream/tostring.py
@@ -63,9 +63,11 @@ def tostring(xml=None, xmlns='', stanza_ns='', stream=None,
default_ns = ''
stream_ns = ''
+ use_cdata = False
if stream:
default_ns = stream.default_ns
stream_ns = stream.stream_ns
+ use_cdata = stream.use_cdata
# Output the tag name and derived namespace of the element.
namespace = ''
@@ -81,7 +83,7 @@ def tostring(xml=None, xmlns='', stanza_ns='', stream=None,
# Output escaped attribute values.
for attrib, value in xml.attrib.items():
- value = xml_escape(value)
+ value = escape(value, use_cdata)
if '}' not in attrib:
output.append(' %s="%s"' % (attrib, value))
else:
@@ -105,24 +107,24 @@ def tostring(xml=None, xmlns='', stanza_ns='', stream=None,
# If there are additional child elements to serialize.
output.append(">")
if xml.text:
- output.append(xml_escape(xml.text))
+ output.append(escape(xml.text, use_cdata))
if len(xml):
for child in xml:
output.append(tostring(child, tag_xmlns, stanza_ns, stream))
output.append("</%s>" % tag_name)
elif xml.text:
# If we only have text content.
- output.append(">%s</%s>" % (xml_escape(xml.text), tag_name))
+ output.append(">%s</%s>" % (escape(xml.text, use_cdata), tag_name))
else:
# Empty element.
output.append(" />")
if xml.tail:
# If there is additional text after the element.
- output.append(xml_escape(xml.tail))
+ output.append(escape(xml.tail, use_cdata))
return ''.join(output)
-def xml_escape(text):
+def escape(text, use_cdata=False):
"""Convert special characters in XML to escape sequences.
:param string text: The XML text to convert.
@@ -132,12 +134,24 @@ def xml_escape(text):
if type(text) != types.UnicodeType:
text = unicode(text, 'utf-8', 'ignore')
- text = list(text)
escapes = {'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&apos;',
'"': '&quot;'}
- for i, c in enumerate(text):
- text[i] = escapes.get(c, c)
- return ''.join(text)
+
+ if not use_cdata:
+ text = list(text)
+ for i, c in enumerate(text):
+ text[i] = escapes.get(c, c)
+ return ''.join(text)
+ else:
+ escape_needed = False
+ for c in text:
+ if c in escapes:
+ escape_needed = True
+ break
+ if escape_needed:
+ escaped = map(lambda x : "<![CDATA[%s]]>" % x, text.split("]]>"))
+ return "<![CDATA[]]]><![CDATA[]>]]>".join(escaped)
+ return text
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index 49f33933..a0b6e4c2 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -26,14 +26,11 @@ import time
import random
import weakref
import uuid
-try:
- import queue
-except ImportError:
- import Queue as queue
from xml.parsers.expat import ExpatError
import sleekxmpp
+from sleekxmpp.util import Queue, QueueEmpty
from sleekxmpp.thirdparty.statemachine import StateMachine
from sleekxmpp.xmlstream import Scheduler, tostring, cert
from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET, ElementBase
@@ -215,6 +212,10 @@ class XMLStream(object):
#: If set to ``True``, attempt to use IPv6.
self.use_ipv6 = True
+ #: Use CDATA for escaping instead of XML entities. Defaults
+ #: 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.
@@ -270,10 +271,10 @@ class XMLStream(object):
self.end_session_on_disconnect = True
#: A queue of stream, custom, and scheduled events to be processed.
- self.event_queue = queue.Queue()
+ self.event_queue = Queue()
#: A queue of string data to be sent over the stream.
- self.send_queue = queue.Queue()
+ self.send_queue = Queue()
self.send_queue_lock = threading.Lock()
self.send_lock = threading.RLock()
@@ -1586,7 +1587,7 @@ class XMLStream(object):
try:
wait = self.wait_timeout
event = self.event_queue.get(True, timeout=wait)
- except queue.Empty:
+ except QueueEmpty:
event = None
if event is None:
continue
@@ -1655,7 +1656,7 @@ class XMLStream(object):
else:
try:
data = self.send_queue.get(True, 1)
- except queue.Empty:
+ except QueueEmpty:
continue
log.debug("SEND: %s", data)
enc_data = data.encode('utf-8')