--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2017 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
+
+# Own modules
+
+__version__ = '0.2.0'
+
+log = logging.getLogger(__name__)
+
+# =============================================================================
+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_unicode(obj, encoding='utf-8'):
+
+ if isinstance(obj, bytes):
+ 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'):
+
+ if isinstance(obj, str):
+ 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.
+ """
+
+ return to_unicode(obj, encoding)
+
+
+
+# =============================================================================
+
+if __name__ == "__main__":
+
+ pass
+
+# =============================================================================
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2017 by Frank Brehm, Berlin
+@summary: The module for the application object.
+"""
+
+# Standard modules
+import sys
+import os
+import logging
+import re
+import textwrap
+import datetime
+
+# Own modules
+import webhooks
+
+
+__version__ = webhooks.__version__
+log = logging.getLogger(__name__)
+
+# =============================================================================
+class WebhookDeployApp(object):
+ """
+ Class for the application objects.
+ """
+
+ cgi_bin_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+ base_dir = os.path.dirname(cgi_bin_dir)
+
+ # -------------------------------------------------------------------------
+ def __init__(self, appname=None, version=__version__):
+ """Constructor."""
+
+ self._appname = None
+ """
+ @ivar: name of the current running application
+ @type: str
+ """
+ if appname:
+ v = str(appname).strip()
+ if v:
+ self._appname = v
+ if not self._appname:
+ self._appname = os.path.basename(sys.argv[0])
+
+ self._version = version
+ """
+ @ivar: version string of the current object or application
+ @type: str
+ """
+
+ self._verbose = 1
+ """
+ @ivar: verbosity level (0 - 9)
+ @type: int
+ """
+
+ self._log_directory = os.sep + os.path.join('var', 'log', 'webooks')
+
+ self.init_logging()
+
+ # -----------------------------------------------------------
+ @property
+ def appname(self):
+ """The name of the current running application."""
+ return self._appname
+
+ @appname.setter
+ def appname(self, value):
+ if value:
+ v = str(value).strip()
+ if v:
+ self._appname = v
+
+ # -----------------------------------------------------------
+ @property
+ def version(self):
+ """The version string of the current object or application."""
+ return self._version
+
+ # -----------------------------------------------------------
+ @property
+ def verbose(self):
+ """The verbosity level."""
+ return getattr(self, '_verbose', 0)
+
+ @verbose.setter
+ def verbose(self, value):
+ v = int(value)
+ if v >= 0:
+ self._verbose = v
+ else:
+ log.warn("Wrong verbose level %r, must be >= 0", value)
+
+ # -----------------------------------------------------------
+ @property
+ def log_directory(self):
+ """The directory containing the logfiles of this application."""
+ return self._log_directory
+
+ # -----------------------------------------------------------
+ @property
+ def logfile(self):
+ """The logfile of this application."""
+ return os.path.join(self.log_directory, self.appname + '.log')
+
+ # -------------------------------------------------------------------------
+ def init_logging(self):
+ """
+ Initialize the logger object.
+ It creates a colored loghandler with all output to STDERR.
+ Maybe overridden in descendant classes.
+
+ @return: None
+ """
+
+ root_log = logging.getLogger()
+ root_log.setLevel(logging.INFO)
+ if self.verbose:
+ root_log.setLevel(logging.DEBUG)
+
+ # create formatter
+ format_str = ''
+ if self.verbose > 1:
+ format_str = '[%(asctime)s]: '
+ format_str += self.appname + ': '
+ if self.verbose:
+ if self.verbose > 1:
+ format_str += '%(name)s(%(lineno)d) %(funcName)s() '
+ else:
+ format_str += '%(name)s '
+ format_str += '%(levelname)s - %(message)s'
+ formatter = logging.Formatter(format_str)
+
+ if 'REQUEST_METHOD' in os.environ:
+
+ # we are in a CGI environment
+ if os.path.is_dir(self.log_directory) and os.access(self.log_directory, os.W_OK):
+ lh_file = logging.FileHandler(
+ self.logfile, mode='a', encoding='utf-8', delay=True)
+ if self.verbose:
+ lh_file.setLevel(logging.DEBUG)
+ else:
+ lh_file.setLevel(logging.INFO)
+ lh_file.setFormatter(formatter)
+ root_log.addHandler(lh_file)
+
+ else:
+ # create log handler for console output
+ lh_console = logging.StreamHandler(sys.stderr)
+ if self.verbose:
+ lh_console.setLevel(logging.DEBUG)
+ else:
+ lh_console.setLevel(logging.INFO)
+ lh_console.setFormatter(formatter)
+
+ root_log.addHandler(lh_console)
+
+ return
+
+ # -------------------------------------------------------------------------
+ def __call__(self):
+ """Helper method to make the resulting object callable."""
+
+ log.info("Starting ...")
+ log.debug("Base directory: {!r}".format(self.base_dir))
+
+
+
+# =============================================================================
+
+if __name__ == "__main__":
+
+ pass
+
+# =============================================================================
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list