mirror of
https://github.com/nicolargo/glances.git
synced 2024-12-27 19:25:27 +03:00
complete rewriting of the Web UI using bootstrap
fixes #461, #366 and #417
This commit is contained in:
parent
b4fd824168
commit
57eaefc3e8
59
glances/outputs/bottle/base.tpl
Normal file
59
glances/outputs/bottle/base.tpl
Normal file
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="{{refresh_time}}">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Glances</title>
|
||||
<link rel="stylesheet" type="text/css" href="normalize.css" />
|
||||
<link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<script src="modernizr.custom.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="pull-left">
|
||||
% include('plugin_text', plugin_name="system", stats=stats['system'])
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
% include('plugin_text', plugin_name="uptime", stats=stats['uptime'])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
% include('plugin_table', plugin_name="cpu", stats=stats['cpu'])
|
||||
</div>
|
||||
<div class="col-sm-3 col-lg-2 col-lg-offset-1">
|
||||
% include('plugin_table', plugin_name="load", stats=stats['load'])
|
||||
</div>
|
||||
<div class="col-sm-3 col-lg-3">
|
||||
% include('plugin_table', plugin_name="mem", stats=stats['mem'])
|
||||
</div>
|
||||
<div class="col-sm-3 col-lg-2 col-lg-offset-1">
|
||||
% include('plugin_table', plugin_name="memswap", stats=stats['memswap'])
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
% include('plugin_table', plugin_name="network", stats=stats['network'])
|
||||
% include('plugin_table', plugin_name="diskio", stats=stats['diskio'])
|
||||
% include('plugin_table', plugin_name="fs", stats=stats['fs'])
|
||||
% include('plugin_table', plugin_name="sensors", stats=stats['sensors'])
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
% include('plugin_table', plugin_name="alert", stats=stats['alert'])
|
||||
% include('plugin_text', plugin_name="processcount", stats=stats['processcount'])
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
% include('plugin_table', plugin_name="monitor", stats=stats['monitor'])
|
||||
</div>
|
||||
</div>
|
||||
% include('plugin_table', plugin_name="processlist", stats=stats['processlist'])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +0,0 @@
|
||||
</body>
|
||||
<footer>
|
||||
</footer>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE HTML><html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="{{refresh_time}}">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Glances</title>
|
||||
<link rel="stylesheet" type="text/css" href="normalize.css" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<script src="modernizr.custom.js"></script>
|
||||
</head>
|
||||
<body>
|
@ -1 +0,0 @@
|
||||
<div id="newline"></div>
|
30
glances/outputs/bottle/plugin_table.tpl
Normal file
30
glances/outputs/bottle/plugin_table.tpl
Normal file
@ -0,0 +1,30 @@
|
||||
% if stats['msgdict'] != []:
|
||||
<section id="{{ plugin_name }}" class="plugin">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
% for msg in stats['msgdict']:
|
||||
% if msg['msg'].startswith('\n'):
|
||||
</tr>
|
||||
<tr>
|
||||
% else:
|
||||
% if stats['display']:
|
||||
% if plugin_name == 'processlist':
|
||||
% if not msg['splittable'] or msg['splittable'] and msg['decoration'] == 'PROCESS':
|
||||
<td class="{{ msg['decoration'].lower() }}">
|
||||
{{ msg['msg'] }}
|
||||
</td>
|
||||
% end
|
||||
% else:
|
||||
<td class="{{ msg['decoration'].lower() }} {{ 'hidden-xs hidden-sm' if msg['optional'] else '' }}">
|
||||
{{ msg['msg'] }}
|
||||
</td>
|
||||
% end
|
||||
% end
|
||||
% end
|
||||
% end
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
% end
|
11
glances/outputs/bottle/plugin_text.tpl
Normal file
11
glances/outputs/bottle/plugin_text.tpl
Normal file
@ -0,0 +1,11 @@
|
||||
% if stats['msgdict'] != []:
|
||||
<section id="{{ plugin_name }}" class="plugin">
|
||||
% for msg in stats['msgdict']:
|
||||
% if stats['display']:
|
||||
<span class="{{ msg['decoration'].lower() }} {{ 'hidden-xs hidden-sm' if msg['optional'] else '' }}">
|
||||
{{ msg['msg'] }}
|
||||
</span>
|
||||
% end
|
||||
% end
|
||||
</section>
|
||||
% end
|
@ -56,27 +56,6 @@ class GlancesBottle(object):
|
||||
# Path where the statics files are stored
|
||||
self.STATIC_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static')
|
||||
|
||||
# Define the style (CSS) list (hash table) for stats
|
||||
self.__style_list = {
|
||||
'DEFAULT': '',
|
||||
'UNDERLINE': 'underline',
|
||||
'BOLD': 'bold',
|
||||
'SORT': 'sort',
|
||||
'OK': 'ok',
|
||||
'FILTER': 'filter',
|
||||
'TITLE': 'title',
|
||||
'CAREFUL': 'careful',
|
||||
'WARNING': 'warning',
|
||||
'CRITICAL': 'critical',
|
||||
'OK_LOG': 'ok_log',
|
||||
'CAREFUL_LOG': 'careful_log',
|
||||
'WARNING_LOG': 'warning_log',
|
||||
'CRITICAL_LOG': 'critical_log',
|
||||
'NICE': 'nice',
|
||||
'STATUS': 'status',
|
||||
'PROCESS': ''
|
||||
}
|
||||
|
||||
def _route(self):
|
||||
"""Define route."""
|
||||
self._app.route('/', method="GET", callback=self._index)
|
||||
@ -269,78 +248,23 @@ class GlancesBottle(object):
|
||||
|
||||
stats: Stats database to display
|
||||
"""
|
||||
html = template('header', refresh_time=refresh_time)
|
||||
html += '<header>'
|
||||
html += self.display_plugin('system', self.stats.get_plugin('system').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('uptime', self.stats.get_plugin('uptime').get_stats_display(args=self.args))
|
||||
html += '</header>'
|
||||
html += template('newline')
|
||||
html += '<section>'
|
||||
html += self.display_plugin('cpu', self.stats.get_plugin('cpu').get_stats_display(args=self.args))
|
||||
load_msg = self.stats.get_plugin('load').get_stats_display(args=self.args)
|
||||
if load_msg['msgdict'] != []:
|
||||
# Load is not available on all OS
|
||||
# Only display if stat is available
|
||||
html += self.display_plugin('load', load_msg)
|
||||
html += self.display_plugin('mem', self.stats.get_plugin('mem').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('memswap', self.stats.get_plugin('memswap').get_stats_display(args=self.args))
|
||||
html += '</section>'
|
||||
html += template('newline')
|
||||
html += '<div>'
|
||||
html += '<aside id="lefttstats">'
|
||||
html += self.display_plugin('network', self.stats.get_plugin('network').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('diskio', self.stats.get_plugin('diskio').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('fs', self.stats.get_plugin('fs').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('raid', self.stats.get_plugin('raid').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('sensors', self.stats.get_plugin('sensors').get_stats_display(args=self.args))
|
||||
html += '</aside>'
|
||||
html += '<section id="rightstats">'
|
||||
html += self.display_plugin('alert', self.stats.get_plugin('alert').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('processcount', self.stats.get_plugin('processcount').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('monitor', self.stats.get_plugin('monitor').get_stats_display(args=self.args))
|
||||
html += self.display_plugin('processlist', self.stats.get_plugin('processlist').get_stats_display(args=self.args))
|
||||
html += '</section>'
|
||||
html += '</div>'
|
||||
html += template('newline')
|
||||
html += template('footer')
|
||||
|
||||
return html
|
||||
stats = {
|
||||
'system': self.stats.get_plugin('system').get_stats_display(args=self.args),
|
||||
'uptime': self.stats.get_plugin('uptime').get_stats_display(args=self.args),
|
||||
'cpu': self.stats.get_plugin('cpu').get_stats_display(args=self.args),
|
||||
'load': self.stats.get_plugin('load').get_stats_display(args=self.args),
|
||||
'mem': self.stats.get_plugin('mem').get_stats_display(args=self.args),
|
||||
'memswap': self.stats.get_plugin('memswap').get_stats_display(args=self.args),
|
||||
'network': self.stats.get_plugin('network').get_stats_display(args=self.args),
|
||||
'diskio': self.stats.get_plugin('diskio').get_stats_display(args=self.args),
|
||||
'fs': self.stats.get_plugin('fs').get_stats_display(args=self.args),
|
||||
'raid': self.stats.get_plugin('raid').get_stats_display(args=self.args),
|
||||
'sensors': self.stats.get_plugin('sensors').get_stats_display(args=self.args),
|
||||
'alert': self.stats.get_plugin('alert').get_stats_display(args=self.args),
|
||||
'processcount': self.stats.get_plugin('processcount').get_stats_display(args=self.args),
|
||||
'monitor': self.stats.get_plugin('monitor').get_stats_display(args=self.args),
|
||||
'processlist': self.stats.get_plugin('processlist').get_stats_display(args=self.args)
|
||||
}
|
||||
|
||||
def display_plugin(self, plugin_name, plugin_stats):
|
||||
"""Generate the Bottle template for the plugin_stats."""
|
||||
# Template header
|
||||
tpl = """ \
|
||||
%#Template for Bottle
|
||||
"""
|
||||
tpl += '<article class="plugin" id="%s">' % plugin_name
|
||||
|
||||
tpl += '<div id="table">'
|
||||
tpl += '<div class="row">'
|
||||
for m in plugin_stats['msgdict']:
|
||||
# New line
|
||||
if m['msg'].startswith('\n'):
|
||||
tpl += '</div>'
|
||||
tpl += '<div class="row">'
|
||||
continue
|
||||
if plugin_name == 'processlist' and m['splittable']:
|
||||
# Processlist: Display first 20 chars of the process name
|
||||
if m['msg'].split(' ', 1)[0] != '':
|
||||
tpl += '<span class="cell" id="%s"> %s</span>' % \
|
||||
(self.__style_list[m['decoration']],
|
||||
m['msg'].split(' ', 1)[0].replace(' ', ' ')[:20])
|
||||
elif m['optional']:
|
||||
# Manage optional stats (responsive design)
|
||||
tpl += '<span class="cell hide" id="%s">%s</span>' % \
|
||||
(self.__style_list[m['decoration']], m['msg'].replace(' ', ' '))
|
||||
else:
|
||||
# Display stat
|
||||
tpl += '<span class="cell" id="%s">%s</span>' % \
|
||||
(self.__style_list[m['decoration']], m['msg'].replace(' ', ' '))
|
||||
tpl += '</div>'
|
||||
tpl += '</div>'
|
||||
|
||||
tpl += """ \
|
||||
</article>
|
||||
%#End Template for Bottle
|
||||
"""
|
||||
return template(tpl)
|
||||
return template('base', refresh_time=refresh_time, stats=stats)
|
||||
|
10
glances/outputs/static/css/bootstrap.min.css
vendored
Normal file
10
glances/outputs/static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -2,162 +2,93 @@ body {
|
||||
background: black;
|
||||
color: #BBB;
|
||||
font-family: "Lucida Sans Typewriter", "Lucida Console", Monaco, "Bitstream Vera Sans Mono", monospace;
|
||||
font-size: 100%;
|
||||
}
|
||||
header,footer,
|
||||
article,section,
|
||||
hgroup,nav,
|
||||
figure,div,aside {
|
||||
display: block;
|
||||
.plugin {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
section {
|
||||
text-align: justify;
|
||||
}
|
||||
section > article {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
*display: inline;
|
||||
zoom: 1;
|
||||
}
|
||||
section:after {
|
||||
content: "";
|
||||
.plugin table {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
aside {
|
||||
float: left;
|
||||
margin-right: 2%;
|
||||
.plugin table tr td:not(:first-child) {
|
||||
text-align: right;
|
||||
}
|
||||
div#newline{
|
||||
clear: both;
|
||||
height: 1em;
|
||||
}
|
||||
#underline{
|
||||
|
||||
.underline{
|
||||
text-decoration: underline
|
||||
}
|
||||
#bold{
|
||||
.bold{
|
||||
font-weight: bold;
|
||||
}
|
||||
#sort{
|
||||
.sort{
|
||||
font-weight: bold;
|
||||
}
|
||||
#sort:after{
|
||||
.sort:after{
|
||||
content: '\25BC'
|
||||
}
|
||||
/*Theme*/
|
||||
#title{
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Theme */
|
||||
|
||||
.title{
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
#table {
|
||||
display: table;
|
||||
}
|
||||
.row {
|
||||
display: table-row;
|
||||
}
|
||||
.cell {
|
||||
display: table-cell;
|
||||
}
|
||||
#ok {
|
||||
.ok {
|
||||
color: green;
|
||||
}
|
||||
#filter {
|
||||
.filter {
|
||||
color: cyan;
|
||||
}
|
||||
#ok_log {
|
||||
.ok_log {
|
||||
background-color: green;
|
||||
color: white;
|
||||
}
|
||||
#careful {
|
||||
.careful {
|
||||
color: blueviolet;
|
||||
}
|
||||
#careful_log {
|
||||
.careful_log {
|
||||
background-color: blueviolet;
|
||||
color: white;
|
||||
}
|
||||
#warning {
|
||||
.warning {
|
||||
color: orange;
|
||||
}
|
||||
#warning_log {
|
||||
.warning_log {
|
||||
background-color: orange;
|
||||
color: white;
|
||||
}
|
||||
#critical {
|
||||
.critical {
|
||||
color: red;
|
||||
}
|
||||
#critical_log {
|
||||
.critical_log {
|
||||
background-color: red;
|
||||
color: white;
|
||||
}
|
||||
#nice {
|
||||
.nice {
|
||||
color: magenta;
|
||||
}
|
||||
#status {
|
||||
.status {
|
||||
color: green;
|
||||
}
|
||||
/*Plugins*/
|
||||
#system {
|
||||
float: left;
|
||||
.process {
|
||||
color: green;
|
||||
}
|
||||
#uptime {
|
||||
float: right;
|
||||
|
||||
/* Plugins */
|
||||
#cpu table tr td:nth-child(3),
|
||||
#mem table tr td:nth-child(3),
|
||||
#monitor table tr td:nth-child(3) {
|
||||
text-align: left;
|
||||
padding-left: 20px;
|
||||
}
|
||||
#cpu {}
|
||||
#load {}
|
||||
#mem {}
|
||||
#memswap {}
|
||||
#leftstats {}
|
||||
#network {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
#diskio {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
#fs {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
#raid {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
#sensors {}
|
||||
#rightstats {}
|
||||
#alert {
|
||||
display: block;
|
||||
}
|
||||
#processcount {
|
||||
display: block;
|
||||
margin: 1em;
|
||||
}
|
||||
#monitor {
|
||||
display: block;
|
||||
margin: 1em;
|
||||
}
|
||||
#processlist {}
|
||||
/*
|
||||
article#processlist>div>div>span:last-child {
|
||||
visibility: hidden;
|
||||
#processlist table tr td {
|
||||
padding: 0px 5px 0px 5px;
|
||||
white-space: nowrap;
|
||||
text-align: right;
|
||||
}
|
||||
*/
|
||||
#now {}
|
||||
/*Responsive design*/
|
||||
@media only screen and (max-width: 1600px) {
|
||||
body { font-size:90%; }
|
||||
}
|
||||
@media only screen and (max-width: 1280px) {
|
||||
body { font-size:80%; }
|
||||
}
|
||||
@media only screen and (max-width: 1024px) {
|
||||
body { font-size:80%; }
|
||||
#processlist .hide { display: none; }
|
||||
}
|
||||
@media only screen and (max-width: 768px) {
|
||||
body { font-size:70%; }
|
||||
aside { margin-right: 1%; }
|
||||
.hide { display: none; }
|
||||
}
|
||||
@media only screen and (max-width: 480px) {
|
||||
body { font-size:60%; }
|
||||
aside { margin-right: 1%; }
|
||||
.hide { display: none; }
|
||||
}
|
||||
#processlist table tr td:nth-child(6),
|
||||
#processlist table tr td:nth-child(12) {
|
||||
text-align: left;
|
||||
}
|
Loading…
Reference in New Issue
Block a user