]> Frank Brehm's Git Trees - pixelpark/puppetmaster-webhooks.git/commitdiff
Adding possibility to change output format
authorFrank Brehm <frank.brehm@pixelpark.com>
Fri, 24 Aug 2018 14:46:49 +0000 (16:46 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Fri, 24 Aug 2018 14:46:49 +0000 (16:46 +0200)
lib/webhooks/__init__.py
lib/webhooks/base_app.py
lib/webhooks/show_modules.py

index 7c3b277f320fbad540d0ae1bc5ea8f6d2a80752b..ed997e8c66182d1c9858119ad8c543db98839136 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/env python3
 # -*- coding: utf-8 -*-
 
-__version__ = '0.10.0'
+__version__ = '0.10.1'
 
 # vim: ts=4 et list
index 40e8b2fcce2a45ba3bc83f795d08f38858f7c6f7..e0f6cef5284a0afccd15fe60288a7cb96701dbd4 100644 (file)
@@ -19,6 +19,8 @@ import smtplib
 import argparse
 import traceback
 import io
+import cgi
+import textwrap
 
 from email.message import EmailMessage
 
@@ -70,6 +72,13 @@ class BaseHookApp(BaseObject):
 
     special_chars_re = re.compile(r'[^a-z0-9_\-]', re.IGNORECASE)
     dev_re = re.compile(r'^dev')
+    valid_output_types = {
+        'txt': 'text/plain',
+        'html': 'text/html',
+        'json': 'application/json',
+    }
+    default_output_type = 'txt'
+    default_mime_type = valid_output_types[default_output_type]
 
     # -------------------------------------------------------------------------
     def __init__(self, appname=None, base_dir=None, verbose=0, version=__version__):
@@ -84,12 +93,18 @@ class BaseHookApp(BaseObject):
         self.data_dir = self.default_data_dir
         self._read_stdin = True
         self.tz_name = self.default_tz_name
+        self._html_title = None
+
+        if not hasattr(self, '_output_type'):
+            self._output_type = self.default_output_type
+        self._mime_type = self.default_mime_type
 
         super(BaseHookApp, self).__init__(
             appname=appname, verbose=verbose, version=version,
             base_dir=base_dir, initialized=False,
         )
 
+        self._mime_type = self.valid_output_types[self.output_type]
         self._start_verbose = self.verbose
         self._simulate = False
 
@@ -102,6 +117,7 @@ class BaseHookApp(BaseObject):
         self.git_ssh_url = None
         self.do_sudo = True
         self.tz = None
+        self.query = {}
 
         self.cmdline_args = None
 
@@ -126,6 +142,10 @@ class BaseHookApp(BaseObject):
         self.do_arg_parser()
 
         self.read_config()
+
+        if self.cmdline_args.data_dir:
+            self._log_directory = self.data_dir
+
         self.init_logging()
         if 'REQUEST_METHOD' in os.environ:
             LOG.debug("We are in a CGI: REQUEST_METHOD {!r}".format(os.environ['REQUEST_METHOD']))
@@ -164,6 +184,14 @@ class BaseHookApp(BaseObject):
     def read_stdin(self, value):
         self._read_stdin = to_bool(value)
 
+    # -----------------------------------------------------------
+    @property
+    def html_title(self):
+        """Title of the generated HTML page, if output_type == 'html'."""
+        if self._html_title:
+            return self._html_title
+        return self.appname
+
     # -----------------------------------------------------------
     @property
     def log_directory(self):
@@ -191,6 +219,29 @@ class BaseHookApp(BaseObject):
             return None
         return os.path.join(self.puppet_envs_dir, cur_env)
 
+    # -----------------------------------------------------------
+    @property
+    def output_type(self):
+        """Typ der Ausgabe - TXT, HTML oder JSON."""
+        return getattr(self, '_output_type', self.default_output_type)
+
+    @output_type.setter
+    def output_type(self, value):
+        if not value:
+            raise ValueError("Invalid output type {!r}.".format(value))
+        val = str(value).strip().lower()
+        if val not in self.valid_output_types:
+            raise ValueError("Invalid output type {!r}.".format(value))
+
+        self._output_type = val
+        self._mime_type = self.valid_output_types[val]
+
+    # -----------------------------------------------------------
+    @property
+    def mime_type(self):
+        """MIME-Typ der Response."""
+        return self._mime_type
+
     # -------------------------------------------------------------------------
     def as_dict(self, short=True):
         """
@@ -213,6 +264,12 @@ class BaseHookApp(BaseObject):
         res['default_data_dir'] = self.default_data_dir
         res['read_stdin'] = self.read_stdin
         res['default_tz_name'] = self.default_tz_name
+        res['valid_output_types'] = self.valid_output_types
+        res['default_output_type'] = self.default_output_type
+        res['default_mime_type'] = self.default_mime_type
+        res['output_type'] = self.output_type
+        res['mime_type'] = self.mime_type
+        res['html_title'] = self.html_title
 
         return res
 
@@ -260,6 +317,11 @@ class BaseHookApp(BaseObject):
             help="Show program's version number and exit"
         )
 
+        arg_parser.add_argument(
+            'query', nargs='?',
+            help="An optional query string like on HTTP GET requests."
+        )
+
         self.cmdline_args = arg_parser.parse_args()
 
         if self.cmdline_args.usage:
@@ -282,10 +344,30 @@ class BaseHookApp(BaseObject):
             if not os.environ.get('REQUEST_METHOD', None):
                 os.environ['REQUEST_METHOD'] = 'GET'
 
+        if self.cmdline_args.query:
+            if not os.environ.get('QUERY_STRING', None):
+                os.environ['QUERY_STRING'] = self.cmdline_args.query
+
         if self.cmdline_args.simulate:
             sys.stderr.write("\nSimulation mode - nothing is really done.\n\n")
             self.simulate = True
 
+        self._get_query()
+        if 'output_type' in self.query:
+            try:
+                self.output_type = self.query['output_type']
+            except ValueError as e:
+                LOG.error(str(e))
+
+    # -------------------------------------------------------------------------
+    def _get_query(self):
+
+        self.query = {}
+        form = cgi.FieldStorage()
+        for key in form:
+            val = form.getvalue(key)
+            self.query[key] = val
+
     # -------------------------------------------------------------------------
     def search_curl_bin(self):
 
@@ -496,8 +578,11 @@ class BaseHookApp(BaseObject):
     def __call__(self):
         """Helper method to make the resulting object callable."""
 
-        self.print_out("Content-Type: text/plain;charset=utf-8\n")
-        self.print_out("Python CGI läuft.\n")
+        self.print_out("Content-Type: {};charset=utf-8\n".format(self.mime_type))
+        if self.output_type == 'txt':
+            self.print_out("Python CGI läuft.\n")
+        elif self.output_type == 'html':
+            self.print_htlm_start()
 
         if self.verbose > 1:
             LOG.debug("Base directory: {!r}".format(self.base_dir))
@@ -542,9 +627,30 @@ class BaseHookApp(BaseObject):
                 self.send_error_msgs(self.full_name)
             else:
                 self.send_error_msgs()
+            if self.output_type == 'html':
+                self.print_htlm_end()
             LOG.info("Finished.")
             sys.exit(0)
 
+    # -------------------------------------------------------------------------
+    def print_htlm_start(self):
+
+        html = textwrap.dedent('''\
+            <!doctype html>
+            <html lang="de">
+            <head>
+                <meta charset="utf-8">
+                <title>{t}</title>
+            </head>
+            <body>
+            ''').strip().format(t=self.html_title)
+        self.print_out(html)
+
+    # ------------------------------------------------------------------------
+    def print_htlm_end(self):
+
+        self.print_out('</body>\n</html>\n')
+
     # -------------------------------------------------------------------------
     def pre_run(self):
 
index da70f148ae9293c84f606ee42f4d0ab4bdd7c22d..e4a194e1c245926a3cbdfb21581f3fe18608e96a 100644 (file)
@@ -14,6 +14,7 @@ import os
 import logging
 import textwrap
 import copy
+import json
 
 # Third party modules
 
@@ -44,10 +45,13 @@ class ShowModulesApp(BaseHookApp):
             ''').strip()
 
         self.cache_file = None
+        self._output_type = 'json'
 
         super(ShowModulesApp, self).__init__(
             appname=appname, verbose=verbose, version=version)
 
+        self._html_title = "All Puppet modules."
+
 #    # -------------------------------------------------------------------------
 #    def as_dict(self, short=True):
 #        """
@@ -78,7 +82,13 @@ class ShowModulesApp(BaseHookApp):
     def run(self):
         """Main routine."""
 
-        self.print_out("Hallo!")
+        if self.output_type == 'txt':
+            self.print_out("Hallo!")
+        elif self.output_type == 'json':
+            data = {'msg': self.html_title}
+            self.print_out(json.dumps(data))
+        elif self.output_type == 'html':
+            self.print_out('<h1>{t}</h1>'.format(t=self.html_title))
 
 # =============================================================================