mirror of
https://github.com/swizzin/swizzin_dashboard.git
synced 2024-09-20 06:46:08 +08:00
Refactor disk and quota info (#1)
* Add WIP * Fix typo * Add disk macros * Close tags * Remove cruft * Don't hover * WIP glances * Don't fill empty space * remove bind mounts * remove fuse entires also * Rename to quota * Hide drives * Fix * Fix function called * Fix js * Attempt at expanding card * Fix expandable logic * Don't adjust behavior every 4th item * Right align * Add logic to prevent errors when exactly 3 mounts
This commit is contained in:
parent
e8ccbc8a03
commit
4db8ccede1
17
core/util.py
17
core/util.py
|
@ -40,6 +40,23 @@ def get_default_interface():
|
|||
continue
|
||||
return fields[0]
|
||||
|
||||
def get_mounts():
|
||||
mounts = []
|
||||
with open("/proc/mounts") as mount:
|
||||
for line in mount:
|
||||
fields = line.strip().split()
|
||||
if fields[0].startswith("/dev"):
|
||||
if ("boot" in fields[1]) or ("fuse" in fields):
|
||||
continue
|
||||
else:
|
||||
mounts.append(fields[1])
|
||||
with open("/etc/fstab") as fstab:
|
||||
for line in fstab:
|
||||
fields = line.strip().split()
|
||||
if "bind" in str(fields):
|
||||
mounts.remove(fields[1])
|
||||
return mounts
|
||||
|
||||
def generate_page_list(user):
|
||||
admin_user = current_app.config['ADMIN_USER']
|
||||
pages = []
|
||||
|
|
|
@ -2,6 +2,29 @@
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#diskinfo a.collapsed:after {
|
||||
content: '+ Show More';
|
||||
}
|
||||
|
||||
#diskinfo a:not(.collapsed):after {
|
||||
content: '- Show Less';
|
||||
}
|
||||
|
||||
#diskglances a.collapsed:after {
|
||||
content: '+ Show More';
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#diskglances a:not(.collapsed):after {
|
||||
content: '- Show Less';
|
||||
}
|
||||
|
||||
a[post=true] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
22
swizzin.py
22
swizzin.py
|
@ -104,7 +104,12 @@ def index(user):
|
|||
# thread = Thread(target=current_speed)
|
||||
# thread.start()
|
||||
pages = generate_page_list(user)
|
||||
return flask.render_template('index.html', title='{user} - swizzin dashboard'.format(user=user), user=user, pages=pages, async_mode=socketio.async_mode)
|
||||
mounts = get_mounts()
|
||||
if os.path.isfile("/install/.quota.lock"):
|
||||
quota = True
|
||||
else:
|
||||
quota = False
|
||||
return flask.render_template('index.html', title='{user} - swizzin dashboard'.format(user=user), user=user, pages=pages, quota=quota, mounts=mounts, async_mode=socketio.async_mode)
|
||||
|
||||
@socketio.on('connect', namespace='/websocket')
|
||||
def socket_connect():
|
||||
|
@ -228,12 +233,21 @@ def vnstat(user):
|
|||
@app.route('/stats/disk')
|
||||
@htpasswd.required
|
||||
def disk_free(user):
|
||||
location = "/"
|
||||
mounts = get_mounts()
|
||||
data = {}
|
||||
for mount in mounts:
|
||||
total, used, free, usage = disk_usage(mount)
|
||||
data[mount] = {"disktotal": total, "diskused": used, "diskfree": free, "perutil": usage}
|
||||
return flask.jsonify(data)
|
||||
|
||||
@app.route('/stats/quota')
|
||||
@htpasswd.required
|
||||
def quota_free(user):
|
||||
if os.path.isfile("/install/.quota.lock"):
|
||||
total, used, free, usage = quota_usage(user)
|
||||
return flask.jsonify({"quota": {"disktotal": total, "diskused": used, "diskfree": free, "perutil": usage}})
|
||||
else:
|
||||
total, used, free, usage = disk_usage(location)
|
||||
return flask.jsonify({"disktotal": total, "diskused": used, "diskfree": free, "perutil": usage})
|
||||
return """Quota not installed"""
|
||||
|
||||
@app.route('/stats/boot')
|
||||
@htpasswd.required
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
<div class="card border-dark mt-3">
|
||||
<div class="card-header">Disk Info</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h5 class="text-center">Used</h5>
|
||||
<p class="text-center"><span id="diskused"></span></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h5 class="text-center">Free</h5>
|
||||
<p class="text-center"><span id="diskfree"></span></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h5 class="text-center">Total</h5>
|
||||
<p class="text-center"><span id="disktotal"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div id="diskprogress" class="progress-bar bg-warning" role="progressbar" style="" aria-valuenow="" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<p class="text-center">You have used <span id="diskpercent"></span>% of your disk</p>
|
||||
<div id="diskinfo" class="card-body">
|
||||
{{macros.build_disk_info(mounts=mounts)}}
|
||||
</div>
|
||||
</div>
|
|
@ -6,10 +6,12 @@
|
|||
<h5 class="text-center">Load</h5>
|
||||
<p class="text-center"><span id="loadindicator" class="systemindicator"></span></p>
|
||||
</div>
|
||||
{% if quota == True %}
|
||||
<div class="col">
|
||||
<h5 class="text-center">Disk</h5>
|
||||
<p class="text-center"><span id="diskindicator" class="systemindicator"></span></p>
|
||||
<p class="text-center"><span id="quotaindicator" class="systemindicator"></span></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col">
|
||||
<h5 class="text-center">RAM</h5>
|
||||
<p class="text-center"><span id="ramindicator" class="systemindicator"></span></p>
|
||||
|
@ -19,6 +21,9 @@
|
|||
<p class="text-center"><span id="iowait-glance">--</span></p>
|
||||
</div>
|
||||
</div>
|
||||
{% if (quota == False or config.ADMIN_USER == user) %}
|
||||
{{macros.build_disk_glances(mounts=mounts)}}
|
||||
{% endif %}
|
||||
<h5 class="text-center">Uptime</h5>
|
||||
<div class="countup text-center" id="uptime">
|
||||
<p>
|
||||
|
|
|
@ -22,7 +22,12 @@
|
|||
{% include 'glance.html' %}
|
||||
{{ macros.build_app_table(apps=pages) }}
|
||||
{% include 'systeminfo.html' %}
|
||||
{% include 'diskinfo.html' %}
|
||||
{% if quota == True %}
|
||||
{% include 'quotainfo.html' %}
|
||||
{% endif %}
|
||||
{% if (quota == False or config.ADMIN_USER == user) %}
|
||||
{% include 'diskinfo.html' %}
|
||||
{% endif %}
|
||||
{% include 'raminfo.html' %}
|
||||
{% if (config.SHAREDSERVER == True or config.ADMIN_USER == user) %}
|
||||
{% include 'netinfo.html' %}
|
||||
|
@ -46,6 +51,29 @@
|
|||
{{ macros.build_widget_js_shared() }}
|
||||
{% endif %}
|
||||
|
||||
{% if quota == True %}
|
||||
(function quotausage() {
|
||||
$.get('{{ url_for('quota_free') }}', function(data) {
|
||||
var percent = Math.trunc(data["quota"]['perutil']);
|
||||
$("#quotafree").html(data["quota"]['diskfree']);
|
||||
$("#quotaused").html(data["quota"]['diskused']);
|
||||
$("#quotatotal").html(data["quota"]['disktotal']);
|
||||
$("#quotapercent").html(data["quota"]['perutil']);
|
||||
if (Number(data["quota"]['perutil']) > 90) {
|
||||
$("#quotaindicator.systemindicator").addClass("bg-danger").removeClass("bg-success bg-warning");
|
||||
$("#quotaprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-danger").removeClass("bg-success bg-warning");
|
||||
} else if (Number(data["quota"]['perutil']) > 75) {
|
||||
$("#quotaindicator.systemindicator").addClass("bg-warning").removeClass("bg-success bg-danger");
|
||||
$("#quotaprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-warning").removeClass("bg-success bg-danger");
|
||||
} else {
|
||||
$("#quotaindicator.systemindicator").addClass("bg-success").removeClass("bg-warning bg-danger");
|
||||
$("#quotaprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-success").removeClass("bg-danger bg-warning");
|
||||
}
|
||||
setTimeout(function(){quotausage()}, 60000);
|
||||
});
|
||||
})();
|
||||
{% endif %}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -133,7 +133,119 @@
|
|||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro build_disk_info(mounts) %}
|
||||
<table class="table table-sm table-dark table-borderless">
|
||||
<thead class="table-active">
|
||||
<tr>
|
||||
<th scope="col" class="text-center">Mount</th>
|
||||
<th scope="col" class="text-center">Used</th>
|
||||
<th scope="col" class="text-center">Free</th>
|
||||
<th scope="col" class="text-center">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for mount in mounts %}
|
||||
<tbody class="diskwidget">
|
||||
<tr style="height: 15px;"></tr>
|
||||
<tr>
|
||||
<td>{{ mount }}</td>
|
||||
<td id='{{ mount }}diskused' class="text-center"></td>
|
||||
<td id='{{ mount }}diskfree'class="text-center"></td>
|
||||
<td id='{{ mount }}disktotal' class="text-center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" class="align-middle"><span class="progress"><div id='{{ mount }}diskprogress' class='progress-bar' role='progressbar' style='' aria-valuenow='' aria-valuemin='0' aria-valuemax='100'></div></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center"><span id='{{ mount }}diskpercent'></span>%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{% if (loop.index == 3 and not loop.last) %}
|
||||
</table>
|
||||
<table class="collapse" id="collapsediskinfo" aria-expanded="false">
|
||||
{% endif %}
|
||||
{% if loop.last %}
|
||||
</table>
|
||||
{% if loop.index > 3 %}
|
||||
<a role="button" class="collapsed" data-toggle="collapse" href="#collapsediskinfo" aria-expanded="false" aria-controls="collapsediskinfo"></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro build_disk_glances(mounts) %}
|
||||
<div id="diskglances">
|
||||
<div class="row">
|
||||
{% for mount in mounts %}
|
||||
<div class="col">
|
||||
<h5 class="text-center">{{ mount }}</h5>
|
||||
<p class="text-center"><span id="{{ mount }}indicator" class="systemindicator"></span></p>
|
||||
</div>
|
||||
{% if (loop.index == 3 and not loop.last) %}
|
||||
</div>
|
||||
<div id="collapsediskglances" class="collapse row" aria-expanded="false">
|
||||
{% endif %}
|
||||
{% if loop.last %}
|
||||
</div>
|
||||
{% if loop.index > 3%}
|
||||
<a role="button" class="collapsed" data-toggle="collapse" href="#collapsediskglances" aria-expanded="false" aria-controls="collapsediskinfo"></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro build_widget_js() %}
|
||||
function getdisks() {
|
||||
$('#diskinfo').html('')
|
||||
var html =`
|
||||
<table class="table table-sm table-hover table-dark table-borderless">
|
||||
<thead class="table-active">
|
||||
<tr>
|
||||
<th scope="col" class="text-center">Mount</th>
|
||||
<th scope="col" class="text-center">Used</th>
|
||||
<th scope="col" class="text-center">Free</th>
|
||||
<th scope="col" class="text-center">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
`
|
||||
$.get('{{ url_for('disk_free') }}', function(data) {
|
||||
var datalength = $(data).length
|
||||
var i = 0
|
||||
for (var mount in data) {
|
||||
html += `
|
||||
<tbody class="diskwidget">
|
||||
<tr style="height: 15px;"></tr>
|
||||
<tr>
|
||||
<td>`+mount+`</td>
|
||||
<td id='`+mount+`diskused' class="text-center"></td>
|
||||
<td id='`+mount+`diskfree'class="text-center"></td>
|
||||
<td id='`+mount+`disktotal' class="text-center"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" class="align-middle"><span class="progress"><div id='`+mount+`diskprogress' class='progress-bar bg-warning' role='progressbar' style='' aria-valuenow='' aria-valuemin='0' aria-valuemax='100'></div></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center"><span id='`+mount+`diskpercent'></span>%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
`
|
||||
if (i < $(data).length) {
|
||||
html += ``
|
||||
}
|
||||
i++
|
||||
}
|
||||
html += `
|
||||
</table>
|
||||
`
|
||||
$('#diskinfo').append(html)
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
//getdisks()
|
||||
|
||||
function appstatus(){
|
||||
$.get("{{ url_for('app_status') }}", function(data){
|
||||
for (var apps in data) {
|
||||
|
@ -177,24 +289,25 @@ appstatus();
|
|||
|
||||
(function diskusage() {
|
||||
$.get('{{ url_for('disk_free') }}', function(data) {
|
||||
var percent = Math.trunc(data['perutil']);
|
||||
$("#diskfree").html(data['diskfree']);
|
||||
$("#diskused").html(data['diskused']);
|
||||
$("#disktotal").html(data['disktotal']);
|
||||
$("#diskpercent").html(data['perutil']);
|
||||
if (Number(data['perutil']) > 90) {
|
||||
$("#diskindicator.systemindicator").addClass("bg-danger").removeClass("bg-success bg-warning");
|
||||
$("#diskprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-danger").removeClass("bg-success bg-warning");
|
||||
} else if (Number(data['perutil']) > 75) {
|
||||
$("#diskindicator.systemindicator").addClass("bg-warning").removeClass("bg-success bg-danger");
|
||||
$("#diskprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-warning").removeClass("bg-success bg-danger");
|
||||
} else {
|
||||
$("#diskindicator.systemindicator").addClass("bg-success").removeClass("bg-warning bg-danger");
|
||||
$("#diskprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-success").removeClass("bg-danger bg-warning");
|
||||
}
|
||||
setTimeout(function(){diskusage()}, 60000);
|
||||
}
|
||||
);
|
||||
for (var mount in data) {
|
||||
var percent = Math.trunc(data[mount]['perutil']);
|
||||
$("#"+$.escapeSelector(mount)+"diskfree").html(data[mount]['diskfree']);
|
||||
$("#"+$.escapeSelector(mount)+"diskused").html(data[mount]['diskused']);
|
||||
$("#"+$.escapeSelector(mount)+"disktotal").html(data[mount]['disktotal']);
|
||||
$("#"+$.escapeSelector(mount)+"diskpercent").html(data[mount]['perutil']);
|
||||
if (Number(data[mount]['perutil']) > 90) {
|
||||
$("#"+$.escapeSelector(mount)+"indicator.systemindicator").addClass("bg-danger").removeClass("bg-success bg-warning");
|
||||
$("#"+$.escapeSelector(mount)+"diskprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-danger").removeClass("bg-success bg-warning");
|
||||
} else if (Number(data[mount]['perutil']) > 75) {
|
||||
$("#"+$.escapeSelector(mount)+"indicator.systemindicator").addClass("bg-warning").removeClass("bg-success bg-danger");
|
||||
$("#"+$.escapeSelector(mount)+"diskprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-warning").removeClass("bg-success bg-danger");
|
||||
} else {
|
||||
$("#"+$.escapeSelector(mount)+"indicator.systemindicator").addClass("bg-success").removeClass("bg-warning bg-danger");
|
||||
$("#"+$.escapeSelector(mount)+"diskprogress").css("width", percent + "%").attr("aria-valuenow", percent).addClass("bg-success").removeClass("bg-danger bg-warning");
|
||||
}
|
||||
}
|
||||
setTimeout(function(){diskusage()}, 60000);
|
||||
});
|
||||
})();
|
||||
|
||||
(function ramusage() {
|
||||
|
|
23
templates/quotainfo.html
Normal file
23
templates/quotainfo.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<div class="card border-dark mt-3">
|
||||
<div class="card-header">Disk Quota Info</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h5 class="text-center">Used</h5>
|
||||
<p class="text-center"><span id="quotaused"></span></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h5 class="text-center">Free</h5>
|
||||
<p class="text-center"><span id="quotafree"></span></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h5 class="text-center">Total</h5>
|
||||
<p class="text-center"><span id="quotatotal"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div id="quotaprogress" class="progress-bar bg-warning" role="progressbar" style="" aria-valuenow="" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<p class="text-center">You have used <span id="quotapercent"></span>% of your disk quota</p>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in a new issue