# # Basic plugin template created by: # Copyright (C) 2008 Martijn Voncken # 2007-2009 Andrew Resch # 2009 Damien Churchill # 2010 Pedro Algarvio # 2017 Calum Lind # # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with # the additional special exception to link portions of this program with the OpenSSL library. # See LICENSE for more details. # import os.path from functools import wraps from sys import exc_info from pkg_resources import resource_filename def get_resource(filename): return resource_filename(__package__, os.path.join('data', filename)) def raises_errors_as(error): """Factory class that returns a decorator which wraps the decorated function to raise all exceptions as the specified error type. """ def decorator(func): """Returns a function which wraps the given func to raise all exceptions as error.""" @wraps(func) def wrapper(self, *args, **kwargs): """Wraps the function in a try..except block and calls it with the specified args. Raises: Any exceptions as error preserving the message and traceback. """ try: return func(self, *args, **kwargs) except Exception: (value, tb) = exc_info()[1:] raise error(value).with_traceback(tb) from None return wrapper return decorator def remove_zeros(ip): """Removes unneeded zeros from ip addresses. Args: ip (str): The ip address. Returns: str: The ip address without the unneeded zeros. Example: 000.000.000.003 -> 0.0.0.3 """ return '.'.join([part.lstrip('0').zfill(1) for part in ip.split('.')]) class BadIP(Exception): _message = None def __init__(self, message): super().__init__(message) def __set_message(self, message): self._message = message def __get_message(self): return self._message message = property(__get_message, __set_message) del __get_message, __set_message class IP: __slots__ = ('q1', 'q2', 'q3', 'q4', '_long') def __init__(self, q1, q2, q3, q4): self.q1 = q1 self.q2 = q2 self.q3 = q3 self.q4 = q4 self._long = 0 for q in self.quadrants(): self._long = (self._long << 8) | int(q) @property def address(self): return '.'.join([str(q) for q in [self.q1, self.q2, self.q3, self.q4]]) @property def long(self): return self._long @classmethod def parse(cls, ip): try: q1, q2, q3, q4 = (int(q) for q in ip.split('.')) except ValueError: raise BadIP(_('The IP address "%s" is badly formed' % ip)) if q1 < 0 or q2 < 0 or q3 < 0 or q4 < 0: raise BadIP(_('The IP address "%s" is badly formed' % ip)) elif q1 > 255 or q2 > 255 or q3 > 255 or q4 > 255: raise BadIP(_('The IP address "%s" is badly formed' % ip)) return cls(q1, q2, q3, q4) def quadrants(self): return (self.q1, self.q2, self.q3, self.q4) # def next_ip(self): # (q1, q2, q3, q4) = self.quadrants() # if q4 >= 255: # if q3 >= 255: # if q2 >= 255: # if q1 >= 255: # raise BadIP(_('There is not a next IP address')) # q1 += 1 # else: # q2 += 1 # else: # q3 += 1 # else: # q4 += 1 # return IP(q1, q2, q3, q4) # # def previous_ip(self): # (q1, q2, q3, q4) = self.quadrants() # if q4 <= 1: # if q3 <= 1: # if q2 <= 1: # if q1 <= 1: # raise BadIP(_('There is not a previous IP address')) # q1 -= 1 # else: # q2 -= 1 # else: # q3 -= 1 # else: # q4 -= 1 # return IP(q1, q2, q3, q4) def __lt__(self, other): if isinstance(other, ''.__class__): other = IP.parse(other) return self.long < other.long def __gt__(self, other): if isinstance(other, ''.__class__): other = IP.parse(other) return self.long > other.long def __eq__(self, other): if isinstance(other, ''.__class__): other = IP.parse(other) return self.long == other.long def __repr__(self): return '<{} long={} address="{}">'.format( self.__class__.__name__, self.long, self.address, )