v1.10.2.2

More AJAX!!!!
pull/19/head
Aidaho12 2018-04-10 09:58:56 +06:00
parent 8266f8a93e
commit b6624d91f8
11 changed files with 677 additions and 126 deletions

View File

@ -64,11 +64,8 @@ if form.getvalue('serv') is not None and form.getvalue('open') is not None :
print('</select>') print('</select>')
print('<input type="hidden" value="%s" name="serv">' % serv) print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="open" name="open">') print('<input type="hidden" value="open" name="open">')
print('<button type="submit" value="Compare" name="Compare">Compare</button></p></form></center>') print('<a class="ui-button ui-widget ui-corner-all" id="show" title="Compare" onclick="showCompare()">Show</a></p></form></center></center><div id=ajax></div>')
if form.getvalue('serv') is not None and form.getvalue('right') is not None:
commands = [ 'diff -ub %s%s %s%s' % (hap_configs_dir, left, hap_configs_dir, right) ]
funct.ssh_command(haproxy_configs_server, commands, compare="1")
funct.footer() funct.footer()

View File

@ -1,63 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html
import cgi import cgi
import listserv as listhap
import subprocess
import os
import http.cookies
import funct import funct
import configparser
from funct import head as head
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv') serv = form.getvalue('serv')
action = form.getvalue('servaction')
backend = form.getvalue('servbackend')
head("Runtime API")
funct.head("Runtime API")
funct.check_login() funct.check_login()
funct.check_config() funct.check_config()
path_config = "haproxy-webintarface.config"
config = configparser.ConfigParser()
config.read(path_config)
server_state_file = config.get('haproxy', 'server_state_file')
haproxy_sock = config.get('haproxy', 'haproxy_sock')
if backend is None:
backend = ""
autofocus = ""
else:
autofocus = "autofocus"
if action == 'disable':
selected1 = 'selected'
selected2 = ''
selected3 = ''
selected4 = ''
elif action == 'enable':
selected1 = ''
selected2 = 'selected'
selected3 = ''
selected4 = ''
elif action == 'set':
selected1 = ''
selected2 = ''
selected3 = 'selected'
selected4 = ''
elif action == 'show':
selected1 = ''
selected2 = ''
selected3 = ''
selected4 = 'selected'
else:
selected1 = ''
selected2 = ''
selected3 = ''
selected4 = ''
print('<h2>Runtime API</h2>' print('<h2>Runtime API</h2>'
'<table class="overview">' '<table class="overview">'
'<tr class="overviewHead">' '<tr class="overviewHead">'
@ -70,45 +22,30 @@ print('<h2>Runtime API</h2>'
'<tr>' '<tr>'
'<td class="padding10" style="width: 25%;">' '<td class="padding10" style="width: 25%;">'
'<form action="edit.py" method="get">' '<form action="edit.py" method="get">'
'<select required name="serv">' '<select required name="serv" id="serv">'
'<option disabled selected>Choose server</option>') '<option disabled selected>Choose server</option>')
funct.choose_server_with_vip(serv) funct.choose_server_with_vip(serv)
print('</select></td>' print('</select></td>'
'<td style="width: 30%;">' '<td style="width: 30%;">'
'<select required name="servaction">' '<select required name="servaction" id="servaction">'
'<option disabled selected>Choose action</option>') '<option disabled selected>Choose action</option>')
if funct.is_admin(): if funct.is_admin():
print('<option value="disable" %s>Disable</option>' % selected1) print('<option value="disable">Disable</option>')
print('<option value="enable" %s>Enable</option>' % selected2) print('<option value="enable">Enable</option>')
print('<option value="set" %s>Set</option>' % selected3) print('<option value="set">Set</option>')
print('<option value="show" %s>Show</option>' % selected4) print('<option value="show">Show</option>'
print('</select></td>') '</select></td>'
print('<td><input type="text" name="servbackend" size=35 title="Frontend, backend/server, show: info, pools or help" required class="form-control" value="%s" %s>' % (backend, autofocus)) '<td>'
'<input type="text" name="servbackend" id="servbackend" size=35 title="Frontend, backend/server, show: info, pools or help" required class="form-control">'
print('</td><td>' '</td><td>'
'<input type="checkbox" name="save" title="Save changes after restart">' '<input type="checkbox" name="save" id="save" value="123" title="Save changes after restart">'
'</td><td>') '</td><td>'
funct.get_button("Enter") '<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="showRuntime()">Show</a>'
print('</td></form>' '</td></form>'
'</tr></table>') '</tr></table>'
'<div id="ajax">'
if form.getvalue('servaction') is not None: '</div>')
enable = form.getvalue('servaction')
cmd='echo "%s %s" |socat stdio %s | cut -d "," -f 1-2,5-10,34-36 | column -s, -t' % (enable, backend, haproxy_sock)
if form.getvalue('save') == "on":
save_command = 'echo "show servers state" | socat stdio %s > %s' % (haproxy_sock, server_state_file)
command = [ cmd, save_command ]
else:
command = [ cmd ]
if enable != "show":
print('<center><h3>You %s %s on HAproxy %s. <a href="viewsttats.py?serv=%s" title="View stat" target="_blank">Look it</a> or <a href="edit.py" title="Edit">Edit something else</a></h3><br />' % (enable, backend, serv, serv))
funct.ssh_command(serv, command, show_log="1")
action = 'edit.py ' + enable + ' ' + backend
funct.logging(serv, action)
funct.footer() funct.footer()

View File

@ -22,6 +22,8 @@ path_config = "haproxy-webintarface.config"
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(path_config) config.read(path_config)
form = cgi.FieldStorage()
serv = form.getvalue('serv')
fullpath = config.get('main', 'fullpath') fullpath = config.get('main', 'fullpath')
ssh_keys = config.get('ssh', 'ssh_keys') ssh_keys = config.get('ssh', 'ssh_keys')
ssh_user_name = config.get('ssh', 'ssh_user_name') ssh_user_name = config.get('ssh', 'ssh_user_name')
@ -121,11 +123,13 @@ def head(title):
'<link href="/inc/awesome.css" rel="stylesheet">' '<link href="/inc/awesome.css" rel="stylesheet">'
'<link href="/inc/vertical_scrol/custom_scrollbar.css" rel="stylesheet">' '<link href="/inc/vertical_scrol/custom_scrollbar.css" rel="stylesheet">'
'<link href="/inc/style.css" rel="stylesheet">' '<link href="/inc/style.css" rel="stylesheet">'
'<link href="/inc/nprogress.css" rel="stylesheet">'
'<link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">' '<link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">'
'<script src="https://code.jquery.com/jquery-1.12.4.js"></script>' '<script src="https://code.jquery.com/jquery-1.12.4.js"></script>'
'<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>' '<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>'
'<script src="/inc/js-cookie.js"></script>' '<script src="/inc/js-cookie.js"></script>'
'<script src="/inc/script.js"></script>' '<script src="/inc/script.js"></script>'
'<script src="/inc/nprogress.js"></script>'
'<script src="/inc/vertical_scrol/custom_scrollbar.min.js"></script>' '<script src="/inc/vertical_scrol/custom_scrollbar.min.js"></script>'
'</head>' '</head>'
'<body>' '<body>'
@ -140,7 +144,7 @@ def head(title):
'<div class="top-menu">' '<div class="top-menu">'
'<div class="LogoText">' '<div class="LogoText">'
'<span style="padding: 10px;">HAproxy-WI</span>' '<span style="padding: 10px;">HAproxy-WI</span>'
'<a href="#" id="hide_menu" title="Hide menu" style="margin-left: 7px;margin-top: -6px;position: absolute;">' '<a href="#" id="hide_menu" title="Hide menu" style="margin-left: 16px;margin-top: -10px;position: absolute;">'
'<span class="ui-state-default ui-corner-all">' '<span class="ui-state-default ui-corner-all">'
'<span class="ui-icon ui-icon-arrowthick-1-w" id="arrow"></span>' '<span class="ui-icon ui-icon-arrowthick-1-w" id="arrow"></span>'
'</span>' '</span>'
@ -186,7 +190,7 @@ def links():
show_login_links() show_login_links()
print('</ul>' print('</ul>'
'</nav>' '</nav>'
'<div class="copyright-menu">HAproxy-WI v1.10.2.1</div>') '<div class="copyright-menu">HAproxy-WI v1.10.2.2</div>')
def show_login_links(): def show_login_links():
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
@ -546,16 +550,14 @@ def choose_only_select(serv, **kwargs):
print('<option value="%s" %s>%s</option>' % (listhap.get(i), selected, i)) print('<option value="%s" %s>%s</option>' % (listhap.get(i), selected, i))
def chooseServer(formName, title, note): def chooseServer(formName, title, note):
servNew = form.getvalue('serNew')
print('<h2>' + title + '</h2><center>') print('<h2>' + title + '</h2><center>')
print('<h3>Choose server</h3>') print('<h3>Choose server</h3>')
print('<form action=' + formName + ' method="get">') print('<form action=' + formName + ' method="get">')
print('<p><select autofocus required name="serv" id="chooseServer">') print('<p><select autofocus required name="serv" id="serv">')
print('<option disabled>Choose server</option>') print('<option disabled>Choose server</option>')
form = cgi.FieldStorage()
serv = form.getvalue('serv')
servNew = form.getvalue('serNew')
choose_only_select(serv, servNew=servNew) choose_only_select(serv, servNew=servNew)
print('</select>') print('</select>')

View File

@ -2,8 +2,6 @@
import html import html
import cgi import cgi
import listserv as listhap import listserv as listhap
import subprocess
import os
import funct import funct
import configparser import configparser
@ -47,20 +45,13 @@ else:
grep = ' ' grep = ' '
print('</td><td><input type="number" name="rows" id="rows" %s class="form-control" required></td>' % rows) print('</td><td><input type="number" name="rows" id="rows" %s class="form-control" required></td>' % rows)
print('<td><input type="text" name="grep" id="grep" class="form-control" %s >' % grep) print('<td class="padding10"><input type="text" name="grep" id="grep" class="form-control" %s >' % grep)
print('</td>' print('</td>'
'<td class="padding10" >' '<td class="padding10">'
'<span id="loading" class="fa fa-spinner fa-spin"></span>' '<a class="ui-button ui-widget ui-corner-all" id="show" title="Show logs" onclick="showLog()">Show</a>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show logs" onclick="showLog()">Show</a>') '</td>'
if form.getvalue('serv') is not None: '</form>'
print('<span style="float: right; margin-top: 8px;">' '</tr></table>'
'<a href="" title="Update logs" id="update">'
'<img alt="Update" src="/image/pic/update.png" style="max-width: 20px;">'
'</a>'
'</span>')
print('</td>'
'</form>'
'</tr></table>'
'<div id="ajax">' '<div id="ajax">'
'</div>') '</div>')
funct.footer() funct.footer()

View File

@ -11,6 +11,7 @@ options = [ "acl", "http-request", "http-response", "set-uri", "set-url", "set-h
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(path_config) config.read(path_config)
funct.check_config()
form = cgi.FieldStorage() form = cgi.FieldStorage()
req = form.getvalue('req') req = form.getvalue('req')
@ -122,6 +123,34 @@ if form.getvalue('act') == "overview":
import ovw import ovw
ovw.get_overview() ovw.get_overview()
if form.getvalue('servaction') is not None:
server_state_file = config.get('haproxy', 'server_state_file')
haproxy_sock = config.get('haproxy', 'haproxy_sock')
enable = form.getvalue('servaction')
cmd='echo "%s %s" |socat stdio %s | cut -d "," -f 1-2,5-10,34-36 | column -s, -t' % (enable, backend, haproxy_sock)
if form.getvalue('save') == "on":
save_command = 'echo "show servers state" | socat stdio %s > %s' % (haproxy_sock, server_state_file)
command = [ cmd, save_command ]
else:
command = [ cmd ]
if enable != "show":
print('<center><h3>You %s %s on HAproxy %s. <a href="viewsttats.py?serv=%s" title="View stat" target="_blank">Look it</a> or <a href="edit.py" title="Edit">Edit something else</a></h3><br />' % (enable, backend, serv, serv))
funct.ssh_command(serv, command, show_log="1")
action = 'edit.py ' + enable + ' ' + backend
funct.logging(serv, action)
if serv is not None and form.getvalue('right') is not None:
left = form.getvalue('left')
right = form.getvalue('right')
haproxy_configs_server = config.get('configs', 'haproxy_configs_server')
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
commands = [ 'diff -ub %s%s %s%s' % (hap_configs_dir, left, hap_configs_dir, right) ]
funct.ssh_command(haproxy_configs_server, commands, compare="1")
if form.getvalue('tailf_stop') is not None: if form.getvalue('tailf_stop') is not None:
serv = form.getvalue('serv') serv = form.getvalue('serv')
commands = [ "ps ax |grep python3 |grep -v grep |awk '{ print $1 }' |xargs kill" ] commands = [ "ps ax |grep python3 |grep -v grep |awk '{ print $1 }' |xargs kill" ]

View File

@ -59,11 +59,6 @@ def get_overview():
'<td>' '<td>'
'Last edit' 'Last edit'
'</td>' '</td>'
'<td>'
'<a href="" title="Update status" id="update">'
'<img alt="Update" src="/image/pic/update.png" class="icon" style="padding-right: 8px; float: right">'
'</a></span>'
'</td>'
'</tr>') '</tr>')
listhap = funct.get_dick_after_permit() listhap = funct.get_dick_after_permit()
@ -94,11 +89,6 @@ def get_overview():
'</td>' '</td>'
'<td>' '<td>'
'Server status' 'Server status'
'<span style="float: right; margin-left: 80&;">'
'<a href="" title="Update status" id="update">'
'<img alt="Update" src="/image/pic/update.png" class="icon" style="padding-right: 8px; float: right">'
'</a>'
'</span>'
'</td>' '</td>'
'</tr>') '</tr>')
print('</td></tr>') print('</td></tr>')

View File

@ -58,8 +58,7 @@ print('<br />'
funct.choose_server_with_vip(serv) funct.choose_server_with_vip(serv)
print('</select>' print('</select>'
'<span id="loading" class="fa fa-spinner fa-spin"></span>' '<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="showStats()">Show</a>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show logs" onclick="showStats()">Show</a>'
'</form>') '</form>')
data = response.content data = response.content

62
inc/nprogress.css Normal file
View File

@ -0,0 +1,62 @@
/* Make clicks pass-through */
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: #fff;
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 3px;
}
/* Fancy blur effect */
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #29d, 0 0 5px #29d;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
/* Remove these to get rid of the spinner */
#nprogress .spinner {
display: block;
position: fixed;
z-index: 1031;
top: 15px;
right: 55px;
}
#nprogress .spinner-icon {
width: 18px;
height: 18px;
box-sizing: border-box;
border: solid 2px transparent;
border-top-color: #fff;
border-left-color: #fff;
border-radius: 50%;
-webkit-animation: nprogress-spinner 400ms linear infinite;
animation: nprogress-spinner 400ms linear infinite;
}
.nprogress-custom-parent {
overflow: hidden;
position: relative;
}
.nprogress-custom-parent #nprogress .spinner,
.nprogress-custom-parent #nprogress .bar {
position: absolute;
}
@-webkit-keyframes nprogress-spinner {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes nprogress-spinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

480
inc/nprogress.js Normal file
View File

@ -0,0 +1,480 @@
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
* @license MIT */
;(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory);
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
root.NProgress = factory();
}
})(this, function() {
var NProgress = {};
NProgress.version = '0.2.0';
var Settings = NProgress.settings = {
minimum: 0.08,
easing: 'linear',
positionUsing: '',
speed: 200,
trickle: true,
trickleSpeed: 200,
showSpinner: true,
barSelector: '[role="bar"]',
spinnerSelector: '[role="spinner"]',
parent: 'body',
template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
};
/**
* Updates configuration.
*
* NProgress.configure({
* minimum: 0.1
* });
*/
NProgress.configure = function(options) {
var key, value;
for (key in options) {
value = options[key];
if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
}
return this;
};
/**
* Last number.
*/
NProgress.status = null;
/**
* Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
*
* NProgress.set(0.4);
* NProgress.set(1.0);
*/
NProgress.set = function(n) {
var started = NProgress.isStarted();
n = clamp(n, Settings.minimum, 1);
NProgress.status = (n === 1 ? null : n);
var progress = NProgress.render(!started),
bar = progress.querySelector(Settings.barSelector),
speed = Settings.speed,
ease = Settings.easing;
progress.offsetWidth; /* Repaint */
queue(function(next) {
// Set positionUsing if it hasn't already been set
if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
// Add transition
css(bar, barPositionCSS(n, speed, ease));
if (n === 1) {
// Fade out
css(progress, {
transition: 'none',
opacity: 1
});
progress.offsetWidth; /* Repaint */
setTimeout(function() {
css(progress, {
transition: 'all ' + speed + 'ms linear',
opacity: 0
});
setTimeout(function() {
NProgress.remove();
next();
}, speed);
}, speed);
} else {
setTimeout(next, speed);
}
});
return this;
};
NProgress.isStarted = function() {
return typeof NProgress.status === 'number';
};
/**
* Shows the progress bar.
* This is the same as setting the status to 0%, except that it doesn't go backwards.
*
* NProgress.start();
*
*/
NProgress.start = function() {
if (!NProgress.status) NProgress.set(0);
var work = function() {
setTimeout(function() {
if (!NProgress.status) return;
NProgress.trickle();
work();
}, Settings.trickleSpeed);
};
if (Settings.trickle) work();
return this;
};
/**
* Hides the progress bar.
* This is the *sort of* the same as setting the status to 100%, with the
* difference being `done()` makes some placebo effect of some realistic motion.
*
* NProgress.done();
*
* If `true` is passed, it will show the progress bar even if its hidden.
*
* NProgress.done(true);
*/
NProgress.done = function(force) {
if (!force && !NProgress.status) return this;
return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
};
/**
* Increments by a random amount.
*/
NProgress.inc = function(amount) {
var n = NProgress.status;
if (!n) {
return NProgress.start();
} else if(n > 1) {
return;
} else {
if (typeof amount !== 'number') {
if (n >= 0 && n < 0.2) { amount = 0.1; }
else if (n >= 0.2 && n < 0.5) { amount = 0.04; }
else if (n >= 0.5 && n < 0.8) { amount = 0.02; }
else if (n >= 0.8 && n < 0.99) { amount = 0.005; }
else { amount = 0; }
}
n = clamp(n + amount, 0, 0.994);
return NProgress.set(n);
}
};
NProgress.trickle = function() {
return NProgress.inc();
};
/**
* Waits for all supplied jQuery promises and
* increases the progress as the promises resolve.
*
* @param $promise jQUery Promise
*/
(function() {
var initial = 0, current = 0;
NProgress.promise = function($promise) {
if (!$promise || $promise.state() === "resolved") {
return this;
}
if (current === 0) {
NProgress.start();
}
initial++;
current++;
$promise.always(function() {
current--;
if (current === 0) {
initial = 0;
NProgress.done();
} else {
NProgress.set((initial - current) / initial);
}
});
return this;
};
})();
/**
* (Internal) renders the progress bar markup based on the `template`
* setting.
*/
NProgress.render = function(fromStart) {
if (NProgress.isRendered()) return document.getElementById('nprogress');
addClass(document.documentElement, 'nprogress-busy');
var progress = document.createElement('div');
progress.id = 'nprogress';
progress.innerHTML = Settings.template;
var bar = progress.querySelector(Settings.barSelector),
perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
parent = document.querySelector(Settings.parent),
spinner;
css(bar, {
transition: 'all 0 linear',
transform: 'translate3d(' + perc + '%,0,0)'
});
if (!Settings.showSpinner) {
spinner = progress.querySelector(Settings.spinnerSelector);
spinner && removeElement(spinner);
}
if (parent != document.body) {
addClass(parent, 'nprogress-custom-parent');
}
parent.appendChild(progress);
return progress;
};
/**
* Removes the element. Opposite of render().
*/
NProgress.remove = function() {
removeClass(document.documentElement, 'nprogress-busy');
removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');
var progress = document.getElementById('nprogress');
progress && removeElement(progress);
};
/**
* Checks if the progress bar is rendered.
*/
NProgress.isRendered = function() {
return !!document.getElementById('nprogress');
};
/**
* Determine which positioning CSS rule to use.
*/
NProgress.getPositioningCSS = function() {
// Sniff on document.body.style
var bodyStyle = document.body.style;
// Sniff prefixes
var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
('MozTransform' in bodyStyle) ? 'Moz' :
('msTransform' in bodyStyle) ? 'ms' :
('OTransform' in bodyStyle) ? 'O' : '';
if (vendorPrefix + 'Perspective' in bodyStyle) {
// Modern browsers with 3D support, e.g. Webkit, IE10
return 'translate3d';
} else if (vendorPrefix + 'Transform' in bodyStyle) {
// Browsers without 3D support, e.g. IE9
return 'translate';
} else {
// Browsers without translate() support, e.g. IE7-8
return 'margin';
}
};
/**
* Helpers
*/
function clamp(n, min, max) {
if (n < min) return min;
if (n > max) return max;
return n;
}
/**
* (Internal) converts a percentage (`0..1`) to a bar translateX
* percentage (`-100%..0%`).
*/
function toBarPerc(n) {
return (-1 + n) * 100;
}
/**
* (Internal) returns the correct CSS for changing the bar's
* position given an n percentage, and speed and ease from Settings
*/
function barPositionCSS(n, speed, ease) {
var barCSS;
if (Settings.positionUsing === 'translate3d') {
barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
} else if (Settings.positionUsing === 'translate') {
barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
} else {
barCSS = { 'margin-left': toBarPerc(n)+'%' };
}
barCSS.transition = 'all '+speed+'ms '+ease;
return barCSS;
}
/**
* (Internal) Queues a function to be executed.
*/
var queue = (function() {
var pending = [];
function next() {
var fn = pending.shift();
if (fn) {
fn(next);
}
}
return function(fn) {
pending.push(fn);
if (pending.length == 1) next();
};
})();
/**
* (Internal) Applies css properties to an element, similar to the jQuery
* css method.
*
* While this helper does assist with vendor prefixed property names, it
* does not perform any manipulation of values prior to setting styles.
*/
var css = (function() {
var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
cssProps = {};
function camelCase(string) {
return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
return letter.toUpperCase();
});
}
function getVendorProp(name) {
var style = document.body.style;
if (name in style) return name;
var i = cssPrefixes.length,
capName = name.charAt(0).toUpperCase() + name.slice(1),
vendorName;
while (i--) {
vendorName = cssPrefixes[i] + capName;
if (vendorName in style) return vendorName;
}
return name;
}
function getStyleProp(name) {
name = camelCase(name);
return cssProps[name] || (cssProps[name] = getVendorProp(name));
}
function applyCss(element, prop, value) {
prop = getStyleProp(prop);
element.style[prop] = value;
}
return function(element, properties) {
var args = arguments,
prop,
value;
if (args.length == 2) {
for (prop in properties) {
value = properties[prop];
if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
}
} else {
applyCss(element, args[1], args[2]);
}
}
})();
/**
* (Internal) Determines if an element or space separated list of class names contains a class name.
*/
function hasClass(element, name) {
var list = typeof element == 'string' ? element : classList(element);
return list.indexOf(' ' + name + ' ') >= 0;
}
/**
* (Internal) Adds a class to an element.
*/
function addClass(element, name) {
var oldList = classList(element),
newList = oldList + name;
if (hasClass(oldList, name)) return;
// Trim the opening space.
element.className = newList.substring(1);
}
/**
* (Internal) Removes a class from an element.
*/
function removeClass(element, name) {
var oldList = classList(element),
newList;
if (!hasClass(element, name)) return;
// Replace the class name.
newList = oldList.replace(' ' + name + ' ', ' ');
// Trim the opening and closing spaces.
element.className = newList.substring(1, newList.length - 1);
}
/**
* (Internal) Gets a space separated list of the class names on the element.
* The list is wrapped with a single space on each end to facilitate finding
* matches within the list.
*/
function classList(element) {
return (' ' + (element && element.className || '') + ' ').replace(/\s+/gi, ' ');
}
/**
* (Internal) Removes an element from the DOM.
*/
function removeElement(element) {
element && element.parentNode && element.parentNode.removeChild(element);
}
return NProgress;
});

View File

@ -49,10 +49,13 @@ var intervalId;
function startSetInterval(interval) { function startSetInterval(interval) {
if (cur_url[0] == "logs.py") { if (cur_url[0] == "logs.py") {
intervalId = setInterval('showLog()', interval); intervalId = setInterval('showLog()', interval);
showLog();
} else if (cur_url[0] == "viewsttats.py") { } else if (cur_url[0] == "viewsttats.py") {
intervalId = setInterval('showStats()', interval); intervalId = setInterval('showStats()', interval);
showStats()
} else if (cur_url[0] == "overview.py") { } else if (cur_url[0] == "overview.py") {
intervalId = setInterval('showOverview()', interval); intervalId = setInterval('showOverview()', interval);
showOverview();
} else { } else {
intervalId = setInterval('document.location.reload()', interval); intervalId = setInterval('document.location.reload()', interval);
} }
@ -84,6 +87,12 @@ function showOverview() {
act: "overview", act: "overview",
}, },
type: "GET", type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) { success: function( data ) {
var form = $("#ajax").html(); var form = $("#ajax").html();
$("#ajax").html(data); $("#ajax").html(data);
@ -100,10 +109,10 @@ function showStats() {
}, },
type: "GET", type: "GET",
beforeSend: function () { beforeSend: function () {
$('#loading').show(); NProgress.start();
}, },
complete: function () { complete: function () {
$("#loading").hide(); NProgress.done();
}, },
success: function( data ) { success: function( data ) {
var form = $("#ajax").html(); var form = $("#ajax").html();
@ -121,10 +130,58 @@ function showLog() {
}, },
type: "GET", type: "GET",
beforeSend: function () { beforeSend: function () {
$('#loading').show(); NProgress.start();
}, },
complete: function () { complete: function () {
$("#loading").hide(); NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
}
} );
}
function showRuntime() {
if($('#save').prop('checked')) {
saveCheck = "on";
} else {
saveCheck = "";
}
$.ajax( {
url: "options.py",
data: {
servaction: $('#servaction').val(),
serv: $("#serv").val(),
servbackend: $("#servbackend").val(),
save: saveCheck
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
}
} );
}
function showCompare() {
$.ajax( {
url: "options.py",
data: {
serv: $("#serv").val(),
left: $('#left').val(),
right: $("#right").val()
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
}, },
success: function( data ) { success: function( data ) {
var form = $("#ajax").html(); var form = $("#ajax").html();

View File

@ -19,6 +19,9 @@ h2 {
margin-top: 0px; margin-top: 0px;
margin-bottom: 0px; margin-bottom: 0px;
} }
h2 span {
width: 300px;
}
h3 { h3 {
margin-top: 10px; margin-top: 10px;
margin-bottom: 0px; margin-bottom: 0px;
@ -55,11 +58,14 @@ pre {
} }
.logoText { .logoText {
color: #EBF1F1; color: #EBF1F1;
font-size: 30px; font-size: 25px;
font-style: italic; font-style: italic;
font-weight: bold; font-weight: bold;
height: 52px; height: 37px;
background-color: #f4ab76; background-color: #f4ab76;
padding-left: 20px;
padding-top: 2px;
padding-bottom: 3px;
} }
.top-menu img { .top-menu img {
max-width: 125px; max-width: 125px;
@ -302,6 +308,7 @@ pre {
padding: 10px; padding: 10px;
padding-left: 15px; padding-left: 15px;
border: none; border: none;
width: 25%;
} }
.ro { .ro {
border: none; border: none;