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', 'pathid', 'filenameid');
53 my $where = $arg->{where};
54 my $jobid = $arg->{jobid};
55 my $pathid = $arg->{pathid};
56 my $fnid = $arg->{filenameid};
57 my $jobid_url = "jobid=$jobid";
60 my $batch = CGI::param("mode") || '';
62 my $md5_rep = md5_hex("$where:$jobid") ;
63 my $base_url = '/bweb/fv' ;
64 my $base_fich = $conf->{fv_write_path};
66 if ($where and $jobid and $batch eq 'batch') {
67 my $root = fv_get_root_pathid($where);
69 fv_compute_size($jobid, $root);
75 print CGI::header('text/html');
76 $bweb->display_begin();
77 $bweb->display_job_zoom($jobid);
79 unless (($where or $pathid) and $jobid) {
80 $bweb->error("Can't get where or jobid");
84 unless ($base_fich and -w $base_fich) {
85 $bweb->error("fv_write_path ($base_fich) is not writable." .
86 " See Bweb configuration.");
90 if (-f "$base_fich/$md5_rep.png" and -f "$base_fich/$md5_rep.tpl")
92 $bweb->display({}, "$base_fich/$md5_rep.tpl");
97 if ($fnid and $pathid)
99 my $attribs = fv_get_file_attribute_from_id($jobid, $pathid, $fnid);
100 if ($attribs->{found}) {
101 $bweb->display($attribs, 'fv_file_attribs.tpl');
102 $bweb->display_end();
107 my $attribs = fv_get_file_attribute($jobid, $where);
108 if ($attribs->{found}) {
109 $bweb->display($attribs, 'fv_file_attribs.tpl');
110 $bweb->display_end();
114 if ($where !~ m!/$!) {
115 $where = $where . "/" ;
122 $where = fv_get_root_path($pathid);
124 $root = fv_get_root_pathid($where);
128 $bweb->error("Can't find $where in catalog");
129 $bweb->display_end();
133 my $total = fv_compute_size($jobid, $root);
135 my $url_action = "bfileview.pl?opt_level=$opt_level" ;
136 my $top = new CCircle(
138 base_url => "$url_action;pathid=$root;$jobid_url;where=$where",
141 fv_display_rep($top, $total, $root, $opt_level) ;
143 $top->draw_labels() ;
144 $top->set_title(Bweb::human_size($total)) ;
146 open(OUT, ">$base_fich/$md5_rep.png") or die "$base_fich/$md5_rep.png $!";
147 # make sure we are writing to a binary stream
149 # Convert the image to PNG and print it on standard output
150 print OUT $CCircle::gd->png;
153 open(OUT, ">$base_fich/$md5_rep.tpl") or die "$base_fich/$md5_rep.tpl $!";
155 <form action='$url_action' method='get'>
157 <input title='jobids' type='hidden' name='jobid' value='$jobid'>
158 <input title='repertoire' type='text' name='where' value='$where'/>
159 <input type='submit' size='256' name='go' value='go'/>
165 print OUT $top->get_imagemap($where, "$base_url/$md5_rep.png") ;
168 $bweb->display({}, "$base_fich/$md5_rep.tpl");
169 $bweb->display_end();
173 my ($ccircle, $max, $rep, $level) = @_ ;
174 return if ($max < 1);
177 my $dirs = fv_list_dirs($jobid, $rep); # 0: pathid, 1: pathname
179 foreach my $dir (@{$dirs})
181 my $size = fv_compute_size($jobid, $dir->[0]);
184 my $per = $size * 100 / $max;
185 # can't use pathname when using utf or accent
187 $ccircle->{base_url} =~ s/pathid=\d+;/pathid=$dir->[0];/;
189 my $chld = $ccircle->add_part($per,
190 basename($dir->[1]) . '/',
192 . sprintf(' %.0f%% ', $per)
193 . Bweb::human_size($size)
196 if ($chld && $level > 0) {
197 fv_display_rep($chld, $size, $dir->[0], $level - 1) ;
201 # 0: name, 1: size, 2: filenameid
202 my $files = fv_get_big_files($jobid, $rep, 3*100/$max, $max_file/($level+1));
203 foreach my $f (@{$files}) {
204 $ccircle->{base_url} =~ s/pathid=\d+;(filenameid=\d+;)?/pathid=$rep;filenameid=$f->[2];/;
205 $ccircle->add_part($f->[1] * 100 / $max,
207 $f->[0] . "\n" . Bweb::human_size($f->[1]));
212 $ccircle->add_part(($max - $sum) * 100 / $max,
214 "other\n" . Bweb::human_size($max - $sum));
217 $ccircle->finalize() ;
222 my ($jobid, $rep) = @_;
224 my $size = fv_get_size($jobid, $rep);
229 $size = fv_get_files_size($jobid, $rep);
231 my $dirs = fv_list_dirs($jobid, $rep);
232 foreach my $dir (@{$dirs}) {
233 $size += fv_compute_size($jobid, $dir->[0]);
236 fv_update_size($jobid, $rep, $size);
242 my ($jobid, $rep) = @_;
244 my $ret = $bweb->dbh_selectall_arrayref("
246 ( SELECT Path FROM Path WHERE PathId = P.PathId) AS Path
249 FROM brestore_pathvisibility
250 INNER JOIN brestore_pathhierarchy USING (PathId)
259 sub fv_get_file_attribute
261 my ($jobid, $full_name) = @_;
263 my $filename = $bweb->dbh_quote(basename($full_name));
264 my $path = $bweb->dbh_quote(dirname($full_name) . "/");
266 my $attr = $bweb->dbh_selectrow_hashref("
269 base64_decode_lstat(8, LStat) AS size,
270 base64_decode_lstat(11, LStat) AS atime,
271 base64_decode_lstat(12, LStat) AS mtime,
272 base64_decode_lstat(13, LStat) AS ctime
274 FROM File INNER JOIN Filename USING (FilenameId)
275 INNER JOIN Path USING (PathId)
276 WHERE Name = $filename
281 $attr->{filename} = $full_name;
282 $attr->{size} = Bweb::human_size($attr->{size});
283 foreach my $d (qw/atime ctime mtime/) {
284 $attr->{$d} = strftime('%F %H:%M', localtime($attr->{$d}));
290 sub fv_get_file_attribute_from_id
292 my ($jobid, $pathid, $filenameid) = @_;
294 my $attr = $bweb->dbh_selectrow_hashref("
297 base64_decode_lstat(8, LStat) AS size,
298 base64_decode_lstat(11, LStat) AS atime,
299 base64_decode_lstat(12, LStat) AS mtime,
300 base64_decode_lstat(13, LStat) AS ctime,
301 Path.Path || Filename.Name AS filename
303 FROM File INNER JOIN Filename USING (FilenameId)
304 INNER JOIN Path USING (PathId)
305 WHERE FilenameId = $filenameid
310 $attr->{size} = Bweb::human_size($attr->{size});
311 foreach my $d (qw/atime ctime mtime/) {
312 $attr->{$d} = strftime('%F %H:%M', localtime($attr->{$d}));
319 my ($jobid, $rep) = @_;
321 my $ret = $bweb->dbh_selectrow_hashref("
323 FROM brestore_pathvisibility
331 sub fv_get_files_size
333 my ($jobid, $rep) = @_;
335 my $ret = $bweb->dbh_selectrow_hashref("
336 SELECT sum(base64_decode_lstat(8,LStat)) AS size
347 my ($jobid, $rep, $min, $limit) = @_;
349 my $ret = $bweb->dbh_selectall_arrayref("
350 SELECT Name AS name, size, FilenameId AS filenameid
352 SELECT FilenameId,base64_decode_lstat(8,LStat) AS size
356 ) AS S INNER JOIN Filename USING (FilenameId)
367 my ($jobid, $rep, $size) = @_;
369 my $nb = $bweb->dbh_do("
370 UPDATE brestore_pathvisibility SET Size = $size
378 sub fv_get_root_pathid
381 $path = $bweb->dbh_quote($path);
382 my $ret = $bweb->dbh_selectrow_hashref("SELECT PathId FROM Path WHERE Path = $path");
383 return $ret->{pathid};
389 my $ret = $bweb->dbh_selectrow_hashref("SELECT Path FROM Path WHERE PathId = $pathid");
396 CREATE OR REPLACE FUNCTION base64_decode_lstat(int4, varchar) RETURNS int8 AS $$
403 size := split_part($2, ' ', $1);
404 b64 := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
406 FOR i IN 1..length(size) LOOP
407 val := val + (strpos(b64, substr(size, i, 1))-1) * (64^(length(size)-i));
411 $$ language 'plpgsql';
413 ALTER TABLE brestore_pathvisibility ADD Size int8;
417 ALTER TABLE brestore_pathvisibility ADD Files int4;