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 (-w $base_fich) {
83 $bweb->error("$base_fich is not writable");
87 if (-f "$base_fich/$md5_rep.png" and -f "$base_fich/$md5_rep.tpl")
89 $bweb->display({}, "$base_fich/$md5_rep.tpl");
94 my $attribs = fv_get_file_attribute($jobid, $where);
95 if ($attribs->{found}) {
96 $bweb->display($attribs, 'fv_file_attribs.tpl');
101 if ($where !~ m!/$!) {
102 $where = $where . "/" ;
105 my $root = fv_get_root_pathid($where);
107 $bweb->error("Can't find $where in catalog");
108 $bweb->display_end();
112 my $total = fv_compute_size($jobid, $root);
114 my $url_action = "bfileview.pl?opt_level=$opt_level" ;
115 my $top = new CCircle(
117 base_url => "$url_action;$jobid_url;where=$where",
120 fv_display_rep($top, $total, $root, $opt_level) ;
122 $top->draw_labels() ;
123 $top->set_title(Bweb::human_size($total)) ;
125 open(OUT, ">$base_fich/$md5_rep.png") or die "$base_fich/$md5_rep.png $!";
126 # make sure we are writing to a binary stream
128 # Convert the image to PNG and print it on standard output
129 print OUT $CCircle::gd->png;
132 open(OUT, ">$base_fich/$md5_rep.tpl") or die "$base_fich/$md5_rep.tpl $!";
134 <form action='$url_action' method='get'>
136 <input title='jobids' type='hidden' name='jobid' value='$jobid'>
137 <input title='repertoire' type='text' name='where' value='$where'/>
138 <input type='submit' size='256' name='go' value='go'/>
144 print OUT $top->get_imagemap($where, "$base_url/$md5_rep.png") ;
147 $bweb->display({}, "$base_fich/$md5_rep.tpl");
148 $bweb->display_end();
152 my ($ccircle, $max, $rep, $level) = @_ ;
153 return if ($max < 1);
156 my $dirs = fv_list_dirs($jobid, $rep); # 0: pathid, 1: pathname
158 foreach my $dir (@{$dirs})
160 my $size = fv_compute_size($jobid, $dir->[0]);
163 my $per = $size * 100 / $max;
164 my $chld = $ccircle->add_part($per,
165 basename($dir->[1]) . '/',
167 . sprintf(' %.0f%% ', $per)
168 . Bweb::human_size($size)
171 if ($chld and $level > 0) {
172 fv_display_rep($chld, $size, $dir->[0], $level - 1) ;
177 my $files = fv_get_big_files($jobid, $rep, 3*100/$max, $max_file/($level+1));
178 foreach my $f (@{$files}) {
179 $ccircle->add_part($f->[1] * 100 / $max,
181 $f->[0] . "\n" . Bweb::human_size($f->[1]));
186 $ccircle->add_part(($max - $sum) * 100 / $max,
188 "other\n" . Bweb::human_size($max - $sum));
191 $ccircle->finalize() ;
196 my ($jobid, $rep) = @_;
198 my $size = fv_get_size($jobid, $rep);
203 $size = fv_get_files_size($jobid, $rep);
205 my $dirs = fv_list_dirs($jobid, $rep);
206 foreach my $dir (@{$dirs}) {
207 $size += fv_compute_size($jobid, $dir->[0]);
210 fv_update_size($jobid, $rep, $size);
216 my ($jobid, $rep) = @_;
218 my $ret = $bweb->dbh_selectall_arrayref("
221 SELECT Path FROM Path WHERE PathId = P.PathId
223 SELECT Path FROM brestore_missing_path WHERE PathId = P.PathId
227 FROM brestore_pathvisibility
228 INNER JOIN brestore_pathhierarchy USING (PathId)
237 sub fv_get_file_attribute
239 my ($jobid, $full_name) = @_;
241 my $filename = $bweb->dbh_quote(basename($full_name));
242 my $path = $bweb->dbh_quote(dirname($full_name) . "/");
244 my $attr = $bweb->dbh_selectrow_hashref("
247 base64_decode_lstat(8, LStat) AS size,
248 base64_decode_lstat(11, LStat) AS atime,
249 base64_decode_lstat(12, LStat) AS mtime,
250 base64_decode_lstat(13, LStat) AS ctime
252 FROM File INNER JOIN Filename USING (FilenameId)
253 INNER JOIN Path USING (PathId)
254 WHERE Name = $filename
259 $attr->{filename} = $full_name;
260 $attr->{size} = Bweb::human_size($attr->{size});
261 foreach my $d (qw/atime ctime mtime/) {
262 $attr->{$d} = strftime('%F %H:%M', localtime($attr->{$d}));
269 my ($jobid, $rep) = @_;
271 my $ret = $bweb->dbh_selectrow_hashref("
273 FROM brestore_pathvisibility
281 sub fv_get_files_size
283 my ($jobid, $rep) = @_;
285 my $ret = $bweb->dbh_selectrow_hashref("
286 SELECT sum(base64_decode_lstat(8,LStat)) AS size
297 my ($jobid, $rep, $min, $limit) = @_;
299 my $ret = $bweb->dbh_selectall_arrayref("
302 SELECT FilenameId,base64_decode_lstat(8,LStat) AS size
306 ) AS S INNER JOIN Filename USING (FilenameId)
317 my ($jobid, $rep, $size) = @_;
319 my $nb = $bweb->dbh_do("
320 UPDATE brestore_pathvisibility SET Size = $size
328 sub fv_get_root_pathid
331 $path = $bweb->dbh_quote($path);
332 my $ret = $bweb->dbh_selectrow_hashref("
333 SELECT PathId FROM Path WHERE Path = $path
335 SELECT PathId FROM brestore_missing_path WHERE PATH = $path
337 return $ret->{pathid};
342 CREATE OR REPLACE FUNCTION base64_decode_lstat(int4, varchar) RETURNS int8 AS $$
349 size := split_part($2, ' ', $1);
350 b64 := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
352 FOR i IN 1..length(size) LOOP
353 val := val + (strpos(b64, substr(size, i, 1))-1) * (64^(length(size)-i));
357 $$ language 'plpgsql';
359 ALTER TABLE brestore_pathvisibility ADD Size int8;
363 ALTER TABLE brestore_pathvisibility ADD Files int4;