mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-05 20:51:15 -07:00
Update IPy-1.01
This commit is contained in:
parent
f6f6421154
commit
db79e050c2
1 changed files with 25 additions and 17 deletions
42
lib/IPy.py
42
lib/IPy.py
|
@ -6,12 +6,14 @@ Further Information might be available at:
|
||||||
https://github.com/haypo/python-ipy
|
https://github.com/haypo/python-ipy
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = '0.83'
|
__version__ = '1.01'
|
||||||
|
|
||||||
import bisect
|
import bisect
|
||||||
import collections
|
|
||||||
import sys
|
|
||||||
import types
|
import types
|
||||||
|
try:
|
||||||
|
import collections.abc as collections_abc
|
||||||
|
except ImportError:
|
||||||
|
import collections as collections_abc
|
||||||
|
|
||||||
# Definition of the Ranges for IPv4 IPs
|
# Definition of the Ranges for IPv4 IPs
|
||||||
# this should include www.iana.org/assignments/ipv4-address-space
|
# this should include www.iana.org/assignments/ipv4-address-space
|
||||||
|
@ -21,7 +23,7 @@ IPv4ranges = {
|
||||||
'00000000': 'PRIVATE', # 0/8
|
'00000000': 'PRIVATE', # 0/8
|
||||||
'00001010': 'PRIVATE', # 10/8
|
'00001010': 'PRIVATE', # 10/8
|
||||||
'0110010001': 'CARRIER_GRADE_NAT', #100.64/10
|
'0110010001': 'CARRIER_GRADE_NAT', #100.64/10
|
||||||
'01111111': 'PRIVATE', # 127.0/8
|
'01111111': 'LOOPBACK', # 127.0/8
|
||||||
'1': 'PUBLIC', # fall back
|
'1': 'PUBLIC', # fall back
|
||||||
'1010100111111110': 'PRIVATE', # 169.254/16
|
'1010100111111110': 'PRIVATE', # 169.254/16
|
||||||
'101011000001': 'PRIVATE', # 172.16/12
|
'101011000001': 'PRIVATE', # 172.16/12
|
||||||
|
@ -121,13 +123,14 @@ MAX_IPV6_ADDRESS = 0xffffffffffffffffffffffffffffffff
|
||||||
IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000
|
IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000
|
||||||
IPV6_MAP_MASK = 0x00000000000000000000ffff00000000
|
IPV6_MAP_MASK = 0x00000000000000000000ffff00000000
|
||||||
|
|
||||||
if sys.version_info >= (3,):
|
try:
|
||||||
|
INT_TYPES = (int, long)
|
||||||
|
STR_TYPES = (str, unicode)
|
||||||
|
xrange
|
||||||
|
except NameError:
|
||||||
INT_TYPES = (int,)
|
INT_TYPES = (int,)
|
||||||
STR_TYPES = (str,)
|
STR_TYPES = (str,)
|
||||||
xrange = range
|
xrange = range
|
||||||
else:
|
|
||||||
INT_TYPES = (int, long)
|
|
||||||
STR_TYPES = (str, unicode)
|
|
||||||
|
|
||||||
|
|
||||||
class IPint(object):
|
class IPint(object):
|
||||||
|
@ -243,7 +246,7 @@ class IPint(object):
|
||||||
else:
|
else:
|
||||||
raise ValueError("can't parse")
|
raise ValueError("can't parse")
|
||||||
|
|
||||||
(self.ip, parsedVersion) = parseAddress(ip)
|
(self.ip, parsedVersion) = parseAddress(ip, ipversion)
|
||||||
if ipversion == 0:
|
if ipversion == 0:
|
||||||
ipversion = parsedVersion
|
ipversion = parsedVersion
|
||||||
if prefixlen == -1:
|
if prefixlen == -1:
|
||||||
|
@ -475,7 +478,7 @@ class IPint(object):
|
||||||
"""Return a description of the IP type ('PRIVATE', 'RESERVED', etc).
|
"""Return a description of the IP type ('PRIVATE', 'RESERVED', etc).
|
||||||
|
|
||||||
>>> print(IP('127.0.0.1').iptype())
|
>>> print(IP('127.0.0.1').iptype())
|
||||||
PRIVATE
|
LOOPBACK
|
||||||
>>> print(IP('192.168.1.1').iptype())
|
>>> print(IP('192.168.1.1').iptype())
|
||||||
PRIVATE
|
PRIVATE
|
||||||
>>> print(IP('195.185.1.2').iptype())
|
>>> print(IP('195.185.1.2').iptype())
|
||||||
|
@ -558,6 +561,8 @@ class IPint(object):
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return self.__nonzero__()
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""
|
"""
|
||||||
|
@ -769,6 +774,9 @@ class IPint(object):
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return self.__cmp__(other) < 0
|
return self.__cmp__(other) < 0
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
return self.__cmp__(other) <= 0
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
"""Called for the key object for dictionary operations, and by
|
"""Called for the key object for dictionary operations, and by
|
||||||
the built-in function hash(). Should return a 32-bit integer
|
the built-in function hash(). Should return a 32-bit integer
|
||||||
|
@ -1017,10 +1025,10 @@ class IP(IPint):
|
||||||
raise ValueError("%s cannot be converted to an IPv4 address."
|
raise ValueError("%s cannot be converted to an IPv4 address."
|
||||||
% repr(self))
|
% repr(self))
|
||||||
|
|
||||||
class IPSet(collections.MutableSet):
|
class IPSet(collections_abc.MutableSet):
|
||||||
def __init__(self, iterable=[]):
|
def __init__(self, iterable=[]):
|
||||||
# Make sure it's iterable, otherwise wrap
|
# Make sure it's iterable, otherwise wrap
|
||||||
if not isinstance(iterable, collections.Iterable):
|
if not isinstance(iterable, collections_abc.Iterable):
|
||||||
raise TypeError("'%s' object is not iterable" % type(iterable).__name__)
|
raise TypeError("'%s' object is not iterable" % type(iterable).__name__)
|
||||||
|
|
||||||
# Make sure we only accept IP objects
|
# Make sure we only accept IP objects
|
||||||
|
@ -1094,7 +1102,7 @@ class IPSet(collections.MutableSet):
|
||||||
|
|
||||||
def add(self, value):
|
def add(self, value):
|
||||||
# Make sure it's iterable, otherwise wrap
|
# Make sure it's iterable, otherwise wrap
|
||||||
if not isinstance(value, collections.Iterable):
|
if not isinstance(value, collections_abc.Iterable):
|
||||||
value = [value]
|
value = [value]
|
||||||
|
|
||||||
# Check type
|
# Check type
|
||||||
|
@ -1108,7 +1116,7 @@ class IPSet(collections.MutableSet):
|
||||||
|
|
||||||
def discard(self, value):
|
def discard(self, value):
|
||||||
# Make sure it's iterable, otherwise wrap
|
# Make sure it's iterable, otherwise wrap
|
||||||
if not isinstance(value, collections.Iterable):
|
if not isinstance(value, collections_abc.Iterable):
|
||||||
value = [value]
|
value = [value]
|
||||||
|
|
||||||
# This is much faster than iterating over the addresses
|
# This is much faster than iterating over the addresses
|
||||||
|
@ -1336,7 +1344,7 @@ def _parseAddressIPv6(ipstr):
|
||||||
index += 1
|
index += 1
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def parseAddress(ipstr):
|
def parseAddress(ipstr, ipversion=0):
|
||||||
"""
|
"""
|
||||||
Parse a string and return the corresponding IP address (as integer)
|
Parse a string and return the corresponding IP address (as integer)
|
||||||
and a guess of the IP version.
|
and a guess of the IP version.
|
||||||
|
@ -1405,7 +1413,7 @@ def parseAddress(ipstr):
|
||||||
# assume IPv6 in pure hexadecimal notation
|
# assume IPv6 in pure hexadecimal notation
|
||||||
return (hexval, 6)
|
return (hexval, 6)
|
||||||
|
|
||||||
elif ipstr.find('.') != -1 or (intval is not None and intval < 256):
|
elif ipstr.find('.') != -1 or (intval is not None and intval < 256 and ipversion != 6):
|
||||||
# assume IPv4 ('127' gets interpreted as '127.0.0.0')
|
# assume IPv4 ('127' gets interpreted as '127.0.0.0')
|
||||||
bytes = ipstr.split('.')
|
bytes = ipstr.split('.')
|
||||||
if len(bytes) > 4:
|
if len(bytes) > 4:
|
||||||
|
@ -1423,7 +1431,7 @@ def parseAddress(ipstr):
|
||||||
# will be interpreted as IPv4 first byte
|
# will be interpreted as IPv4 first byte
|
||||||
if intval > MAX_IPV6_ADDRESS:
|
if intval > MAX_IPV6_ADDRESS:
|
||||||
raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, intval))
|
raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, intval))
|
||||||
if intval <= MAX_IPV4_ADDRESS:
|
if intval <= MAX_IPV4_ADDRESS and ipversion != 6:
|
||||||
return (intval, 4)
|
return (intval, 4)
|
||||||
else:
|
else:
|
||||||
return (intval, 6)
|
return (intval, 6)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue