]> git.sur5r.net Git - bacula/bacula/blobdiff - gui/bweb/lib/Bweb.pm
ebl small fix
[bacula/bacula] / gui / bweb / lib / Bweb.pm
index aad116b59589aa8858308000861f1ec7f373cef1..fc70854e55acb1306cc037d3b5c429589025f97c 100644 (file)
@@ -853,7 +853,7 @@ sub transfer
     
     if ($? == 0) {
        my $content = $self->get_slot($src);
-       print "content = $content<br/> $src => $dst<br/>";
+       print "$content ($src) => $dst<br/>";
        $self->{slot}->[$src] = 'empty';
        $self->set_slot($dst, $content);
        return 1;
@@ -1174,6 +1174,10 @@ sub connect_db
            unless ($self->{dbh});
 
        $self->{dbh}->{FetchHashKeyName} = 'NAME_lc';
+
+       if ($self->{info}->{dbi} =~ /^dbi:Pg/i) {
+           $self->{dbh}->do("SET datestyle TO 'ISO, YMD'");
+       }
     }
 }
 
@@ -1329,11 +1333,16 @@ sub get_form
                 priority => 10,
                 age    => 60*60*24*7,
                 days   => 1,
+                maxvoljobs  => 0,
+                maxvolbytes => 0,
+                maxvolfiles => 0,
                 );
 
     my %opt_s = (              # default to ''
                 ach    => 1,
                 status => 1,
+                volstatus => 1,
+                 inchanger => 1,
                  client => 1,
                 level  => 1,
                 pool   => 1,
@@ -1343,6 +1352,7 @@ sub get_form
                 graph  => 1,
                  gtype  => 1,
                  type   => 1,
+                recyclepool => 1,
                 );
     my %opt_p = (              # option with path
                 fileset=> 1,
@@ -1351,6 +1361,11 @@ sub get_form
                 device => 1,
                 );
 
+    my %opt_d = (              # option with date
+                voluseduration=> 1,
+                volretention => 1,
+               );
+
     foreach my $i (@what) {
        if (exists $opt_i{$i}) {# integer param
            my $value = CGI::param($i) || $opt_i{$i} ;
@@ -1383,6 +1398,11 @@ sub get_form
            if ($value =~ /^([\w\d\.\/\s:\@\-]+)$/) {
                $ret{$i} = $1;
            }
+       } elsif (exists $opt_d{$i}) {
+           my $value = CGI::param($i) || '';
+           if ($value =~ /^\s*(\d+\s+\w+)$/) {
+               $ret{$i} = $1;
+           }
        }
     }
 
@@ -1781,7 +1801,11 @@ sub get_param
        my $status = CGI::param('status') || '';
        if ($status =~ /^(\w)$/) {
            $ret{status} = $1;
-           $limit .= "AND Job.JobStatus = '$1' ";
+           if ($1 eq 'f') {
+               $limit .= "AND Job.JobStatus IN ('f','E') ";            
+           } else {
+               $limit .= "AND Job.JobStatus = '$1' ";          
+           }
        }
     }
 
@@ -1909,6 +1933,7 @@ SELECT DISTINCT Job.JobId       AS jobid,
                 JobFiles        AS jobfiles, 
                 JobBytes        AS jobbytes,
                JobStatus       AS jobstatus,
+                JobErrors       AS joberrors,
                 $self->{sql}->{SEC_TO_TIME}(  $self->{sql}->{UNIX_TIMESTAMP}(EndTime)  
                                             - $self->{sql}->{UNIX_TIMESTAMP}(StartTime)) AS duration
 
@@ -2138,6 +2163,37 @@ WHERE Location.Location = $arg->{qlocation}
     $self->display_location();
 }
 
+sub location_del
+{
+    my ($self) = @_ ;
+    my $arg = $self->get_form(qw/qlocation/) ;
+
+    unless ($arg->{qlocation}) {
+       return $self->error("Can't get location");
+    }
+
+    my $query = "
+SELECT count(Media.MediaId) AS nb 
+  FROM Media INNER JOIN Location USING (LocationID)
+WHERE Location = $arg->{qlocation}
+";
+
+    my $res = $self->dbh_selectrow_hashref($query);
+
+    if ($res->{nb}) {
+       return $self->error("Sorry, the location must be empty");
+    }
+
+    $query = "
+DELETE FROM Location WHERE Location = $arg->{qlocation} LIMIT 1
+";
+
+    $self->dbh_do($query);
+
+    $self->display_location();
+}
+
+
 sub location_add
 {
     my ($self) = @_ ;
@@ -2223,82 +2279,6 @@ sub get_media_max_size
     }
 }
 
-sub do_update_media
-{
-    my ($self) = @_ ;
-
-    my $media = CGI::param('media');
-    unless ($media) {
-       return $self->error("Can't find media selection");
-    }
-
-    $media = $self->dbh_quote($media);
-
-    my $update = '';
-
-    my $volstatus = CGI::param('volstatus') || ''; 
-    $volstatus = $self->dbh_quote($volstatus); # is checked by db
-    $update .= " VolStatus=$volstatus, ";
-    
-    my $inchanger = CGI::param('inchanger') || '';
-    if ($inchanger) {
-       $update .= " InChanger=1, " ;
-       my $slot = CGI::param('slot') || '';
-       if ($slot =~ /^(\d+)$/) {
-           $update .= " Slot=$1, ";
-       } else {
-           $update .= " Slot=0, ";
-       }
-    } else {
-       $update = " Slot=0, InChanger=0, ";
-    }
-
-    my $pool = CGI::param('pool') || '';
-    $pool = $self->dbh_quote($pool); # is checked by db
-    $update .= " PoolId=(SELECT PoolId FROM Pool WHERE Name=$pool), ";
-
-    my $volretention = CGI::param('volretention') || '';
-    $volretention = from_human_sec($volretention);
-    unless ($volretention) {
-       return $self->error("Can't get volume retention");
-    }
-
-    $update .= " VolRetention = $volretention, ";
-
-    my $loc = CGI::param('location') || '';
-    $loc = $self->dbh_quote($loc); # is checked by db
-    $update .= " LocationId=(SELECT LocationId FROM Location WHERE Location=$loc), ";
-
-    my $usedu = CGI::param('voluseduration') || '0';
-    $usedu = from_human_sec($usedu);
-    $update .= " VolUseDuration=$usedu, ";
-
-    my $maxj = CGI::param('maxvoljobs') || '0';
-    unless ($maxj =~ /^(\d+)$/) {
-       return $self->error("Can't get max jobs");
-    }
-    $update .= " MaxVolJobs=$1, " ;
-
-    my $maxf = CGI::param('maxvolfiles') || '0';
-    unless ($maxj =~ /^(\d+)$/) {
-       return $self->error("Can't get max files");
-    }
-    $update .= " MaxVolFiles=$1, " ;
-   
-    my $maxb = CGI::param('maxvolbytes') || '0';
-    unless ($maxb =~ /^(\d+)$/) {
-       return $self->error("Can't get max bytes");
-    }
-    $update .= " MaxVolBytes=$1 " ;
-    
-    my $row=$self->dbh_do("UPDATE Media SET $update WHERE VolumeName=$media");
-    
-    if ($row) {
-       print "Update Ok\n";
-       $self->update_media();
-    }
-}
-
 sub update_media
 {
     my ($self) = @_ ;
@@ -2320,7 +2300,9 @@ SELECT Media.Slot         AS slot,
        Media.MaxVolJobs   AS maxvoljobs,
        Media.MaxVolFiles  AS maxvolfiles,
        Media.VolUseDuration AS voluseduration,
-       Media.VolRetention AS volretention
+       Media.VolRetention AS volretention,
+       Media.Comment      AS comment,
+       Media.RecyclePoolId AS recyclepoolid
 
 FROM Media INNER JOIN Pool ON (Media.PoolId = Pool.PoolId)
            LEFT  JOIN Location ON (Media.LocationId = Location.LocationId)
@@ -2364,7 +2346,9 @@ sub save_location
 
     my $nb = $self->dbh_do($query);
 
-    print "$nb media updated";
+    print "$nb media updated, you may have to update your autochanger.";
+
+    $self->display_media();
 }
 
 sub change_location
@@ -2447,9 +2431,9 @@ sub display_pool
 # TODO : afficher les tailles et les dates
 
     my $query = "
-SELECT sum(subq.volmax)   AS volmax,
-       sum(subq.volnum)   AS volnum,
-       sum(subq.voltotal) AS voltotal,
+SELECT subq.volmax        AS volmax,
+       subq.volnum        AS volnum,
+       subq.voltotal      AS voltotal,
        Pool.Name          AS name,
        Pool.Recycle       AS recycle,
        Pool.VolRetention  AS volretention,
@@ -2472,16 +2456,28 @@ FROM
               WHERE Media.VolStatus = 'Full' 
               GROUP BY Media.MediaType
                ) AS media_avg_size ON (Media.MediaType = media_avg_size.MediaType)
-    GROUP BY Media.MediaType, Media.PoolId
-  ) AS subq 
-INNER JOIN Pool ON (Pool.PoolId = subq.PoolId) 
-GROUP BY subq.PoolId
+    GROUP BY Media.MediaType, Media.PoolId, media_avg_size.volavg
+  ) AS subq
+LEFT JOIN Pool ON (Pool.PoolId = subq.PoolId)
 ";
 
     my $all = $self->dbh_selectall_hashref($query, 'name') ;
 
+    $query = "
+SELECT Pool.Name AS name,
+       sum(VolBytes) AS size
+FROM   Media JOIN Pool ON (Media.PoolId = Pool.PoolId)
+WHERE  Media.VolStatus IN ('Recycled', 'Purged')
+GROUP BY Pool.Name;
+";
+    my $empty = $self->dbh_selectall_hashref($query, 'name');
+
     foreach my $p (values %$all) {
-       if ($p->{volmax}) {
+       if ($p->{volmax} > 0) { # mysql returns 0.0000
+           # we remove Recycled/Purged media from pool usage
+           if (defined $empty->{$p->{name}}) {
+               $p->{voltotal} -= $empty->{$p->{name}}->{size};
+           }
            $p->{poolusage} = sprintf('%.2f', $p->{voltotal} * 100/ $p->{volmax}) ;
        } else {
            $p->{poolusage} = 0;
@@ -2568,17 +2564,12 @@ WHERE JobStatus IN ('C','R','B','e','D','F','S','m','M','s','j','c','d','t','p')
 sub eject_media
 {
     my ($self) = @_;
-    my $arg = $self->get_form('jmedias', 'slots', 'ach');
+    my $arg = $self->get_form('jmedias');
 
     unless ($arg->{jmedias}) {
        return $self->error("Can't get media selection");
     }
 
-    my $a = $self->ach_get($arg->{ach});
-    unless ($a) {
-       return 0;
-    }
-    
     my $query = "
 SELECT Media.VolumeName  AS volumename,
        Storage.Name      AS storage,
@@ -2592,9 +2583,15 @@ WHERE Media.VolumeName IN ($arg->{jmedias})
 
     my $all = $self->dbh_selectall_hashref($query, 'volumename');
 
-    $a->status();
-
     foreach my $vol (values %$all) {
+       my $a = $self->ach_get($vol->{location});
+       next unless ($a) ;
+
+       unless ($a->{have_status}) {
+           $a->status();
+           $a->{have_status} = 1;
+       }
+
        print "eject $vol->{volumename} from $vol->{storage} : ";
        if ($a->send_to_io($vol->{slot})) {
            print "ok</br>";
@@ -2604,6 +2601,23 @@ WHERE Media.VolumeName IN ($arg->{jmedias})
     }
 }
 
+sub move_email
+{
+    my ($self) = @_;
+
+    my ($to, $subject, $content) = (CGI::param('email'),
+                                   CGI::param('subject'),
+                                   CGI::param('content'));
+    $to =~ s/[^\w\d\.\@<>,]//;
+    $subject =~ s/[^\w\d\.\[\]]/ /;    
+
+    open(MAIL, "|mail -s '$subject' '$to'") ;
+    print MAIL $content;
+    close(MAIL);
+
+    print "Mail sent";
+}
+
 sub restore
 {
     my ($self) = @_;
@@ -2757,25 +2771,120 @@ sub delete
        my $ret = $b->send_cmd("delete jobid=\"$arg->{jobid}\"");
 
        $self->display({
-           content => $b->send_cmd("delete jobid=\"$arg->{jobid}\""),
+           content => $ret,
            title => "Delete a job ",
            name => "delete jobid=$arg->{jobid}",
        }, "command.tpl");      
     }
 }
 
+sub do_update_media
+{
+    my ($self) = @_ ;
+
+    my $arg = $self->get_form(qw/media volstatus inchanger pool
+                                slot volretention voluseduration 
+                                maxvoljobs maxvolfiles maxvolbytes
+                                qcomment recyclepool
+                             /);
+
+    unless ($arg->{media}) {
+       return $self->error("Can't find media selection");
+    }
+
+    my $update = "update volume=$arg->{media} ";
+
+    if ($arg->{volstatus}) {
+       $update .= " volstatus=$arg->{volstatus} ";
+    }
+    
+    if ($arg->{inchanger}) {
+       $update .= " inchanger=yes " ;
+       if ($arg->{slot}) {
+           $update .= " slot=$arg->{slot} ";
+       }
+    } else {
+       $update .= " slot=0 inchanger=no ";
+    }
+
+    if ($arg->{pool}) {
+       $update .= " pool=$arg->{pool} " ;
+    }
+
+    $arg->{volretention} ||= 0 ; 
+    if ($arg->{volretention}) {
+       $update .= " volretention=\"$arg->{volretention}\" " ;
+    }
+
+    $arg->{voluseduration} ||= 0 ; 
+    if ($arg->{voluseduration}) {
+       $update .= " voluse=\"$arg->{voluseduration}\" " ;
+    }
+
+    $arg->{maxvoljobs} ||= 0;
+    if ($arg->{maxvoljobs}) {
+       $update .= " maxvoljobs=$arg->{maxvoljobs} " ;
+    }
+    
+    $arg->{maxvolfiles} ||= 0;
+    if ($arg->{maxvolfiles}) {
+       $update .= " maxvolfiles=$arg->{maxvolfiles} " ;
+    }    
+
+    $arg->{maxvolbytes} ||= 0;
+    if ($arg->{maxvolbytes}) {
+       $update .= " maxvolbytes=$arg->{maxvolbytes} " ;
+    }    
+
+    my $b = $self->get_bconsole();
+
+    $self->display({
+       content => $b->send_cmd($update),
+       title => "Update a volume ",
+       name => $update,
+    }, "command.tpl"); 
+
+
+    my @q;
+    my $media = $self->dbh_quote($arg->{media});
+
+    my $loc = CGI::param('location') || '';
+    if ($loc) {
+       $loc = $self->dbh_quote($loc); # is checked by db
+       push @q, "LocationId=(SELECT LocationId FROM Location WHERE Location=$loc)";
+    }
+    if ($arg->{recyclepool}) {
+       push @q, "RecyclePoolId=(SELECT PoolId FROM Pool WHERE Name='$arg->{recyclepool}')";
+    }
+    if (!$arg->{qcomment}) {
+       $arg->{qcomment} = "''";
+    }
+    push @q, "Comment=$arg->{qcomment}";
+    
+
+    my $query = "
+UPDATE Media 
+   SET " . join (',', @q) . "
+ WHERE Media.VolumeName = $media
+";
+    $self->dbh_do($query);
+
+    $self->update_media();
+}
+
 sub update_slots
 {
     my ($self) = @_;
 
     my $ach = CGI::param('ach') ;
-    unless ($ach =~ /^([\w\d\.-]+)$/) {
+    $ach = $self->ach_get($ach);
+    unless ($ach) {
        return $self->error("Bad autochanger name");
     }
 
     print "<pre>";
     my $b = new Bconsole(pref => $self->{info},timeout => 60,log_stdout => 1);
-    $b->update_slots($ach);
+    $b->update_slots($ach->{name});
     print "</pre>\n" 
 }
 
@@ -2804,10 +2913,15 @@ SELECT Job.Name as name, Client.Name as clientname
 
     $query = "
 SELECT Time AS time, LogText AS log
- FROM  Log
- WHERE JobId = $arg->{jobid}
- ORDER BY Time
+ FROM  Log INNER JOIN Job ON (Job.JobId = Log.JobId)
+ WHERE Log.JobId = $arg->{jobid}
+    OR (    Log.JobId = 0 
+        AND Log.Time >= Job.StartTime
+        AND Log.Time <= COALESCE(Job.EndTime, Now())
+       )
+ ORDER BY LogId
 ";
+
     my $log = $self->dbh_selectall_arrayref($query);
     unless ($log) {
        return $self->error("Can't get log for jobid $arg->{jobid}");