Revision 401089d8

b/snf-astakos-app/astakos/im/settings.py
219 219
NEWPASSWD_INVALIDATE_TOKEN = getattr(
220 220
    settings, 'ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN', True)
221 221

  
222
USAGE_UPDATE_INTERVAL = getattr(settings, 'ASTAKOS_USAGE_UPDATE_INTERVAL', 5000)
222 223

  
223 224
RESOURCES_PRESENTATION_DATA = getattr(
224 225
    settings, 'ASTAKOS_RESOURCES_PRESENTATION_DATA', {
b/snf-astakos-app/astakos/im/static/im/css/modules.css
443 443
.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}
444 444
.stats .bar										{ padding: 0; text-align:center;  float:left; width:200px;}
445 445
.stats .bar div									{ width:340px; height:30px; border:1px solid #000; margin-top:20px; overflow:hidden;}
446
.stats .bar span								{ text-align:right; display:block; height:100%; float:left; }
447
.stats .bar span em								{ color:#fff; float:right; }
448
.stats .bar em									{ font-style:normal; color:#222;  line-height:30px; font-size:1.231em; padding-left:10px; float:left  }
446
.stats .bar span								{ text-align:right; display:block; height:100%; position: relative; overflow: visible; }
447
.stats .bar span.value							{ background-color: transparent !important; }
448
.stats .bar span em								{ color:#000; }
449
.stats .bar span em.hovered 					{ color:#fff; }
450
.stats .bar em { 
451
    font-style:normal; 
452
    color:#222;  
453
    line-height:30px; 
454
    font-size:1.231em; 
455
    padding-left:10px; 
456
    position: absolute;
457
    right: 10px;
458
    left: 10px;
459
}
449 460
.stats .red .bar span							{ background:#ef4f54; }
450 461
.stats .yellow .bar span						{ background:#f6921e; }
451 462
.stats .green .bar span							{ background:#55b577; }
......
519 530

  
520 531
/* login section */
521 532
.login-section {}
522
.main-login-method 								{ margin-bottom: 20px;}
533
.main-login-method 								{ margin-bottom: 20px;}
534

  
535

  
536

  
537
.stats .bar span {
538
    transition: width 1s, background-color 0.3s;
539
    -moz-transition: width 1s, background-color 0.3s; /* Firefox 4 */
540
    -webkit-transition: width 1s, background-color 0.3s; /* Safari and Chrome */
541
    -o-transition: width 1s, background-color 0.3s; /* Opera */
542
}
543

  
544
.stats .bar em {
545
    transition: width 1s, color 0.2s;
546
    -moz-transition: width 1s, color 0.2s; /* Firefox 4 */
547
    -webkit-transition: width 1s, color 0.2s; /* Safari and Chrome */
548
    -o-transition: width 1s, color 0.2s; /* Opera */
549
}
b/snf-astakos-app/astakos/im/static/im/js/usage.js
1
;(function() {
2

  
3

  
4
// helper humanize methods
5
// https://github.com/taijinlee/humanize/blob/master/humanize.js 
6
humanize = {};
7
humanize.filesize = function(filesize, kilo, decimals, decPoint, thousandsSep) {
8
    kilo = (kilo === undefined) ? 1024 : kilo;
9
    decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
10
    decPoint = (decPoint === undefined) ? '.' : decPoint;
11
    thousandsSep = (thousandsSep === undefined) ? ',' : thousandsSep;
12
    if (filesize <= 0) { return '0 bytes'; }
13

  
14
    var thresholds = [1];
15
    var units = ['bytes', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'];
16
    if (filesize < kilo) { return humanize.numberFormat(filesize, 0) + ' ' + units[0]; }
17

  
18
    for (var i = 1; i < units.length; i++) {
19
      thresholds[i] = thresholds[i-1] * kilo;
20
      if (filesize < thresholds[i]) {
21
        return humanize.numberFormat(filesize / thresholds[i-1], decimals, decPoint, thousandsSep) + ' ' + units[i-1];
22
      }
23
    }
24

  
25
    // use the last unit if we drop out to here
26
    return humanize.numberFormat(filesize / thresholds[units.length - 1], decimals, decPoint, thousandsSep) + ' ' + units[units.length - 1];
27
};
28
humanize.numberFormat = function(number, decimals, decPoint, thousandsSep) {
29
    decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
30
    decPoint = (decPoint === undefined) ? '.' : decPoint;
31
    thousandsSep = (thousandsSep === undefined) ? ',' : thousandsSep;
32

  
33
    var sign = number < 0 ? '-' : '';
34
    number = Math.abs(+number || 0);
35

  
36
    var intPart = parseInt(number.toFixed(decimals), 10) + '';
37
    var j = intPart.length > 3 ? intPart.length % 3 : 0;
38

  
39
    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) : '');
40
  };
41

  
42
function UsageClient(settings) {
43
  this.settings = settings;
44
  this.url = this.settings.url;
45
  this.container = $(this.settings.container);
46
}
47

  
48
UsageClient.prototype.load = function() {
49
  var self = this;
50
  $.ajax(this.url, {
51
    'success': function(data) {
52
      self.update(data);
53
    }
54
  })
55
}
56

  
57
function setText(el, valueFrom, valueTo, direction, modifier) {
58
  //valueTo = parseInt(valueTo);
59
  //text = valueFrom;
60

  
61
  //if (valueFrom >= valueTo) {
62
    //valueFrom = valueTo;
63
  //}
64
  
65
  var text = valueTo;
66
  if (modifier) {
67
    text = modifier(text);
68
  }
69
  el.html(text);
70

  
71
  //if (valueTo > valueFrom) {
72
    //window.setTimeout(function() {
73
      //setText(el, parseInt(valueFrom) + step, parseInt(valueTo));
74
    //}, 10)
75
  //}
76
}
77

  
78
UsageClient.prototype.updateEntry = function(key, data) {
79

  
80
  var entry = $('li[data-resourcekey=\''+key+'\']');
81
  var currentEl = entry.find("span.currValue");
82
  var maxEl = entry.find("span.maxValue");
83
  var ratioEl = entry.find("div.bar");
84
  var barEl = entry.find("div.bar span");
85
  var percentageEl = ratioEl.find("em");
86
  var units = entry.data("units");
87
  var infoEl = entry.find(".info");
88
  
89
  var current = data.currValue;
90
  var max = data.maxValue;
91
  
92
  modifier = function(v) { return v; }
93
  if (units == 'bytes') {
94
      modifier = humanize.filesize;
95
  }
96

  
97
  setText(maxEl, infoEl.data('maxvalue'), max, infoEl.data('maxvalue') > max, 
98
          modifier);
99
  setText(currentEl, infoEl.data('currvalue'), current, 
100
          infoEl.data('currvalue') > current, modifier);
101
  
102
  var percentage = humanize.numberFormat(data.ratio, 1);
103
  setText(percentageEl, percentageEl.data('value'), 
104
          percentage, percentageEl.data('value') > percentage, 
105
          function(v) { return v + '&#37; &nbsp;&nbsp;'});
106

  
107
  var width = data.ratio;
108
  if (width > 100) { width = 100; }
109
  if (width < 0) { width = 0; }
110

  
111
  width = humanize.numberFormat(width, 1);
112
  barEl.css({'width': width + '%'});
113

  
114
  if (percentage > 18) {
115
      percentageEl.addClass("hovered");
116
  } else {
117
      percentageEl.removeClass("hovered");
118
  }
119
  percentageEl.data('value', percentage);
120

  
121
  entry.removeClass("red green yellow");
122
  entry.addClass(data.load_class);
123

  
124
  entry.find(".info").data("currvalue", data.currValue);
125
  entry.find(".info").data("maxvalue", data.maxValue);
126
}
127

  
128
UsageClient.prototype.update = function(data) {
129
  var usage = {}, self = this;
130
  _.each(data, function(e) { usage[e.name] = e});
131

  
132
  _.each(usage, function(data, key) {
133
      self.updateEntry(key, data);
134
  });
135
}
136

  
137
window.UsageClient = UsageClient;
138
})();
b/snf-astakos-app/astakos/im/templates/im/base.html
43 43
  {% block headjs %}
44 44
  	  <script src="{{ IM_STATIC_URL }}js/jquery-1.7.1.min.js"></script>	
45 45
  	  
46
  	  <script src="{{ IM_STATIC_URL }}js/underscore.js"></script>	
46 47
  	  <script src="{{ IM_STATIC_URL }}js/os.js"></script>	
47 48
      <script src="{{ IM_STATIC_URL }}js/modernizr-2.0.6.js"></script>	
48 49
      <script src="{{ IM_STATIC_URL }}js/jquery.js"></script>	
b/snf-astakos-app/astakos/im/templates/im/resource_usage.html
2 2

  
3 3
{% load filters %}
4 4

  
5
{% block headjs %}
6
{{ block.super }}
7
<script src="{{ IM_STATIC_URL }}js/usage.js"></script>	
8
{% endblock %}
9

  
5 10
{% block page.body %}
6 11
<div class="maincol {% block innerpage.class %}{% endblock %}"> 
7 12
	<div class="stats clearfix">
8 13
		<ul>
9 14
			{% for rdata in resource_usage %}
10
		 		<li class="clearfix  {{ rdata.load_class }} {{ rdata.name|get_value_after_dot }}">
15
            <li class="clearfix  {{ rdata.load_class }} {{ rdata.name|get_value_after_dot }}" 
16
                    data-resourcekey="{{ rdata.name }}" data-units="{{ rdata.unit }}">
11 17
		 			<div class="img-wrap">&nbsp;</div>
12
		 			<div class="info">
18
                    <div class="info" data-currvalue="{{ rdata.currValue }}"
19
                                      data-maxvalue="{{ rdata.maxValue }}">
13 20
						<h3>{{ rdata.report_desc }}</h3>
14 21
						<p>							
15 22
						{% if rdata.unit == 'bytes' %}
16
							{{ rdata.currValue|sizeof_fmt  }} out of  {{ rdata.maxValue|sizeof_fmt }}
17
						{% else %}
18
							{{ rdata.currValue }}  out of  {{ rdata.maxValue }} {{ rdata.unit }}
23
                        <span class="currValue">
24
                            {{ rdata.currValue|sizeof_fmt }}
25
                        </span> out of  
26
                        <span class="maxValue">
27
                            {{ rdata.maxValue|sizeof_fmt }}
28
                        </span>
29
                        {% else %}
30
                        <span class="currValue">
31
                            <span class="value">{{ rdata.currValue }}</span>
32
                        </span>
33
                        out of  
34
                        <span class="maxValue">
35
                            <span class="value">{{ rdata.maxValue }}</span>
36
                            <span class="unit">{{ rdata.unit }}</span>
37
                        </span>
19 38
						{% endif %}		
20
						{% 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  %}
39
                        {% if rdata.is_abbreviation %}
40
                            {{ rdata.verbose_name|upper }}
41
                        {% else %}
42
                            {{ rdata.verbose_name }}
43
                        {% endif %}
44
                        {% if rdata.maxValue|floatformat:"0" != "1" and not rdata.unit %}s {% endif  %}
21 45
						</p>
22 46
					</div>
23
					<div class="bar">
47
					<div class="bar" data-steps="">
24 48
						<div>
25 49
							<span style="width:{{ rdata.ratio_limited|floatformat }}%;">
26
								 {% if rdata.ratio > 18  %}
27
								 <em>{{ rdata.ratio|floatformat }}% &nbsp;&nbsp;</em>	
50
                                <em data-value="{{ rdata.ratio }}" class="value {% if rdata.ratio > 18 %}hovered{% endif %}
51
">{{ rdata.ratio|floatformat }}&#37; &nbsp;&nbsp;</em>	
28 52
							</span>
29
								{% else%}
30
								&nbsp;
31
							</span>
32
							<em>{{ rdata.ratio|floatformat }}% &nbsp;&nbsp;</em>
33
								{% endif %}
34 53
						</div>
35 54
					</div>
36 55
		 		</li>
......
39 58
			 
40 59
	</div>    
41 60
</div>
61
<script>
62
    $(document).ready(function(){
63
        var usageClient = new UsageClient({
64
            'url': '{% url resource_usage %}?json=1',
65
            'dataType': 'json',
66
            'container': 'div.stats'
67
        });
68
        
69
        window.setInterval(function() {
70
            usageClient.load();
71
        }, {{ usage_update_interval }});
72
        usageClient.load();
73
    })
74

  
75
</script>
42 76
{% endblock %}
b/snf-astakos-app/astakos/im/views.py
841 841
    else:
842 842
        messages.error(request, result.reason)
843 843
        backenddata = []
844
        resource_usage = []
845

  
846
    if request.REQUEST.get('json', None):
847
        return HttpResponse(json.dumps(backenddata),
848
                            mimetype="application/json")
849

  
844 850
    return render_response('im/resource_usage.html',
845 851
                           context_instance=get_context(request),
846 852
                           resource_usage=backenddata,
853
                           usage_update_interval=astakos_settings.USAGE_UPDATE_INTERVAL,
847 854
                           result=result)
848 855

  
849 856
# TODO: action only on POST and user should confirm the removal

Also available in: Unified diff