Commit 071971ba authored by Kostas Papadimitriou's avatar Kostas Papadimitriou
Browse files

Periodically update quotas information in astakos usage page

parent 96904553
......@@ -219,6 +219,7 @@ PAGINATE_BY_ALL = getattr(settings, 'ASTAKOS_PAGINATE_BY_ALL', 15)
NEWPASSWD_INVALIDATE_TOKEN = getattr(
settings, 'ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN', True)
USAGE_UPDATE_INTERVAL = getattr(settings, 'ASTAKOS_USAGE_UPDATE_INTERVAL', 5000)
RESOURCES_PRESENTATION_DATA = getattr(
settings, 'ASTAKOS_RESOURCES_PRESENTATION_DATA', {
......
......@@ -443,9 +443,20 @@ form.quotas-form span.info span { width:285px; }
.stats ul li { margin:0 0 1em 0; padding:0 0 1em 0; list-style:none outside none; background:url(../images/stats-line.jpg) repeat-x left bottom}
.stats .bar { padding: 0; text-align:center; float:left; width:200px;}
.stats .bar div { width:340px; height:30px; border:1px solid #000; margin-top:20px; overflow:hidden;}
.stats .bar span { text-align:right; display:block; height:100%; float:left; }
.stats .bar span em { color:#fff; float:right; }
.stats .bar em { font-style:normal; color:#222; line-height:30px; font-size:1.231em; padding-left:10px; float:left }
.stats .bar span { text-align:right; display:block; height:100%; position: relative; overflow: visible; }
.stats .bar span.value { background-color: transparent !important; }
.stats .bar span em { color:#000; }
.stats .bar span em.hovered { color:#fff; }
.stats .bar em {
font-style:normal;
color:#222;
line-height:30px;
font-size:1.231em;
padding-left:10px;
position: absolute;
right: 10px;
left: 10px;
}
.stats .red .bar span { background:#ef4f54; }
.stats .yellow .bar span { background:#f6921e; }
.stats .green .bar span { background:#55b577; }
......@@ -519,4 +530,20 @@ form.withlabels.hidden-submit { margin-bottom:4em; }
/* login section */
.login-section {}
.main-login-method { margin-bottom: 20px;}
\ No newline at end of file
.main-login-method { margin-bottom: 20px;}
.stats .bar span {
transition: width 1s, background-color 0.3s;
-moz-transition: width 1s, background-color 0.3s; /* Firefox 4 */
-webkit-transition: width 1s, background-color 0.3s; /* Safari and Chrome */
-o-transition: width 1s, background-color 0.3s; /* Opera */
}
.stats .bar em {
transition: width 1s, color 0.2s;
-moz-transition: width 1s, color 0.2s; /* Firefox 4 */
-webkit-transition: width 1s, color 0.2s; /* Safari and Chrome */
-o-transition: width 1s, color 0.2s; /* Opera */
}
;(function() {
// helper humanize methods
// https://github.com/taijinlee/humanize/blob/master/humanize.js
humanize = {};
humanize.filesize = function(filesize, kilo, decimals, decPoint, thousandsSep) {
kilo = (kilo === undefined) ? 1024 : kilo;
decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
decPoint = (decPoint === undefined) ? '.' : decPoint;
thousandsSep = (thousandsSep === undefined) ? ',' : thousandsSep;
if (filesize <= 0) { return '0 bytes'; }
var thresholds = [1];
var units = ['bytes', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'];
if (filesize < kilo) { return humanize.numberFormat(filesize, 0) + ' ' + units[0]; }
for (var i = 1; i < units.length; i++) {
thresholds[i] = thresholds[i-1] * kilo;
if (filesize < thresholds[i]) {
return humanize.numberFormat(filesize / thresholds[i-1], decimals, decPoint, thousandsSep) + ' ' + units[i-1];
}
}
// use the last unit if we drop out to here
return humanize.numberFormat(filesize / thresholds[units.length - 1], decimals, decPoint, thousandsSep) + ' ' + units[units.length - 1];
};
humanize.numberFormat = function(number, decimals, decPoint, thousandsSep) {
decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
decPoint = (decPoint === undefined) ? '.' : decPoint;
thousandsSep = (thousandsSep === undefined) ? ',' : thousandsSep;
var sign = number < 0 ? '-' : '';
number = Math.abs(+number || 0);
var intPart = parseInt(number.toFixed(decimals), 10) + '';
var j = intPart.length > 3 ? intPart.length % 3 : 0;
return sign + (j ? intPart.substr(0, j) + thousandsSep : '') + intPart.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousandsSep) + (decimals ? decPoint + Math.abs(number - intPart).toFixed(decimals).slice(2) : '');
};
function UsageClient(settings) {
this.settings = settings;
this.url = this.settings.url;
this.container = $(this.settings.container);
}
UsageClient.prototype.load = function() {
var self = this;
$.ajax(this.url, {
'success': function(data) {
self.update(data);
}
})
}
function setText(el, valueFrom, valueTo, direction, modifier) {
//valueTo = parseInt(valueTo);
//text = valueFrom;
//if (valueFrom >= valueTo) {
//valueFrom = valueTo;
//}
var text = valueTo;
if (modifier) {
text = modifier(text);
}
el.html(text);
//if (valueTo > valueFrom) {
//window.setTimeout(function() {
//setText(el, parseInt(valueFrom) + step, parseInt(valueTo));
//}, 10)
//}
}
UsageClient.prototype.updateEntry = function(key, data) {
var entry = $('li[data-resourcekey=\''+key+'\']');
var currentEl = entry.find("span.currValue");
var maxEl = entry.find("span.maxValue");
var ratioEl = entry.find("div.bar");
var barEl = entry.find("div.bar span");
var percentageEl = ratioEl.find("em");
var units = entry.data("units");
var infoEl = entry.find(".info");
var current = data.currValue;
var max = data.maxValue;
modifier = function(v) { return v; }
if (units == 'bytes') {
modifier = humanize.filesize;
}
setText(maxEl, infoEl.data('maxvalue'), max, infoEl.data('maxvalue') > max,
modifier);
setText(currentEl, infoEl.data('currvalue'), current,
infoEl.data('currvalue') > current, modifier);
var percentage = humanize.numberFormat(data.ratio, 1);
setText(percentageEl, percentageEl.data('value'),
percentage, percentageEl.data('value') > percentage,
function(v) { return v + '&#37; &nbsp;&nbsp;'});
var width = data.ratio;
if (width > 100) { width = 100; }
if (width < 0) { width = 0; }
width = humanize.numberFormat(width, 1);
barEl.css({'width': width + '%'});
if (percentage > 18) {
percentageEl.addClass("hovered");
} else {
percentageEl.removeClass("hovered");
}
percentageEl.data('value', percentage);
entry.removeClass("red green yellow");
entry.addClass(data.load_class);
entry.find(".info").data("currvalue", data.currValue);
entry.find(".info").data("maxvalue", data.maxValue);
}
UsageClient.prototype.update = function(data) {
var usage = {}, self = this;
_.each(data, function(e) { usage[e.name] = e});
_.each(usage, function(data, key) {
self.updateEntry(key, data);
});
}
window.UsageClient = UsageClient;
})();
......@@ -43,6 +43,7 @@
{% block headjs %}
<script src="{{ IM_STATIC_URL }}js/jquery-1.7.1.min.js"></script>
<script src="{{ IM_STATIC_URL }}js/underscore.js"></script>
<script src="{{ IM_STATIC_URL }}js/os.js"></script>
<script src="{{ IM_STATIC_URL }}js/modernizr-2.0.6.js"></script>
<script src="{{ IM_STATIC_URL }}js/jquery.js"></script>
......
......@@ -2,35 +2,54 @@
{% load filters %}
{% block headjs %}
{{ block.super }}
<script src="{{ IM_STATIC_URL }}js/usage.js"></script>
{% endblock %}
{% block page.body %}
<div class="maincol {% block innerpage.class %}{% endblock %}">
<div class="stats clearfix">
<ul>
{% for rdata in resource_usage %}
<li class="clearfix {{ rdata.load_class }} {{ rdata.name|get_value_after_dot }}">
<li class="clearfix {{ rdata.load_class }} {{ rdata.name|get_value_after_dot }}"
data-resourcekey="{{ rdata.name }}" data-units="{{ rdata.unit }}">
<div class="img-wrap">&nbsp;</div>
<div class="info">
<div class="info" data-currvalue="{{ rdata.currValue }}"
data-maxvalue="{{ rdata.maxValue }}">
<h3>{{ rdata.report_desc }}</h3>
<p>
{% if rdata.unit == 'bytes' %}
{{ rdata.currValue|sizeof_fmt }} out of {{ rdata.maxValue|sizeof_fmt }}
{% else %}
{{ rdata.currValue }} out of {{ rdata.maxValue }} {{ rdata.unit }}
<span class="currValue">
{{ rdata.currValue|sizeof_fmt }}
</span> out of
<span class="maxValue">
{{ rdata.maxValue|sizeof_fmt }}
</span>
{% else %}
<span class="currValue">
<span class="value">{{ rdata.currValue }}</span>
</span>
out of
<span class="maxValue">
<span class="value">{{ rdata.maxValue }}</span>
<span class="unit">{{ rdata.unit }}</span>
</span>
{% endif %}
{% if rdata.is_abbreviation %}{{ rdata.verbose_name|upper }}{% else %}{{ rdata.verbose_name }}{% endif %}{% if rdata.maxValue|floatformat:"0" != "1" and not rdata.unit %}s {% endif %}
{% if rdata.is_abbreviation %}
{{ rdata.verbose_name|upper }}
{% else %}
{{ rdata.verbose_name }}
{% endif %}
{% if rdata.maxValue|floatformat:"0" != "1" and not rdata.unit %}s {% endif %}
</p>
</div>
<div class="bar">
<div class="bar" data-steps="">
<div>
<span style="width:{{ rdata.ratio_limited|floatformat }}%;">
{% if rdata.ratio > 18 %}
<em>{{ rdata.ratio|floatformat }}% &nbsp;&nbsp;</em>
<em data-value="{{ rdata.ratio }}" class="value {% if rdata.ratio > 18 %}hovered{% endif %}
">{{ rdata.ratio|floatformat }}&#37; &nbsp;&nbsp;</em>
</span>
{% else%}
&nbsp;
</span>
<em>{{ rdata.ratio|floatformat }}% &nbsp;&nbsp;</em>
{% endif %}
</div>
</div>
</li>
......@@ -39,4 +58,19 @@
</div>
</div>
<script>
$(document).ready(function(){
var usageClient = new UsageClient({
'url': '{% url resource_usage %}?json=1',
'dataType': 'json',
'container': 'div.stats'
});
window.setInterval(function() {
usageClient.load();
}, {{ usage_update_interval }});
usageClient.load();
})
</script>
{% endblock %}
......@@ -841,9 +841,16 @@ def resource_usage(request):
else:
messages.error(request, result.reason)
backenddata = []
resource_usage = []
if request.REQUEST.get('json', None):
return HttpResponse(json.dumps(backenddata),
mimetype="application/json")
return render_response('im/resource_usage.html',
context_instance=get_context(request),
resource_usage=backenddata,
usage_update_interval=astakos_settings.USAGE_UPDATE_INTERVAL,
result=result)
# TODO: action only on POST and user should confirm the removal
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment