]> Frank Brehm's Git Trees - pixelpark/create-vmware-tpl.git/commitdiff
Adding lib/cr_vmware_tpl/common.py
authorFrank Brehm <frank.brehm@pixelpark.com>
Tue, 20 Mar 2018 13:38:01 +0000 (14:38 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Tue, 20 Mar 2018 13:38:01 +0000 (14:38 +0100)
lib/cr_vmware_tpl/common.py [new file with mode: 0644]

diff --git a/lib/cr_vmware_tpl/common.py b/lib/cr_vmware_tpl/common.py
new file mode 100644 (file)
index 0000000..e0d7729
--- /dev/null
@@ -0,0 +1,387 @@
+#!/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