]> git.sur5r.net Git - bacula/bacula/blob - gui/bweb/html/bweb.js
bweb: Add sqlite support
[bacula/bacula] / gui / bweb / html / bweb.js
1 // Bweb - A Bacula web interface
2 // Bacula® - The Network Backup Solution
3 //
4 // Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
5 //
6 // The main author of Bweb is Eric Bollengier.
7 // The main author of Bacula is Kern Sibbald, with contributions from
8 // many others, a complete list can be found in the file AUTHORS.
9 //
10 // This program is Free Software; you can redistribute it and/or
11 // modify it under the terms of version two of the GNU General Public
12 // License as published by the Free Software Foundation plus additions
13 // that are listed in the file LICENSE.
14 //
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 // 02110-1301, USA.
24 //
25 // Bacula® is a registered trademark of Kern Sibbald.
26 // The licensor of Bacula is the Free Software Foundation Europe
27 // (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
28 // Switzerland, email:ftf@fsfeurope.org.
29
30  var even_cell_color = "#FFFFFF";
31  var odd_cell_color  = "#EEEEEE";
32  var header_color    = "#E1E0DA";
33  var rows_per_page   = 20;
34  var bweb_root       = "/bweb/";
35  var up_icon         = "/bweb/up.gif";
36  var down_icon       = "/bweb/down.gif";
37  var prev_icon       = "/bweb/left.gif";
38  var next_icon       = "/bweb/right.gif";
39  var rew_icon        = "/bweb/first.gif";
40  var fwd_icon        = "/bweb/last.gif";
41
42  var jobstatus = {
43  'C': 'created but not yet running',
44  'R': 'running',
45  'B': 'blocked',
46  'T': 'terminated normally',
47  'E': 'Job terminated in error',
48  'e': 'Non-fatal error',
49  'f': 'Fatal error',
50  'D': 'Verify differences',
51  'A': 'canceled by user',
52  'F': 'waiting on File daemon',
53  'S': 'waiting on the Storage daemon',
54  'm': 'waiting for new media',
55  'M': 'waiting for Mount',
56  's': 'Waiting for storage resource',
57  'j': 'Waiting for job resource',
58  'c': 'Waiting for Client resource',
59  'd': 'Waiting for maximum jobs',
60  't': 'Waiting for start time',
61  'p': 'Waiting for higher priority jobs to finish'
62 };
63
64 var joblevel = {
65  'F': 'Full backup',
66  'I': 'Incr (since last backup)',
67  'D': 'Diff (since last full backup)',
68  'C': 'verify from catalog',
69  'V': 'verify save (init DB)',
70  'O': 'verify Volume to catalog entries',
71  'd': 'verify Disk attributes to catalog',
72  'A': 'verify data on volume',
73  'B': 'Base level job'
74 };
75
76 var joblevelname = {
77  'F': 'Full',
78  'I': 'Incremental',
79  'D': 'Differential',
80  'B': 'Base'
81 };
82
83
84 var refresh_time = 60000;
85
86 function bweb_refresh() {
87   location.reload(true)
88 }
89 function bweb_add_refresh(){
90         window.setInterval("bweb_refresh()",refresh_time);
91 }
92 function human_size(val)
93 {   
94    if (!val) {
95       return '';
96    }
97    val = parseInt(val);
98    var unit = ['B', 'KB', 'MB', 'GB', 'TB'];
99    var i=0;
100    var format;
101    while (val /1024 > 1) {
102       i++;
103       val /= 1024;
104    }
105
106    var format = (i>0)?1:0;
107    return val.toFixed(format) + ' ' + unit[i];
108 }
109
110 function human_enabled(val)
111 {   
112    if (!val) {
113       return 'no';
114    }
115
116    if (val == 'yes' || val == '1') {
117       return 'yes';
118
119    } else if (val == 'archived' || val == '2') {
120       return 'archived';
121    } else {
122       return 'no';
123    }
124 }
125
126 function human_sec(val)
127 {
128    if (!val) {
129       val = 0;
130    }
131    val = parseInt(val);
132    val /= 60;                   // sec -> min
133    
134    if ((val / 60) <= 1) {
135       return val.toFixed(0) + ' min' + add_s(val) ;
136    }
137
138    val /= 60;                   // min -> hour
139
140    if ((val / 24) <= 1) { 
141       return val.toFixed(0) + ' hour' + add_s(val) ;
142    }
143
144    val /= 24;                   // hour -> day
145
146    if ((val / 365) < 2) { 
147       return val.toFixed(0) + ' day' + add_s(val);
148    }
149
150    val /= 365;
151
152    return val.toFixed(0) + ' year' + add_s(val);
153 }
154
155 function add_s(val)
156 {
157     if (val >= 2) {
158         return "s ";
159     } else {
160         return " ";
161     }
162 }
163
164 function human_sec2(val)
165 {
166    if (!val) {
167       val = 0;
168    }
169    val = parseInt(val);
170    if (val < 60) {
171        return val.toFixed(0) + ' sec' + add_s(val);
172    }
173
174    val /= 60;                   // sec -> min
175    if ((val / 60) <= 1) {
176        return val.toFixed(0) + ' min' + add_s(val);
177    }
178
179    var prev = val % 60;
180    val /= 60;                   // min -> hour
181
182    if ((val / 24) <= 1) { 
183        return val.toFixed(0) + ' hour' + add_s(val) 
184            + prev.toFixed(0) + ' min' + add_s(prev);
185    }
186  
187    prev = val % 24;
188    val /= 24;                   // hour -> day
189
190    if ((val / 365) < 2) { 
191        return val.toFixed(0) + ' day' + add_s(val) 
192            + prev.toFixed(0) + ' hour' + add_s(prev);
193    }
194
195    prev = val % 365;
196    val /= 365;
197
198     return val.toFixed(0) + ' year' + add_s(val) 
199         + prev.toFixed(0) + ' day' + add_s(prev);
200 }
201
202 function human_duration(val)
203 {
204     if (!val) {
205         val = 0;
206     }
207     val = parseInt(val);
208     var sec = val % 60;
209     val = val / 60;
210     var min = val % 60;
211     val = val / 60;
212     return pad(val.toFixed(0)) + ':' + pad(min.toFixed(0)) + ':' + pad(sec.toFixed(0));
213 }
214
215
216 //
217 // percent_display("row2", [ { nb: 1, name: "Full"   },
218 //                         { nb: 2, name: "Error"  },
219 //                         { nb: 5, name: "Append" },
220 //                         { nb: 2, name: "Purged" },
221 //                         {}                               # last element must be {}
222 //                       ]);
223
224 function percent_get_img(type)
225 {
226    var img=document.createElement('img');
227    if (type) {
228       img.className="pSlice" + type ;
229    } else {
230       img.className="pSlice";
231    }
232    img.src="/bweb/pix.png";
233    img.alt="";
234    return img;
235 }
236
237 var percent_display_nb_slice = 20;
238 var percent_usage_nb_slice = 5;
239
240 function percent_display(hash_values, parent)
241 {
242    var nb_elt=percent_display_nb_slice;
243    var tips= "";
244
245    if (!parent) {
246       parent = document.createElement('DIV');
247    }
248
249    if (typeof parent != "object") {
250       parent = document.getElementById(parent);
251    } 
252
253    if (!parent) {
254        alert("E : display_percent(): Can't find parent " + parent);
255        return;
256    }
257
258    hash_values.pop(); // drop last element {}
259
260    var nb_displayed = 0;
261    var nb_max = 0;
262
263    for(var i=0;i<hash_values.length;i++) {
264         nb_max += hash_values[i]['nb'];
265    }
266
267    for(var i=0;i<hash_values.length;i++) {
268         var elt = hash_values[i];
269         var cur_nb = (elt['nb'] * nb_elt)/nb_max;
270         var cur_name = elt['name'];
271         cur_name.replace(/-/,"_");
272
273         tips = tips + " " + elt['nb'] + " " + cur_name;
274
275         while ((nb_displayed < nb_elt) && (cur_nb >=1)) {
276             nb_displayed++;
277             cur_nb--;
278
279             var img= percent_get_img(cur_name);
280             parent.appendChild(img);
281         }       
282    }
283
284    while (nb_displayed < nb_elt) {
285       nb_displayed++;
286       var img= percent_get_img();
287       parent.appendChild(img);
288   }     
289
290   parent.title = tips;
291
292   return parent;
293 }
294
295 function percent_finish(value, corr, parent)
296 {
297    var type;
298
299    var nb = parseInt(value*300/100, 10);
300    var nbp = parseInt(value*100,10)/100;
301    if (nbp > 500) {
302       return;
303    }
304    parent.title = nbp + "% finished (approximate " + (corr).toFixed(2) + ")" ;
305    var img=document.createElement('img');
306    img.className="pSliceFinished";
307    img.src="/bweb/pix.png";
308    img.width=nb;
309    parent.appendChild(img);
310
311    if (value >= 100) {
312       return;
313    }
314
315    nb = parseInt((100-value)*300/100, 10);
316    img=document.createElement('img');
317    img.className="pSliceNotFinished";
318    img.src="/bweb/pix.png";
319    img.width=nb;
320    parent.appendChild(img);       
321 }
322
323 function percent_usage(value, parent)
324 {
325    var nb_elt=percent_usage_nb_slice;
326    var type;
327   
328    if (!parent) {
329       parent = document.createElement('DIV');
330    }   
331
332    if (typeof parent != "object") {
333       parent = document.getElementById(parent);
334    } 
335
336    if (!parent) {
337        alert("E : display_percent(): Can't find parent " + parent);
338        return;
339    }
340
341    if (value >= 500) {
342       return;
343    } else if (value <= 0.001) {
344       type = "Empty";
345       value = 0;      
346    } else if (value <= 40) {
347       type = "Ok";
348    } else if (value <= 75) {
349       type = "Warn";
350    } else if (value <= 85) {
351       type = "Crit";
352    } else {
353       type = "Crit";
354    }
355
356    var nb = parseInt(value*nb_elt/100, 10);
357    parent.title = parseInt(value*100,10)/100 + "% used (approximate)";
358
359    for(var i=0; i<nb; i++) {
360       var img= percent_get_img(type);
361       parent.appendChild(img);
362    }
363
364    for(nb;nb < nb_elt;nb++) {
365       var img= percent_get_img("Empty");
366       parent.appendChild(img);       
367    } 
368
369    return parent;
370 }
371
372 function pad(n){return n<10 ? '0'+n : n}
373
374 function timestamp_to_iso(ts)
375 {
376     if(ts < 1000000000000){
377         ts=(ts*1000);
378     }
379     var datum = new Date(ts);
380     
381     return datum.getFullYear() + '-' + pad(datum.getMonth()+1) + '-' + pad(datum.getDay()+1) + ' ' + pad(datum.getHours()) + ':' + pad(datum.getMinutes()) + ':' + pad(datum.getSeconds());
382 }
383
384 function bweb_get_job_img(status, errors, type)
385 {
386   var ret;
387
388   if (status == "T") {
389      if (errors > 0) {
390         ret = "W.png";
391
392      } else {
393         if (type == 'B' || type == 'R') { // Backup or Restore
394            ret = "T.png";
395
396         } else if (type == 'C') {
397            ret = "CT.png";
398
399         } else {
400            ret = "AT.png";      // Admin, migration, copy etc...
401         }
402      }
403   } else {
404      ret = status + ".png";
405   }
406
407   return bweb_root + ret;
408 }
409
410 function toggle_display(id, arrow) 
411 {
412    var a = document.getElementById(arrow);
413    var e = document.getElementById(id);
414    if(e.style.display == 'block') {
415       e.style.display = 'none';
416       a.src = '/bweb/right.gif';
417    } else {
418       e.style.display = 'block';
419       a.src = '/bweb/down.gif';
420    }
421 }
422
423 function search_media()
424 {
425  var what = document.getElementById('searchbox').value;
426  if (what) {
427    document.search.action.value='media';
428    document.search.re_media.value=what;
429    document.search.submit();
430  }
431 }
432
433 function search_client()
434 {
435  var what = document.getElementById('searchbox').value;
436  if (what) {
437    document.search.action.value='client';
438    document.search.re_client.value=what;
439    document.search.submit();
440  }
441 }
442
443 sfHover = function() {
444  var sfEls = document.getElementById("menu").getElementsByTagName("LI");
445  for (var i=0; i<sfEls.length; i++) {
446     sfEls[i].onmouseover=function() {
447        this.className+=" sfhover";
448     }
449     sfEls[i].onmouseout=function() {
450        this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
451     }
452  }
453 }
454
455 if (window.attachEvent) window.attachEvent("onload", sfHover);