+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-@author: Frank Brehm
-@contact: frank.brehm@pixelpark.com
-@copyright: © 2018 by Frank Brehm, Berlin
-@summary: The module for common used functions.
-"""
-
-# Standard modules
-import sys
-import os
-import logging
-import re
-import pprint
-import platform
-import locale
-
-# Third party modules
-import six
-
-# Own modules
-
-__version__ = '0.5.3'
-
-LOG = logging.getLogger(__name__)
-
-RE_YES = re.compile(r'^\s*(?:y(?:es)?|true)\s*$', re.IGNORECASE)
-RE_NO = re.compile(r'^\s*(?:no?|false|off)\s*$', re.IGNORECASE)
-PAT_TO_BOOL_TRUE = locale.nl_langinfo(locale.YESEXPR)
-RE_TO_BOOL_TRUE = re.compile(PAT_TO_BOOL_TRUE)
-PAT_TO_BOOL_FALSE = locale.nl_langinfo(locale.NOEXPR)
-RE_TO_BOOL_FALSE = re.compile(PAT_TO_BOOL_FALSE)
-
-RE_DOT = re.compile(r'\.')
-RE_DOT_AT_END = re.compile(r'(\.)*$')
-RE_DECIMAL = re.compile(r'^\d+$')
-RE_IPV4_PTR = re.compile(r'\.in-addr\.arpa\.$', re.IGNORECASE)
-RE_IPV6_PTR = re.compile(r'\.ip6\.arpa\.$', re.IGNORECASE)
-
-
-# =============================================================================
-def pp(value, indent=4, width=99, depth=None):
- """
- Returns a pretty print string of the given value.
-
- @return: pretty print string
- @rtype: str
- """
-
- pretty_printer = pprint.PrettyPrinter(
- indent=indent, width=width, depth=depth)
- return pretty_printer.pformat(value)
-
-
-# =============================================================================
-def terminal_can_colors(debug=False):
- """
- Method to detect, whether the current terminal (stdout and stderr)
- is able to perform ANSI color sequences.
-
- @return: both stdout and stderr can perform ANSI color sequences
- @rtype: bool
-
- """
-
- cur_term = ''
- if 'TERM' in os.environ:
- cur_term = os.environ['TERM'].lower().strip()
-
- colored_term_list = (
- r'ansi',
- r'linux.*',
- r'screen.*',
- r'[xeak]term.*',
- r'gnome.*',
- r'rxvt.*',
- r'interix',
- )
- term_pattern = r'^(?:' + r'|'.join(colored_term_list) + r')$'
- re_term = re.compile(term_pattern)
-
- ansi_term = False
- env_term_has_colors = False
-
- if cur_term:
- if cur_term == 'ansi':
- env_term_has_colors = True
- ansi_term = True
- elif re_term.search(cur_term):
- env_term_has_colors = True
- if debug:
- sys.stderr.write(
- "ansi_term: %r, env_term_has_colors: %r\n" % (
- ansi_term, env_term_has_colors))
-
- has_colors = False
- if env_term_has_colors:
- has_colors = True
- for handle in [sys.stdout, sys.stderr]:
- if (hasattr(handle, "isatty") and handle.isatty()):
- if debug:
- sys.stderr.write("%s is a tty.\n" % (handle.name))
- if (platform.system() == 'Windows' and not ansi_term):
- if debug:
- sys.stderr.write("platform is Windows and not ansi_term.\n")
- has_colors = False
- else:
- if debug:
- sys.stderr.write("%s is not a tty.\n" % (handle.name))
- if ansi_term:
- pass
- else:
- has_colors = False
-
- return has_colors
-
-
-# =============================================================================
-def to_bool(value):
- """
- Converter from string to boolean values (e.g. from configurations)
- """
-
- if not value:
- return False
-
- try:
- v_int = int(value)
- except ValueError:
- pass
- except TypeError:
- pass
- else:
- if v_int == 0:
- return False
- else:
- return True
-
- global PAT_TO_BOOL_TRUE
- global RE_TO_BOOL_TRUE
- global PAT_TO_BOOL_FALSE
- global RE_TO_BOOL_FALSE
-
- c_yes_expr = locale.nl_langinfo(locale.YESEXPR)
- if c_yes_expr != PAT_TO_BOOL_TRUE:
- PAT_TO_BOOL_TRUE = c_yes_expr
- RE_TO_BOOL_TRUE = re.compile(PAT_TO_BOOL_TRUE)
- # LOG.debug("Current pattern for 'yes': %r.", c_yes_expr)
-
- c_no_expr = locale.nl_langinfo(locale.NOEXPR)
- if c_no_expr != PAT_TO_BOOL_FALSE:
- PAT_TO_BOOL_FALSE = c_no_expr
- RE_TO_BOOL_FALSE = re.compile(PAT_TO_BOOL_FALSE)
- # LOG.debug("Current pattern for 'no': %r.", c_no_expr)
-
- v_str = ''
- if isinstance(value, str):
- v_str = value
- if six.PY2:
- if isinstance(value, unicode): # noqa
- v_str = value.encode('utf-8')
- elif six.PY3 and isinstance(value, bytes):
- v_str = value.decode('utf-8')
- else:
- v_str = str(value)
-
- match = RE_YES.search(v_str)
- if match:
- return True
- match = RE_TO_BOOL_TRUE.search(v_str)
- if match:
- return True
-
- match = RE_NO.search(v_str)
- if match:
- return False
- match = RE_TO_BOOL_FALSE.search(v_str)
- if match:
- return False
-
- return bool(value)
-
-
-# =============================================================================
-def to_unicode(obj, encoding='utf-8'):
-
- do_decode = False
- if six.PY2:
- if isinstance(obj, str):
- do_decode = True
- else:
- if isinstance(obj, bytes):
- do_decode = True
-
- if do_decode:
- obj = obj.decode(encoding)
-
- return obj
-
-
-# =============================================================================
-def to_utf8(obj):
-
- return encode_or_bust(obj, 'utf-8')
-
-
-# =============================================================================
-def encode_or_bust(obj, encoding='utf-8'):
-
- do_encode = False
- if six.PY2:
- if isinstance(obj, unicode): # noqa
- do_encode = True
- else:
- if isinstance(obj, str):
- do_encode = True
-
- if do_encode:
- obj = obj.encode(encoding)
-
- return obj
-
-
-# =============================================================================
-def to_bytes(obj, encoding='utf-8'):
- "Wrapper for encode_or_bust()"
-
- return encode_or_bust(obj, encoding)
-
-
-# =============================================================================
-def to_str(obj, encoding='utf-8'):
- """
- Transformes the given string-like object into the str-type according
- to the current Python version.
- """
-
- if six.PY2:
- return encode_or_bust(obj, encoding)
- else:
- return to_unicode(obj, encoding)
-
-
-# =============================================================================
-def caller_search_path():
- """
- Builds a search path for executables from environment $PATH
- including some standard paths.
-
- @return: all existing search paths
- @rtype: list
- """
-
- path_list = []
- search_path = os.environ['PATH']
- if not search_path:
- search_path = os.defpath
-
- search_path_list = [
- '/opt/PPlocal/bin',
- ]
-
- for d in search_path.split(os.pathsep):
- search_path_list.append(d)
-
- default_path = [
- '/bin',
- '/usr/bin',
- '/usr/local/bin',
- '/sbin',
- '/usr/sbin',
- '/usr/local/sbin',
- '/usr/ucb',
- '/usr/sfw/bin',
- '/opt/csw/bin',
- '/usr/openwin/bin',
- '/usr/ccs/bin',
- ]
-
- for d in default_path:
- search_path_list.append(d)
-
- for d in search_path_list:
- if not os.path.exists(d):
- continue
- if not os.path.isdir(d):
- continue
- d_abs = os.path.realpath(d)
- if d_abs not in path_list:
- path_list.append(d_abs)
-
- return path_list
-
-# =============================================================================
-def compare_fqdn(x, y):
-
- # LOG.debug("Comparing {!r} <=> {!r}.".format(x, y))
-
- # First check for None values
- if x is None and y is None:
- return 0
- if x is None:
- return -1
- if y is None:
- return 1
-
- # Check for empty FQDNs
- xs = str(x).strip().lower()
- ys = str(y).strip().lower()
-
- if xs == '' and ys == '':
- return 0
- if xs == '':
- return -1
- if ys == '':
- return 1
-
- # Ensure a dot at end
- xs = RE_DOT_AT_END.sub('.', xs)
- ys = RE_DOT_AT_END.sub('.', ys)
-
- if xs == ys:
- return 0
-
- # Reverse IPv4 zones first, then reverse IPv6 zones
- if RE_IPV4_PTR.search(xs):
- if not RE_IPV4_PTR.search(ys):
- return -1
- elif RE_IPV4_PTR.search(ys):
- if not RE_IPV4_PTR.search(xs):
- return 1
- elif RE_IPV6_PTR.search(xs):
- if not RE_IPV6_PTR.search(ys):
- return -1
- elif RE_IPV6_PTR.search(ys):
- if not RE_IPV6_PTR.search(xs):
- return 1
-
- return compare_fqdn_tokens(xs, ys)
-
-# =============================================================================
-def compare_fqdn_tokens(xs, ys):
-
- xa = RE_DOT.split(xs)
- xa.reverse()
- xa.pop(0)
-
- ya = RE_DOT.split(ys)
- ya.reverse()
- ya.pop(0)
-
- # Compare token from the last to the first
- nr_tokens = min(len(xa), len(ya))
- while nr_tokens > 0:
- token_x = xa.pop(0)
- token_y = ya.pop(0)
- if RE_DECIMAL.match(token_x) and RE_DECIMAL.match(token_y):
- num_x = int(token_x)
- num_y = int(token_y)
- if num_x < num_y:
- return -1
- elif num_x > num_y:
- return 1
- else:
- if token_x < token_y:
- return -1
- elif token_x > token_y:
- return 1
- nr_tokens -= 1
-
- if len(xa):
- return 1
- if len(ya):
- return -1
-
- return 0
-
-# =============================================================================
-
-if __name__ == "__main__":
-
- pass
-
-# =============================================================================
-
-# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-@author: Frank Brehm
-@summary: module for some common used error classes
-"""
-
-# Standard modules
-import errno
-
-
-__version__ = '0.1.1'
-
-# =============================================================================
-class PpError(Exception):
- """
- Base error class for all other self defined exceptions.
- """
-
- pass
-
-
-# =============================================================================
-class PpAppError(PpError):
-
- pass
-
-
-# =============================================================================
-class FunctionNotImplementedError(PpError, NotImplementedError):
- """
- Error class for not implemented functions.
- """
-
- # -------------------------------------------------------------------------
- def __init__(self, function_name, class_name):
- """
- Constructor.
-
- @param function_name: the name of the not implemented function
- @type function_name: str
- @param class_name: the name of the class of the function
- @type class_name: str
-
- """
-
- self.function_name = function_name
- if not function_name:
- self.function_name = '__unkown_function__'
-
- self.class_name = class_name
- if not class_name:
- self.class_name = '__unkown_class__'
-
- # -------------------------------------------------------------------------
- def __str__(self):
- """
- Typecasting into a string for error output.
- """
-
- msg = "Function {func}() has to be overridden in class {cls!r}."
- return msg.format(func=self.function_name, cls=self.class_name)
-
-
-# =============================================================================
-class IoTimeoutError(PpError, IOError):
- """
- Special error class indicating a timout error on a read/write operation
- """
-
- # -------------------------------------------------------------------------
- def __init__(self, strerror, timeout, filename=None):
- """
- Constructor.
-
- @param strerror: the error message about the operation
- @type strerror: str
- @param timeout: the timout in seconds leading to the error
- @type timeout: float
- @param filename: the filename leading to the error
- @type filename: str
-
- """
-
- t_o = None
- try:
- t_o = float(timeout)
- except ValueError:
- pass
- self.timeout = t_o
-
- if t_o is not None:
- strerror += " (timeout after {:0.1f} secs)".format(t_o)
-
- if filename is None:
- super(IoTimeoutError, self).__init__(errno.ETIMEDOUT, strerror)
- else:
- super(IoTimeoutError, self).__init__(
- errno.ETIMEDOUT, strerror, filename)
-
-
-# =============================================================================
-class ReadTimeoutError(IoTimeoutError):
- """
- Special error class indicating a timout error on reading of a file.
- """
-
- # -------------------------------------------------------------------------
- def __init__(self, timeout, filename):
- """
- Constructor.
-
- @param timeout: the timout in seconds leading to the error
- @type timeout: float
- @param filename: the filename leading to the error
- @type filename: str
-
- """
-
- strerror = "Timeout error on reading"
- super(ReadTimeoutError, self).__init__(strerror, timeout, filename)
-
-
-# =============================================================================
-class WriteTimeoutError(IoTimeoutError):
- """
- Special error class indicating a timout error on a writing into a file.
- """
-
- # -------------------------------------------------------------------------
- def __init__(self, timeout, filename):
- """
- Constructor.
-
- @param timeout: the timout in seconds leading to the error
- @type timeout: float
- @param filename: the filename leading to the error
- @type filename: str
-
- """
-
- strerror = "Timeout error on writing"
- super(WriteTimeoutError, self).__init__(strerror, timeout, filename)
-
-
-# =============================================================================
-
-if __name__ == "__main__":
- pass
-
-# =============================================================================
-
-# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4