Please check the README file.
+diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1bb99d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.pyc
+.*.swp
+conf/servers.json
diff --git a/README.md b/README.md
index df9b82a..78a97a4 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,85 @@
-# monit-dashboard
- A web dashboard for rule all monit servers at a glance
+# Monit Dashboard
+
+## Description
+Python web application to get a dashboard of a bunch of [Monit][monit]
+servers at a glance.
+
+## How does it work?
+Every 300 seconds the application ask for the data served by the
+Monit built-in web server in a XMl report from each configured server.
+Then, thanks to the built-in web server, it is displayed in a single
+HTML page.
+
+## Pre requisites
+
+### Debian GNU/Linux
+
+#### Web.py framework
+- `apt install python-webpy`
+
+#### Python libraries
+- `apt install python-xmltodict python-requests`
+
+### CentOS
+
+#### Python PIP
+- `yum install epel-release`
+- `yum install python-pip`
+
+#### Web.py framework
+- `pip install web.py`
+
+#### Python libaries
+
+- `yum install python-requests python-xmltodict python-simplejson`
+
+## Requisites
+- Config file `conf/servers.json` prior run. You might find a sample
+file at `conf/servers.json.example`.
+- Please see [Config](#config) section for further details.
+
+## Run
+`./bin/monit-dashboard.py`
+
+By default, it will be reachable at http://localhost:8080. You might
+change the port by adjusting `app.run(port=8080)` in
+`bin/monit-dashboard.py` file.
+
+## References
+- [web.py 0.3 tutorial][webpy-tutorial]
+- [Learn Python the hard way, ex 50][lpthw]
+- [A template example][template-example]
+- [How to change HTTP server port][port]
+
+## Config
+- Placed in `conf/servers.json`
+- Sample settings as follows:
+```
+{
+ "My server to monit": {
+ "url": "http://example.com:2812",
+ "user": "monit",
+ "passwd": "*****"
+ }
+}
+```
+
+# Credits
+- [Original idea][idea]
+- Frontend support: Júlia Vázquez
+- [Icons][icons]
+- [Accordion menu][accordion]
+
+# License
+[AGPL][license]
+
+[monit]: https://mmonit.com/monit/
+[webpy]: http://webpy.org/
+[webpy-tutorial]: http://webpy.org/tutorial3.en
+[port]: https://stackoverflow.com/questions/14444913/web-py-specify-address-and-port
+[lpthw]: https://learnpythonthehardway.org/book/ex50.html
+[template-example]: https://stackoverflow.com/questions/28508869/using-web-py-to-dynamically-output-values-from-process-initiated-by-form-submiss
+[idea]: https://imil.net/blog/2016/03/16/Fetch-monit-status-in-JSON/
+[icons]: https://commons.wikimedia.org/wiki/User:House
+[accordion]: http://www.w3schools.com/howto/howto_js_accordion.asp
+[license]: LICENSE
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bin/monit-dashboard.py b/bin/monit-dashboard.py
new file mode 100755
index 0000000..c5dc05d
--- /dev/null
+++ b/bin/monit-dashboard.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+
+import web
+import requests, xmltodict, json, os, sys
+import datetime
+
+urls = ('/', 'index',
+ '/help', 'help'
+)
+
+app = web.application(urls, globals())
+render = web.template.render('templates/', base="layout")
+
+## Uncomment to turn debug off
+web.config.debug = False
+
+## Variables
+output = []
+
+## Functions
+
+def getMonit():
+ output = []
+ server = {}
+ checks = {}
+ xmlQuery = "/_status?format=xml"
+
+ with open('{0}/conf/servers.json'.format(os.path.expanduser('.'))) as f:
+ cf = json.loads(f.read())
+
+ for site in cf:
+ s = cf[site]
+ r = requests.get(s['url'] + xmlQuery, auth = (s['user'], s['passwd']))
+
+ allstat = json.loads(json.dumps(xmltodict.parse(r.text)['monit']))
+
+ services = allstat['service']
+ status = {}
+ checks = {}
+
+ for service in services:
+ name = service['name']
+ status[name] = int(service['status'])
+ checks[service['name']] = status[name]
+
+ server = dict(name = site, url = s['url'], result = checks)
+
+ output.append(server)
+
+ print(datetime.datetime.now())
+ return(output)
+
+## Classes
+
+class monitDashboard(web.application):
+ def run(self, port=8080, *middleware):
+ func = self.wsgifunc(*middleware)
+ return web.httpserver.runsimple(func, ('0.0.0.0', port))
+
+class index(object):
+ def GET(self):
+ return render.index(output = getMonit(), now = datetime.datetime.now())
+
+class help(object):
+ def GET(self):
+ return render.help()
+
+## Main
+if __name__ == "__main__":
+ app = monitDashboard(urls, globals())
+ app.run(port=8080)
diff --git a/conf/servers.json.example b/conf/servers.json.example
new file mode 100644
index 0000000..7cbdbe4
--- /dev/null
+++ b/conf/servers.json.example
@@ -0,0 +1,14 @@
+{
+ Server A": {
+ "url": "http://one.example.com:2812",
+ "user": "monit",
+ "passwd": "secret"
+ },
+
+ "Server B": {
+ "url": "http://two.example.com:2812",
+ "user": "monit",
+ "passwd": "secret"
+ }
+
+}
diff --git a/static/img/error.png b/static/img/error.png
new file mode 100644
index 0000000..5e52ae6
Binary files /dev/null and b/static/img/error.png differ
diff --git a/static/img/ok.png b/static/img/ok.png
new file mode 100644
index 0000000..2905a9b
Binary files /dev/null and b/static/img/ok.png differ
diff --git a/static/monit-dashboard.css b/static/monit-dashboard.css
new file mode 100644
index 0000000..8b11e3d
--- /dev/null
+++ b/static/monit-dashboard.css
@@ -0,0 +1,72 @@
+.server-link a {
+ color: #fff;
+ text-decoration: none;
+ text-transform: uppercase;
+ text-decoration: underline;
+}
+
+th {
+ background-color: #999;
+ padding: 10px;
+}
+
+td {
+ border-bottom: 1px solid #ccc;
+ padding: 15px;
+}
+
+body {
+ font-family: arial;
+}
+
+tr:nth-child(odd) {
+ background-color:#fff;
+}
+
+tr:nth-child(even) {
+ background-color:#f2f2f2;
+}
+
+a {
+ color: #cb0017;
+ font-weight: bolder;
+}
+
+button.accordion {
+ color: #444;
+ cursor: pointer;
+ padding: 18px;
+ width: 100%;
+ text-align: left;
+ border: none;
+ outline: none;
+ transition: 0.4s;
+}
+
+div.panel {
+ padding: 0 18px;
+ background-color: white;
+ display: none;
+}
+
+div.panel.show {
+ display: block;
+}
+
+.green {
+ background-color: #79bd8f;
+ font-size: 20px;
+}
+
+.green:hover {
+ background-color: #588a68;
+}
+
+.red {
+ background-color: #d9534f;
+ font-size: 20px;
+}
+
+.red:hover {
+ background-color: #c9302c;
+}
diff --git a/static/monit-dashboard.js b/static/monit-dashboard.js
new file mode 100644
index 0000000..f3d0746
--- /dev/null
+++ b/static/monit-dashboard.js
@@ -0,0 +1,9 @@
+var acc = document.getElementsByClassName("accordion");
+var i;
+
+for (i = 0; i < acc.length; i++) {
+ acc[i].onclick = function(){
+ this.classList.toggle("active");
+ this.nextElementSibling.classList.toggle("show");
+ }
+}
diff --git a/templates/help.html b/templates/help.html
new file mode 100644
index 0000000..ba5755f
--- /dev/null
+++ b/templates/help.html
@@ -0,0 +1,3 @@
+ Please check the README file.
+ $output[server]['name'] + | |
---|---|
$check | ++ |
$check | ++ |
+ $output[server]['name'] + | |
---|---|
$check | ++ |
$check | ++ |