From 36ac2eb5fdf4c124ce14b7661d08fa7f75fa4b22 Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Fri, 19 Jun 2020 11:58:23 -0500 Subject: [PATCH] Add a very crude web view. --- .gitignore | 1 + metrics | 28 ++++++++----- modules/jenkins.py | 58 +++++++++++++++++++++++++- templates/jenkins.html | 92 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 templates/jenkins.html diff --git a/.gitignore b/.gitignore index a51c439..93ff3da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__ *.sqlite +output diff --git a/metrics b/metrics index a841a99..e325901 100755 --- a/metrics +++ b/metrics @@ -32,6 +32,7 @@ def sqlite_run(command, db, return_output=False): conn = sqlite3.connect(db) c = conn.cursor() for cmd in command: + log.debug("Executing: %s" % cmd) c.execute(cmd) conn.commit() @@ -48,16 +49,25 @@ def sqlite_run(command, db, return_output=False): def main(module): """Given a specific module, set it up and insert recent values""" + + # Initialize the module module = module() - run = [] - run.append(module.sqlite_setup()) - run.append(module.sqlite_add()) - #run.append(module.sqlite_time_range(days=10)) - log.debug("Commands to be ran: " + str(run)) - - # Use --db-location to pass to sqlite - log.info("Running SQLite commands") - log.debug(sqlite_run(run, db=args.db_location, return_output=True)) + + # Stage the setup commands to be ran and run them + run = [module.sqlite_setup(), module.sqlite_add()] + log.debug(sqlite_run(run, db=args.db_location)) + + # Pull some useful data and have the module render a template + # The output is in MODULENAME_DAYday.html + # This generates a report for each of the given day windows + for day in (1, 7, 30, 90, 180): + # Fetch the data and log to debug + run = [module.sqlite_time_range(days=day)] + data = sqlite_run(run, db=args.db_location, return_output=True) + log.debug(data) + + # Render the template + module.render_template(day, data) if __name__ == "__main__": diff --git a/modules/jenkins.py b/modules/jenkins.py index 494a601..9efd62f 100755 --- a/modules/jenkins.py +++ b/modules/jenkins.py @@ -20,7 +20,8 @@ import requests_cache import time from jenkinsapi.custom_exceptions import NoBuildData from jenkinsapi.jenkins import Jenkins -from os import getenv +from jinja2 import Template +from os import getenv, makedirs, path requests_cache.install_cache("jenkins", backend="sqlite", expire_after=300) @@ -131,3 +132,58 @@ class JenkinsModule: command = "SELECT * FROM jenkins WHERE date > %s;" % unix_time return command + + def render_template(self, days, data): + """Render a template with days in the filename, given the data + + The above function sqlite_time_range() is ran on the database with + some predetermined date ranges. This function actually interprets that + data, uses Jinja2 to magically render a template, and voila. + """ + + # Initialize a (softly) ephemeral dict to store data + jenkins = {} + _data = {"date": [], "nonpassing": [], "failing": [], "total": []} + + # Put the data from the DB query into _data + for row in data: + _data["date"].append(row[0]) + _data["nonpassing"].append(row[1]) + _data["failing"].append(row[2]) + _data["total"].append(row[3]) + + # Get human-readable averages and throw it in a dict + _nonpassing = sum(_data["nonpassing"]) / len(_data["nonpassing"]) + _nonpassing = format(_nonpassing, ".1f") + _failing = sum(_data["failing"]) / len(_data["failing"]) + _failing = format(_failing, ".1f") + _total = sum(_data["total"]) / len(_data["total"]) + _total = format(_total, ".1f") + average = {"nonpassing": _nonpassing, + "failing": _failing, + "total": _total} + + # Assign data to the dict Jinja2 is actually going to use + jenkins = {"nonpassing": zip(_data["date"], _data["nonpassing"]), + "failing": zip(_data["date"], _data["failing"]), + "total": zip(_data["date"], _data["total"])} + + # Grab our template from templates/ and store it as a Template + t_path = path.join("templates", "jenkins.html") + with open(t_path) as templatef: + template = "" + for text in templatef.readlines(): + template += text + template = Template(template) + + # Render the template + template = template.render(jenkins=jenkins, average=average, days=days) + + # Make the output dir if it doesn't already exist + if not path.exists("output"): + makedirs("output") + + # Write it back to the filename in the output dir + with open(path.join("output", "jenkins_%sdays.html" % days), + "w+") as f: + f.write(template) diff --git a/templates/jenkins.html b/templates/jenkins.html new file mode 100644 index 0000000..f9ee53f --- /dev/null +++ b/templates/jenkins.html @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+

Jenkins data for the past {{ days }} day(s)

+ +

Average number of failing jobs: {{ average.failing }}

+

Average number of non-passing jobs: {{ average.nonpassing }}

+

Average number of total jobs: {{ average.total }}

+
+
+
+ + + +