5 Bweb - A Bacula web interface
6 Bacula® - The Network Backup Solution
8 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
10 The main author of Bweb is Eric Bollengier.
11 The main author of Bacula is Kern Sibbald, with contributions from
12 many others, a complete list can be found in the file AUTHORS.
14 This program is Free Software; you can redistribute it and/or
15 modify it under the terms of version two of the GNU General Public
16 License as published by the Free Software Foundation plus additions
17 that are listed in the file LICENSE.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 Bacula® is a registered trademark of John Walker.
30 The licensor of Bacula is the Free Software Foundation Europe
31 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
32 Switzerland, email:ftf@fsfeurope.org.
41 use POSIX qw/strftime/;
44 use Digest::MD5 qw(md5_hex);
45 use File::Basename qw/basename dirname/;
47 my $conf = new Bweb::Config(config_file => $Bweb::config_file);
49 my $bweb = new Bweb(info => $conf);
52 my $arg = $bweb->get_form('where', 'jobid');
53 my $where = $arg->{where};
54 my $jobid = $arg->{jobid};
55 my $jobid_url = "jobid=$jobid";
58 my $batch = CGI::param("mode") || '';
60 my $md5_rep = md5_hex("$where:$jobid") ;
61 my $base_url = '/bweb/fv' ;
62 my $base_fich = $conf->{fv_write_path};
64 if ($where and $jobid and $batch eq 'batch') {
65 my $root = fv_get_root_pathid($where);
67 fv_compute_size($jobid, $root);
73 print CGI::header('text/html');
74 $bweb->display_begin();
75 $bweb->display_job_zoom($jobid);
77 unless ($where and $jobid) {
78 $bweb->error("Can't get where or jobid");
82 unless ($base_fich and -w $base_fich) {
83 $bweb->error("fv_write_path ($base_fich) is not writable." .
84 " See Bweb configuration.");
88 if (-f "$base_fich/$md5_rep.png" and -f "$base_fich/$md5_rep.tpl")
90 $bweb->display({}, "$base_fich/$md5_rep.tpl");
95 my $attribs = fv_get_file_attribute($jobid, $where);
96 if ($attribs->{found}) {
97 $bweb->display($attribs, 'fv_file_attribs.tpl');
102 if ($where !~ m!/$!) {
103 $where = $where . "/" ;
106 my $root = fv_get_root_pathid($where);
108 $bweb->error("Can't find $where in catalog");
109 $bweb->display_end();
113 my $total = fv_compute_size($jobid, $root);
115 my $url_action = "bfileview.pl?opt_level=$opt_level" ;
116 my $top = new CCircle(
118 base_url => "$url_action;$jobid_url;where=$where",
121 fv_display_rep($top, $total, $root, $opt_level) ;
123 $top->draw_labels() ;
124 $top->set_title(Bweb::human_size($total)) ;
126 open(OUT, ">$base_fich/$md5_rep.png") or die "$base_fich/$md5_rep.png $!";
127 # make sure we are writing to a binary stream
129 # Convert the image to PNG and print it on standard output
130 print OUT $CCircle::gd->png;
133 open(OUT, ">$base_fich/$md5_rep.tpl") or die "$base_fich/$md5_rep.tpl $!";
135 <form action='$url_action' method='get'>
137 <input title='jobids' type='hidden' name='jobid' value='$jobid'>
138 <input title='repertoire' type='text' name='where' value='$where'/>
139 <input type='submit' size='256' name='go' value='go'/>
145 print OUT $top->get_imagemap($where, "$base_url/$md5_rep.png") ;
148 $bweb->display({}, "$base_fich/$md5_rep.tpl");
149 $bweb->display_end();
153 my ($ccircle, $max, $rep, $level) = @_ ;
154 return if ($max < 1);
157 my $dirs = fv_list_dirs($jobid, $rep); # 0: pathid, 1: pathname
159 foreach my $dir (@{$dirs})
161 my $size = fv_compute_size($jobid, $dir->[0]);
164 my $per = $size * 100 / $max;
165 my $chld = $ccircle->add_part($per,
166 basename($dir->[1]) . '/',
168 . sprintf(' %.0f%% ', $per)
169 . Bweb::human_size($size)
172 if ($chld and $level > 0) {
173 fv_display_rep($chld, $size, $dir->[0], $level - 1) ;
178 my $files = fv_get_big_files($jobid, $rep, 3*100/$max, $max_file/($level+1));
179 foreach my $f (@{$files}) {
180 $ccircle->add_part($f->[1] * 100 / $max,
182 $f->[0] . "\n" . Bweb::human_size($f->[1]));
187 $ccircle->add_part(($max - $sum) * 100 / $max,
189 "other\n" . Bweb::human_size($max - $sum));
192 $ccircle->finalize() ;
197 my ($jobid, $rep) = @_;
199 my $size = fv_get_size($jobid, $rep);
204 $size = fv_get_files_size($jobid, $rep);
206 my $dirs = fv_list_dirs($jobid, $rep);
207 foreach my $dir (@{$dirs}) {
208 $size += fv_compute_size($jobid, $dir->[0]);
211 fv_update_size($jobid, $rep, $size);
217 my ($jobid, $rep) = @_;
219 my $ret = $bweb->dbh_selectall_arrayref("
222 SELECT Path FROM Path WHERE PathId = P.PathId
224 SELECT Path FROM brestore_missing_path WHERE PathId = P.PathId
228 FROM brestore_pathvisibility
229 INNER JOIN brestore_pathhierarchy USING (PathId)
238 sub fv_get_file_attribute
240 my ($jobid, $full_name) = @_;
242 my $filename = $bweb->dbh_quote(basename($full_name));
243 my $path = $bweb->dbh_quote(dirname($full_name) . "/");
245 my $attr = $bweb->dbh_selectrow_hashref("
248 base64_decode_lstat(8, LStat) AS size,
249 base64_decode_lstat(11, LStat) AS atime,
250 base64_decode_lstat(12, LStat) AS mtime,
251 base64_decode_lstat(13, LStat) AS ctime
253 FROM File INNER JOIN Filename USING (FilenameId)
254 INNER JOIN Path USING (PathId)
255 WHERE Name = $filename
260 $attr->{filename} = $full_name;
261 $attr->{size} = Bweb::human_size($attr->{size});
262 foreach my $d (qw/atime ctime mtime/) {
263 $attr->{$d} = strftime('%F %H:%M', localtime($attr->{$d}));
270 my ($jobid, $rep) = @_;
272 my $ret = $bweb->dbh_selectrow_hashref("
274 FROM brestore_pathvisibility
282 sub fv_get_files_size
284 my ($jobid, $rep) = @_;
286 my $ret = $bweb->dbh_selectrow_hashref("
287 SELECT sum(base64_decode_lstat(8,LStat)) AS size
298 my ($jobid, $rep, $min, $limit) = @_;
300 my $ret = $bweb->dbh_selectall_arrayref("
303 SELECT FilenameId,base64_decode_lstat(8,LStat) AS size
307 ) AS S INNER JOIN Filename USING (FilenameId)
318 my ($jobid, $rep, $size) = @_;
320 my $nb = $bweb->dbh_do("
321 UPDATE brestore_pathvisibility SET Size = $size
329 sub fv_get_root_pathid
332 $path = $bweb->dbh_quote($path);
333 my $ret = $bweb->dbh_selectrow_hashref("
334 SELECT PathId FROM Path WHERE Path = $path
336 SELECT PathId FROM brestore_missing_path WHERE PATH = $path
338 return $ret->{pathid};
343 CREATE OR REPLACE FUNCTION base64_decode_lstat(int4, varchar) RETURNS int8 AS $$
350 size := split_part($2, ' ', $1);
351 b64 := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
353 FOR i IN 1..length(size) LOOP
354 val := val + (strpos(b64, substr(size, i, 1))-1) * (64^(length(size)-i));
358 $$ language 'plpgsql';
360 ALTER TABLE brestore_pathvisibility ADD Size int8;
364 ALTER TABLE brestore_pathvisibility ADD Files int4;