]> git.sur5r.net Git - bacula/bacula/blobdiff - gui/bweb/lib/Bweb.pm
ebl display f and E state on error
[bacula/bacula] / gui / bweb / lib / Bweb.pm
index 10a1c1285becf8b71581035ec86fa1e760a7d6ee..03c109b32c9e426081f8d6e9b747751cdbd7a1f4 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;
@@ -952,8 +952,7 @@ WHERE Media.VolumeName IN ($media_list)
                }
                
                $all->{$vol}->{realslot} = $slot;
-               $all->{$vol}->{volbytes} = Bweb::human_size($all->{$vol}->{volbytes}) ;
-               
+
                push @{ $param }, $all->{$vol};
 
            } else {            # empty or no label
@@ -1025,8 +1024,10 @@ our %sql_func = (
              MATCH => " ~ ",
              STARTTIME_DAY  => " date_trunc('day', Job.StartTime) ",
              STARTTIME_HOUR => " date_trunc('hour', Job.StartTime) ",
+             STARTTIME_MONTH  => " date_trunc('month', Job.StartTime) ",
              STARTTIME_PHOUR=> " date_part('hour', Job.StartTime) ",
              STARTTIME_PDAY => " date_part('day', Job.StartTime) ",
+             STARTTIME_PMONTH => " date_part('month', Job.StartTime) ",
          },
          mysql => {
              UNIX_TIMESTAMP => 'UNIX_TIMESTAMP',
@@ -1037,8 +1038,10 @@ our %sql_func = (
              MATCH => " REGEXP ",
              STARTTIME_DAY  => " DATE_FORMAT(StartTime, '%Y-%m-%d') ",
              STARTTIME_HOUR => " DATE_FORMAT(StartTime, '%Y-%m-%d %H') ",
+             STARTTIME_MONTH => " DATE_FORMAT(StartTime, '%Y-%m') ",
              STARTTIME_PHOUR=> " DATE_FORMAT(StartTime, '%H') ",
              STARTTIME_PDAY => " DATE_FORMAT(StartTime, '%d') ",
+             STARTTIME_PMONTH => " DATE_FORMAT(StartTime, '%m') ",
          },
         );
 
@@ -1235,11 +1238,6 @@ $where
 
     my $all = $self->dbh_selectall_hashref($query, 'name') ;
 
-    foreach (values %$all) {
-       $_->{fileretention} = human_sec($_->{fileretention});
-       $_->{jobretention} = human_sec($_->{jobretention});
-    }
-
     my $dsp = { ID => $cur_id++,
                clients => [ values %$all] };
 
@@ -1347,6 +1345,7 @@ sub get_form
                  type   => 1,
                 );
     my %opt_p = (              # option with path
+                fileset=> 1,
                 mtxcmd => 1,
                 precmd => 1,
                 device => 1,
@@ -1445,7 +1444,6 @@ FROM FileSet
 
        $ret{db_filesets} = [sort {lc($a->{fileset}) cmp lc($b->{fileset}) } 
                               values %$filesets] ;
-
     }
 
     if ($what{db_jobnames}) {
@@ -1458,7 +1456,6 @@ FROM Job
 
        $ret{db_jobnames} = [sort {lc($a->{jobname}) cmp lc($b->{jobname}) } 
                               values %$jobnames] ;
-
     }
 
     if ($what{db_devices}) {
@@ -1471,7 +1468,6 @@ FROM Device
 
        $ret{db_devices} = [sort {lc($a->{name}) cmp lc($b->{name}) } 
                               values %$devices] ;
-
     }
 
     return \%ret;
@@ -1481,9 +1477,10 @@ sub display_graph
 {
     my ($self) = @_;
 
-    my $fields = $self->get_form(qw/age level status clients filesets graph gtype type
-                                  db_clients limit db_filesets width height
-                                  qclients qfilesets qjobnames db_jobnames/);
+    my $fields = $self->get_form(qw/age level status clients filesets 
+                                    graph gtype type
+                                   db_clients limit db_filesets width height
+                                   qclients qfilesets qjobnames db_jobnames/);
                                
 
     my $url = CGI::url(-full => 0,
@@ -1530,10 +1527,6 @@ SELECT DISTINCT Job.JobId       AS jobid,
 
     my $all = $self->dbh_selectall_hashref($query, 'jobid') ;
 
-    foreach (values %$all) {
-       $_->{jobbytes} = human_size($_->{jobbytes}) ;
-    }
-
     $self->display({ clientname => $arg{clientname},
                     Filter => $label,
                     ID => $cur_id++,
@@ -1788,7 +1781,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' ";          
+           }
        }
     }
 
@@ -1843,25 +1840,6 @@ sub get_param
 
     get last backup
 
-SELECT DISTINCT Job.JobId       AS jobid,
-                Client.Name     AS client,
-                FileSet.FileSet AS fileset,
-               Job.Name        AS jobname,
-                Level           AS level,
-                StartTime       AS starttime,
-                JobFiles        AS jobfiles, 
-                JobBytes        AS jobbytes,
-                VolumeName      AS volumename,
-               JobStatus       AS jobstatus,
-                JobErrors      AS joberrors
-
- FROM Client,Job,JobMedia,Media,FileSet
- WHERE Client.ClientId=Job.ClientId
-   AND Job.FileSetId=FileSet.FileSetId
-   AND JobMedia.JobId=Job.JobId 
-   AND JobMedia.MediaId=Media.MediaId
- $limit
-
 =cut 
 
 sub display_job
@@ -1906,10 +1884,6 @@ SELECT  Job.JobId       AS jobid,
 
     my $all = $self->dbh_selectall_hashref($query, 'jobid') ;
 
-    foreach (values %$all) {
-       $_->{jobbytes} = human_size($_->{jobbytes}) ;
-    }
-
     $self->display({ Filter => $label,
                     ID => $cur_id++,
                     Jobs => 
@@ -1951,8 +1925,6 @@ SELECT DISTINCT Job.JobId       AS jobid,
 
     my $row = $self->dbh_selectrow_hashref($query) ;
 
-    $row->{jobbytes} = human_size($row->{jobbytes}) ;
-
     # display all volumes associate with this job
     $query="
 SELECT Media.VolumeName as volumename
@@ -2013,9 +1985,6 @@ $where
 ";
 
     my $all = $self->dbh_selectall_hashref($query, 'volumename') ;
-    foreach (values %$all) {
-       $_->{volbytes} = human_size($_->{volbytes}) ;
-    }
 
     $self->display({ ID => $cur_id++,
                     Pool => $elt{pool},
@@ -2078,11 +2047,6 @@ SELECT InChanger     AS online,
     my $all = $self->dbh_selectall_hashref($query, 'volumename') ;
 
     foreach my $media (values %$all) {
-       $media->{nb_bytes} = human_size($media->{nb_bytes}) ;
-       $media->{voluseduration} = human_sec($media->{voluseduration});
-       $media->{volretention} = human_sec($media->{volretention});
-       $media->{volreadtime}  = human_sec($media->{volreadtime});
-       $media->{volwritetime}  = human_sec($media->{volwritetime});
        my $mq = $self->dbh_quote($media->{volumename});
 
        $query = "
@@ -2102,10 +2066,6 @@ SELECT DISTINCT Job.JobId AS jobid,
 
        my $jobs = $self->dbh_selectall_hashref($query, 'jobid') ;
 
-       foreach (values %$jobs) {
-           $_->{bytes} = human_size($_->{bytes}) ;
-       }
-
        $query = "
 SELECT LocationLog.Date    AS date,
        Location.Location   AS location,
@@ -2182,6 +2142,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) = @_ ;
@@ -2294,7 +2285,7 @@ sub do_update_media
            $update .= " Slot=0, ";
        }
     } else {
-       $update = " Slot=0, InChanger=0, ";
+       $update .= " Slot=0, InChanger=0, ";
     }
 
     my $pool = CGI::param('pool') || '';
@@ -2381,8 +2372,7 @@ WHERE Media.VolumeName = $media->{qmedia}
     $self->display({
        %$elt,
         %$row,
-    },
-                  "update_media.tpl");
+    }, "update_media.tpl");
 }
 
 sub save_location
@@ -2409,7 +2399,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
@@ -2480,7 +2472,6 @@ GROUP BY Client.Name
 
     $row->{ID} = $cur_id++;
     $row->{label} = $label;
-    $row->{nb_bytes}    = human_size($row->{nb_bytes}) ;
 
     $self->display($row, "display_client_stats.tpl");
 }
@@ -2493,9 +2484,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,
@@ -2518,19 +2509,14 @@ 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') ;
 
     foreach my $p (values %$all) {
-       $p->{maxvolbytes}    = human_size($p->{maxvolbytes}) ;
-       $p->{volretention}   = human_sec($p->{volretention}) ;
-       $p->{voluseduration} = human_sec($p->{voluseduration}) ;
-
        if ($p->{volmax}) {
            $p->{poolusage} = sprintf('%.2f', $p->{voltotal} * 100/ $p->{volmax}) ;
        } else {
@@ -2618,17 +2604,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,
@@ -2642,9 +2623,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>";
@@ -2654,6 +2641,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) = @_;
@@ -2724,7 +2728,8 @@ sub ach_edit
     $ach->{drives} = 
        [ map { { name => $_, index => $i++ } } @{$ach->{drive_name}} ] ;
 
-    my $b = new Bconsole(pref => $self->{info});    
+    my $b = $self->get_bconsole();
+
     my @storages = $b->list_storage() ;
 
     $ach->{devices} = [ map { { name => $_ } } @storages ];
@@ -2758,7 +2763,7 @@ sub ach_add
     my ($self) = @_;
     my $arg = $self->get_form('ach', 'mtxcmd', 'device', 'precmd');
 
-    my $b = new Bconsole(pref => $self->{info});    
+    my $b = $self->get_bconsole();
     my @storages = $b->list_storage() ;
 
     unless ($arg->{ach}) {
@@ -2801,10 +2806,10 @@ sub delete
     my ($self) = @_;
     my $arg = $self->get_form('jobid');
 
-    my $b = new Bconsole(pref => $self->{info});
-
     if ($arg->{jobid}) {
+       my $b = $self->get_bconsole();
        my $ret = $b->send_cmd("delete jobid=\"$arg->{jobid}\"");
+
        $self->display({
            content => $b->send_cmd("delete jobid=\"$arg->{jobid}\""),
            title => "Delete a job ",
@@ -2822,8 +2827,10 @@ sub update_slots
        return $self->error("Bad autochanger name");
     }
 
-    my $b = new Bconsole(pref => $self->{info});
-    print "<pre>" . $b->update_slots($ach) . "</pre>";
+    print "<pre>";
+    my $b = new Bconsole(pref => $self->{info},timeout => 60,log_stdout => 1);
+    $b->update_slots($ach);
+    print "</pre>\n" 
 }
 
 sub get_job_log
@@ -2900,6 +2907,7 @@ sub label_barcodes
                       drive => $arg->{drive},
                       pool  => 'Scratch',
                       slots => $slots) ;
+    $b->close();
     print "</pre>";
 }
 
@@ -2909,6 +2917,10 @@ sub purge
 
     my @volume = CGI::param('media');
 
+    unless (@volume) {
+       return $self->error("Can't get media selection");
+    }
+
     my $b = new Bconsole(pref => $self->{info}, timeout => 60);
 
     $self->display({
@@ -2916,20 +2928,27 @@ sub purge
        title => "Purge media",
        name => "purge volume=" . join(' volume=', @volume),
     }, "command.tpl"); 
+    $b->close();
 }
 
 sub prune
 {
     my ($self) = @_;
 
+    my @volume = CGI::param('media');
+    unless (@volume) {
+       return $self->error("Can't get media selection");
+    }
+
     my $b = new Bconsole(pref => $self->{info}, timeout => 60);
 
-    my @volume = CGI::param('media');
     $self->display({
        content => $b->prune_volume(@volume),
        title => "Prune media",
        name => "prune volume=" . join(' volume=', @volume),
     }, "command.tpl"); 
+
+    $b->close();
 }
 
 sub cancel_job
@@ -2938,10 +2957,10 @@ sub cancel_job
 
     my $arg = $self->get_form('jobid');
     unless ($arg->{jobid}) {
-       return $self->error('Bad jobid');
+       return $self->error("Can't get jobid");
     }
 
-    my $b = new Bconsole(pref => $self->{info});
+    my $b = $self->get_bconsole();
     $self->display({
        content => $b->cancel($arg->{jobid}),
        title => "Cancel job",
@@ -2949,14 +2968,31 @@ sub cancel_job
     }, "command.tpl"); 
 }
 
+sub fileset_view
+{
+    # Warning, we display current fileset
+    my ($self) = @_;
+
+    my $arg = $self->get_form('fileset');
+
+    if ($arg->{fileset}) {
+       my $b = $self->get_bconsole();
+       my $ret = $b->get_fileset($arg->{fileset});
+       $self->display({ fileset => $arg->{fileset},
+                        %$ret,
+                    }, "fileset_view.tpl");
+    } else {
+       $self->error("Can't get fileset name");
+    }
+}
+
 sub director_show_sched
 {
     my ($self) = @_ ;
 
     my $arg = $self->get_form('days');
 
-    my $b = new Bconsole(pref => $self->{info}) ;
-    
+    my $b = $self->get_bconsole();
     my $ret = $b->director_get_sched( $arg->{days} );
 
     $self->display({
@@ -2974,7 +3010,7 @@ sub enable_disable_job
        return $self->error("Can't find job name");
     }
 
-    my $b = new Bconsole(pref => $self->{info}) ;
+    my $b = $self->get_bconsole();
 
     my $cmd;
     if ($what) {
@@ -2990,10 +3026,16 @@ sub enable_disable_job
     }, "command.tpl"); 
 }
 
+sub get_bconsole
+{
+    my ($self) = @_;
+    return new Bconsole(pref => $self->{info});
+}
+
 sub run_job_select
 {
     my ($self) = @_;
-    $b = new Bconsole(pref => $self->{info});
+    my $b = $self->get_bconsole();
 
     my $joblist = [ map { { name => $_ } } $b->list_job() ];
 
@@ -3028,7 +3070,7 @@ sub run_parse_job
 sub run_job_mod
 {
     my ($self) = @_;
-    $b = new Bconsole(pref => $self->{info});
+    my $b = $self->get_bconsole();
     
     my $job = CGI::param('job') || '';
 
@@ -3055,7 +3097,7 @@ sub run_job_mod
 sub run_job
 {
     my ($self) = @_;
-    $b = new Bconsole(pref => $self->{info});
+    my $b = $self->get_bconsole();
     
     my $jobs   = [ map {{ name => $_ }} $b->list_job() ];
 
@@ -3067,7 +3109,7 @@ sub run_job
 sub run_job_now
 {
     my ($self) = @_;
-    $b = new Bconsole(pref => $self->{info});
+    my $b = $self->get_bconsole();
     
     # TODO: check input (don't use pool, level)