summaryrefslogtreecommitdiff
path: root/sleekxmpp/thirdparty
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp/thirdparty')
-rw-r--r--sleekxmpp/thirdparty/__init__.py1
-rw-r--r--sleekxmpp/thirdparty/orderedset.py89
-rw-r--r--sleekxmpp/thirdparty/socks.py17
-rw-r--r--sleekxmpp/thirdparty/statemachine.py12
4 files changed, 113 insertions, 6 deletions
diff --git a/sleekxmpp/thirdparty/__init__.py b/sleekxmpp/thirdparty/__init__.py
index 2a1db717..337598ac 100644
--- a/sleekxmpp/thirdparty/__init__.py
+++ b/sleekxmpp/thirdparty/__init__.py
@@ -10,3 +10,4 @@ except:
from sleekxmpp.thirdparty import socks
from sleekxmpp.thirdparty.mini_dateutil import tzutc, tzoffset, parse_iso
+from sleekxmpp.thirdparty.orderedset import OrderedSet
diff --git a/sleekxmpp/thirdparty/orderedset.py b/sleekxmpp/thirdparty/orderedset.py
new file mode 100644
index 00000000..f6642db3
--- /dev/null
+++ b/sleekxmpp/thirdparty/orderedset.py
@@ -0,0 +1,89 @@
+# Copyright (c) 2009 Raymond Hettinger
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import collections
+
+class OrderedSet(collections.MutableSet):
+
+ def __init__(self, iterable=None):
+ self.end = end = []
+ end += [None, end, end] # sentinel node for doubly linked list
+ self.map = {} # key --> [key, prev, next]
+ if iterable is not None:
+ self |= iterable
+
+ def __len__(self):
+ return len(self.map)
+
+ def __contains__(self, key):
+ return key in self.map
+
+ def add(self, key):
+ if key not in self.map:
+ end = self.end
+ curr = end[1]
+ curr[2] = end[1] = self.map[key] = [key, curr, end]
+
+ def discard(self, key):
+ if key in self.map:
+ key, prev, next = self.map.pop(key)
+ prev[2] = next
+ next[1] = prev
+
+ def __iter__(self):
+ end = self.end
+ curr = end[2]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[2]
+
+ def __reversed__(self):
+ end = self.end
+ curr = end[1]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[1]
+
+ def pop(self, last=True):
+ if not self:
+ raise KeyError('set is empty')
+ key = self.end[1][0] if last else self.end[2][0]
+ self.discard(key)
+ return key
+
+ def __repr__(self):
+ if not self:
+ return '%s()' % (self.__class__.__name__,)
+ return '%s(%r)' % (self.__class__.__name__, list(self))
+
+ def __eq__(self, other):
+ if isinstance(other, OrderedSet):
+ return len(self) == len(other) and list(self) == list(other)
+ return set(self) == set(other)
+
+
+if __name__ == '__main__':
+ s = OrderedSet('abracadaba')
+ t = OrderedSet('simsalabim')
+ print(s | t)
+ print(s & t)
+ print(s - t) \ No newline at end of file
diff --git a/sleekxmpp/thirdparty/socks.py b/sleekxmpp/thirdparty/socks.py
index 9239a7b9..34090d51 100644
--- a/sleekxmpp/thirdparty/socks.py
+++ b/sleekxmpp/thirdparty/socks.py
@@ -28,6 +28,9 @@ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE.
This module provides a standard socket-like interface for Python
for tunneling connections through SOCKS proxies.
+"""
+
+"""
Minor modifications made by Christopher Gilbert (http://motomastyle.com/)
for use in PyLoris (http://pyloris.sourceforge.net/)
@@ -35,10 +38,13 @@ for use in PyLoris (http://pyloris.sourceforge.net/)
Minor modifications made by Mario Vilas (http://breakingcode.wordpress.com/)
mainly to merge bug fixes found in Sourceforge
+Minor modifications made by Eugene Dementiev (http://www.dementiev.eu/)
+
"""
import socket
import struct
+import sys
PROXY_TYPE_SOCKS4 = 1
PROXY_TYPE_SOCKS5 = 2
@@ -208,12 +214,12 @@ class socksocket(socket.socket):
if self.__proxy[3]:
# Resolve remotely
ipaddr = None
- req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + destaddr
+ req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + destaddr.encode()
else:
# Resolve locally
ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
req = req + chr(0x01).encode() + ipaddr
- req = req + struct.pack(">H", destport)
+ req += struct.pack(">H", destport)
self.sendall(req)
# Get the response
resp = self.__recvall(4)
@@ -282,7 +288,7 @@ class socksocket(socket.socket):
# The username parameter is considered userid for SOCKS4
if self.__proxy[4] != None:
req = req + self.__proxy[4]
- req = req + chr(0x00).encode()
+ req += chr(0x00).encode()
# DNS name if remote resolving is required
# NOTE: This is actually an extension to the SOCKS4 protocol
# called SOCKS4A and may not be supported in all cases.
@@ -323,7 +329,10 @@ class socksocket(socket.socket):
# We read the response until we get the string "\r\n\r\n"
resp = self.recv(1)
while resp.find("\r\n\r\n".encode()) == -1:
- resp = resp + self.recv(1)
+ recv = self.recv(1)
+ if not recv:
+ raise GeneralProxyError((1, _generalerrors[1]))
+ resp = resp + recv
# We just need the first line to check if the connection
# was successful
statusline = resp.splitlines()[0].split(" ".encode(), 2)
diff --git a/sleekxmpp/thirdparty/statemachine.py b/sleekxmpp/thirdparty/statemachine.py
index 113320fa..6c504dce 100644
--- a/sleekxmpp/thirdparty/statemachine.py
+++ b/sleekxmpp/thirdparty/statemachine.py
@@ -34,7 +34,7 @@ class StateMachine(object):
self.lock.release()
- def transition(self, from_state, to_state, wait=0.0, func=None, args=[], kwargs={}):
+ def transition(self, from_state, to_state, wait=0.0, func=None, args=None, kwargs=None):
'''
Transition from the given `from_state` to the given `to_state`.
This method will return `True` if the state machine is now in `to_state`. It
@@ -65,15 +65,23 @@ class StateMachine(object):
values for `args` and `kwargs` are provided, they are expanded and passed like so:
`func( *args, **kwargs )`.
'''
+ if not args:
+ args = []
+ if not kwargs:
+ kwargs = {}
return self.transition_any((from_state,), to_state, wait=wait,
func=func, args=args, kwargs=kwargs)
- def transition_any(self, from_states, to_state, wait=0.0, func=None, args=[], kwargs={}):
+ def transition_any(self, from_states, to_state, wait=0.0, func=None, args=None, kwargs=None):
'''
Transition from any of the given `from_states` to the given `to_state`.
'''
+ if not args:
+ args = []
+ if not kwargs:
+ kwargs = {}
if not isinstance(from_states, (tuple, list, set)):
raise ValueError("from_states should be a list, tuple, or set")