diff --git a/metrics b/metrics
index 3e51ea8..506fced 100755
--- a/metrics
+++ b/metrics
@@ -15,5 +15,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+from modules.jenkins import JenkinsModule
+
if __name__ == "__main__":
- print("Coming soon.")
+ jenkins = JenkinsModule()
+ print(jenkins.sqlite_setup())
+ print(jenkins.sqlite_add())
diff --git a/modules/__init__.py b/modules/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/modules/jenkins.py b/modules/jenkins.py
new file mode 100755
index 0000000..091d4ee
--- /dev/null
+++ b/modules/jenkins.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2020 Simon Quigley
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+from jenkinsapi.custom_exceptions import NoBuildData
+from jenkinsapi.jenkins import Jenkins
+from os import getenv
+
+class JenkinsModule:
+ """Jenkins module for the Metrics program"""
+
+ def _auth_jenkins_server(self):
+ """Authenticate to the Jenkins server
+
+ This uses the API_SITE, API_USER, and API_KEY env vars.
+ """
+ # Load the API values from the environment variables
+ api_site = getenv("API_SITE")
+ api_user = getenv("API_USER")
+ api_key = getenv("API_KEY")
+ for envvar in [api_site, api_user, api_key]:
+ if not envvar:
+ raise ValueError("API_SITE, API_USER, and API_KEY must be",
+ "defined")
+ # Authenticate to the server
+ server = Jenkins(api_site, username=api_user, password=api_key)
+
+ return server
+
+ def _get_data(self):
+ """Get the data from the Jenkins server
+
+ This function returns three distinct values as one list:
+
+ [nonpassing, failing, total]
+ """
+
+ # Authenticate to the server
+ server = self._auth_jenkins_server()
+
+ # Initialize the data, and get the total jobs on the server
+ data = [0, 0, len(server.jobs.keys())]
+
+ # jenkinsapi has a built-in method for iterating on jobs
+ # val will always be a jenkins Job class
+ for val in server.jobs.itervalues():
+ # If we come across a job that has no build, make it a SUCCESS
+ # The goal of this is to identify problematic jobs, and jobs with
+ # no existing builds aren't necessarily problematic (yet)
+ try:
+ status = val.get_last_build().get_status()
+ except NoBuildData:
+ status = "SUCCESS"
+
+ # If it's not successful, add it to nonpassing, since failing is
+ # reserved for jobs with the specific status of FAILURE
+ if status != "SUCCESS":
+ data[0] += 1
+
+ if status == "FAILURE":
+ data[1] += 1
+
+ return data
+
+ def sqlite_setup(self):
+ """Initially set up the table for usage in SQLite
+
+ This returns a str which will then be executed in our SQLite db
+
+ Here is the "jenkins" table layout:
+ - date is the primary key, and it is the Unix timestamp as an int
+ - nonpassing is the number of !(SUCCESS) jobs as an int
+ - failing is the number of FAILURE jobs as an int
+ - total is the total number of jobs on the Jenkins server as an int
+ """
+
+ command = "CREATE TABLE IF NOT EXISTS jenkins (date INTEGER PRIMARY "
+ command += "KEY, nonpassing INTEGER, failing INTEGER, total INTEGER);"
+
+ return command
+
+ def sqlite_add(self):
+ """Add data to the SQLite db
+
+ This retrieves the current data from the Jenkins server, and returns a
+ str which will then be executed in our SQLite db
+ """
+
+ # Match the variable names with the column names in the db
+ nonpassing, failing, total = self._get_data()
+ date = "strftime('%s', 'now')"
+
+
+ # Craft the str
+ command = "INSERT INTO jenkins VALUES ({}, {}, {}, {});".format(
+ date, nonpassing, failing, total)
+
+ return command