/[BackupPC]/trunk/lib/BackupPC/SearchLib.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/lib/BackupPC/SearchLib.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 9 by dpavlin, Thu Jun 23 12:36:22 2005 UTC revision 194 by dpavlin, Thu Oct 13 17:11:59 2005 UTC
# Line 4  package BackupPC::SearchLib; Line 4  package BackupPC::SearchLib;
4  use strict;  use strict;
5  use BackupPC::CGI::Lib qw(:all);  use BackupPC::CGI::Lib qw(:all);
6  use BackupPC::Attrib qw(:all);  use BackupPC::Attrib qw(:all);
 use Data::Dumper;  
7  use DBI;  use DBI;
8    use DateTime;
9    use vars qw(%In $MyURL);
10    use Time::HiRes qw/time/;
11    use XML::Writer;
12    use IO::File;
13    
14    my $on_page = 100;
15    my $pager_pages = 10;
16    
17    my $dsn = $Conf{SearchDSN};
18    my $db_user = $Conf{SearchUser} || '';
19    
20    my $hest_index_path = $Conf{HyperEstraierIndex};
21    
22    my $dbh;
23    
24    sub get_dbh {
25            $dbh ||= DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
26            return $dbh;
27    }
28    
29  sub getUnits() {  sub getUnits() {
30      my @ret = ();          my @ret;
31      my $tmp;  
32      my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",          my $dbh = get_dbh();
33          "", "", { RaiseError => 1, AutoCommit => 1 } );          my $sth = $dbh->prepare(qq{
34      my $st =                  SELECT
35        $dbh->prepare(                          shares.id       as id,
36          " SELECT shares.ID AS ID, shares.share AS name FROM shares;");                          hosts.name || ':' || shares.name as share
37      $st->execute();                  FROM shares
38      push (@ret, { 'ID' => '', 'name' => '-'});                  JOIN hosts on hostid = hosts.id
39      while ( $tmp = $st->fetchrow_hashref() ) {                  ORDER BY share
40          push( @ret, { 'ID' => $tmp->{'ID'}, 'name' => $tmp->{'name'} } );          } );
41      }          $sth->execute();
42      $dbh->disconnect();          push @ret, { 'id' => '', 'share' => '-'};       # dummy any
43      return @ret;  
44            while ( my $row = $sth->fetchrow_hashref() ) {
45                    push @ret, $row;
46            }
47            return @ret;
48    }
49    
50    sub epoch_to_iso {
51            my $t = shift || return;
52            my $iso = BackupPC::Lib::timeStamp(undef, $t);
53            $iso =~ s/\s/ /g;
54            return $iso;
55  }  }
56    
57    sub dates_from_form($) {
58            my $param = shift || return;
59    
60            sub mk_epoch_date($$) {
61                    my ($name,$suffix) = @_;
62    
63                    my $yyyy = $param->{ $name . '_year_' . $suffix} || return undef;
64                    my $mm .= $param->{ $name . '_month_' . $suffix} ||
65                            ( $suffix eq 'from' ? 1 : 12);
66                    my $dd .= $param->{ $name . '_day_' . $suffix} ||
67                            ( $suffix eq 'from' ? 1 : 31);
68    
69                    $yyyy =~ s/\D//g;
70                    $mm =~ s/\D//g;
71                    $dd =~ s/\D//g;
72    
73                    my $h = my $m = my $s = 0;
74                    if ($suffix eq 'to') {
75                            $h = 23;
76                            $m = 59;
77                            $s = 59;
78                    }
79    
80                    my $dt = new DateTime(
81                            year => $yyyy,
82                            month => $mm,
83                            day => $dd,
84                            hour => $h,
85                            minute => $m,
86                            second => $s,
87                    );
88                    print STDERR "mk_epoch_date($name,$suffix) [$yyyy-$mm-$dd] = " . $dt->ymd . " " . $dt->hms . "\n";
89                    return $dt->epoch || 'NULL';
90            }
91    
92            my @ret = (
93                    mk_epoch_date('search_backup', 'from'),
94                    mk_epoch_date('search_backup', 'to'),
95                    mk_epoch_date('search', 'from'),
96                    mk_epoch_date('search', 'to'),
97            );
98    
99            return @ret;
100    
101    }
102    
103    
104  sub getWhere($) {  sub getWhere($) {
105      my ($param)    = @_;          my $param = shift || return;
106      my $retSQL     = "";  
107      my @conditions = ();          my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
108      my $cond;  
109            my @conditions;
110                push @conditions, qq{ backups.date >= $backup_from } if ($backup_from);
111              push @conditions, qq{ backups.date <= $backup_to } if ($backup_to);
112                push @conditions, qq{ files.date >= $files_from } if ($files_from);
113      if ( defined( $param->{'search_backup_day_from'} ) && $param->{'search_backup_day_from'} ne "") {          push @conditions, qq{ files.date <= $files_to } if ($files_to);
114          push( @conditions,  
115              ' strftime("%d", datetime(backups.date, "unixepoch","localtime")) >= "'          print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:" . join(" and ",@conditions);
116                . $param->{'search_backup_day_from'} ."\"");  
117      }          push( @conditions, ' files.shareid = ' . $param->{'search_share'} ) if ($param->{'search_share'});
118      if ( defined( $param->{'search_backup_day_to'} ) && $param->{'search_backup_day_to'} ne "") {          push (@conditions, " upper(files.path) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});
119          push( @conditions,  
120              ' strftime("%d", datetime(backups.date, "unixepoch","localtime")) <= "'          return join(" and ", @conditions);
121                . $param->{'search_backup_day_from'}  ."\"");  }
122      }  
123      if ( defined( $param->{'search_backup_month_from'} ) && $param->{'search_backup_month_from'} ne "") {  
124          push( @conditions,  sub getFiles($) {
125              ' strftime("%m", datetime(backups.date, "unixepoch","localtime")) >= "'          my ($param) = @_;
126                . $param->{'search_backup_month_from'}  ."\"");  
127      }          my $offset = $param->{'offset'} || 0;
128      if ( defined( $param->{'search_backup_month_to'} ) && $param->{'search_backup_month_to'} ne "") {          $offset *= $on_page;
129          push( @conditions,  
130              ' strftime("%m", datetime(backups.date, "unixepoch","localtime")) <= "'          my $dbh = get_dbh();
131                . $param->{'search_backup_month_to'}  ."\"");  
132      }          my $sql_cols = qq{
133      if ( defined( $param->{'search_backup_year_from'} ) && $param->{'search_backup_year_from'} ne "") {                  files.id                        AS fid,
134          push( @conditions,                  hosts.name                      AS hname,
135              ' strftime("%Y", datetime(backups.date, "unixepoch","localtime")) >= "'                  shares.name                     AS sname,
136                . $param->{'search_backup_year_from'}  ."\"");                  files.backupnum                 AS backupnum,
137      }                  files.path                      AS filepath,
138      if ( defined( $param->{'search_backup_year_to'} ) && $param->{'search_backup_year_to'} ne "") {                  files.date                      AS date,
139          push( @conditions,                  files.type                      AS type,
140              ' strftime("%Y", datetime(backups.date, "unixepoch","localtime")) <= "'                  files.size                      AS size
               . $param->{'search_backup_year_to'}  ."\"");  
     }  
   
     if ( defined( $param->{'search_day_from'} )   && $param->{'search_day_from'} ne "" ) {  
         push( @conditions,  
             ' strftime("%d", datetime(files.date, "unixepoch","localtime")) >= "'  
               . $param->{'search_day_from'}  ."\"");  
     }  
     if ( defined( $param->{'search_month_from'} ) && $param->{'search_month_from'} ne "") {  
         push( @conditions,  
             ' strftime("%m", datetime(files.date, "unixepoch","localtime")) >= "'  
               . $param->{'search_month_from'}  ."\"");  
     }  
     if ( defined( $param->{'search_year_from'} ) && $param->{'search_year_from'} ne "") {  
         push( @conditions,  
             ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) >= "'  
               . $param->{'search_year_from'}  ."\"");  
     }  
     if ( defined( $param->{'search_day_to'} )   && $param->{'search_day_to'} ne "" ) {  
         push( @conditions,  
             ' strftime("%d", datetime(files.date, "unixepoch","localtime")) <= "'  
               . $param->{'search_day_to'}  ."\"");  
     }  
     if ( defined( $param->{'search_month_to'} ) && $param->{'search_month_to'} ne "" ) {  
         push( @conditions,  
             ' strftime("%m", datetime(files.date, "unixepoch","localtime")) <= "'  
               . $param->{'search_month_to'} ."\"" );  
     }  
     if ( defined( $param->{'search_year_to'} )&& $param->{'search_year_to'} ne "" )  {  
         push( @conditions,  
             ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) <= "'  
               . $param->{'search_year_to'} ."\"");  
     }  
   
     if ( defined( $param->{'search_host'} ) && $param->{'search_host'} ne "") {  
       push( @conditions, ' backups.hostID = ' . $param->{'search_host'} );  
     }  
   
     if ( defined ($param->{'search_filename'}) && $param->{'search_filename'} ne "") {  
         push (@conditions, " files.name LIKE '".$param->{'search_filename'}."%'");  
         }  
       
     $retSQL = "";  
     foreach $cond(@conditions)  
       {  
           if ($retSQL ne "")  
             {  
                 $retSQL .= " AND ";  
             }  
           $retSQL .= $cond;  
       }        
   
       
     return $retSQL;  
 }  
   
 sub getFiles($$)  
   {  
       my ($where, $offset) = @_;  
         
         
       my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",  
         "", "", { RaiseError => 1, AutoCommit => 1 } );  
       my $sql =            
         q{    
               SELECT files.id                       AS fid,  
                      hosts.name                     AS hname,  
                      shares.name                    AS sname,  
                      shares.share                   AS sharename,  
                      backups.num                    AS backupNum,  
                      files.name                     AS filename,  
                      files.path                     AS filepath,  
                      shares.share||files.fullpath AS networkPath,  
                      date(files.date, 'unixepoch', 'localtime') AS date,  
                      files.type                     AS filetype,  
                      files.size                     AS size,  
                      dvds.name                      AS dvd  
                   FROM  
                      files  
                         INNER JOIN shares  ON files.shareID=shares.ID  
                         INNER JOIN hosts   ON hosts.ID = shares.hostID  
                         INNER JOIN backups ON backups.hostID = hosts.ID  
                         LEFT  JOIN dvds    ON dvds.ID = files.dvdid  
               
           };  
   
       if (defined($where) && $where ne "")  
         {  
             $sql .= " WHERE ". $where;        
         }  
   
       $sql .=  
         q{            
             ORDER BY files.id  
               LIMIT 100  
               OFFSET ? * 100 + 1  
141          };          };
142          
143                  my $sql_from = qq{
144                          FROM files
145        my $st = $dbh->prepare(                          INNER JOIN shares       ON files.shareID=shares.ID
146            $sql                          INNER JOIN hosts        ON hosts.ID = shares.hostID
147            );                              INNER JOIN backups      ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = files.shareID
148        if (!defined($offset) && $offset ne "")          };
149        {  
150          $st->bind_param(1, $offset);          my $sql_where;
151        }          my $where = getWhere($param);
152        else          $sql_where = " WHERE ". $where if ($where);
153        {  
154          $st->bind_param(1,0);          my $sql_order = qq{
155        }                  ORDER BY files.date
156        $st->execute;                  LIMIT $on_page
157                          OFFSET ?
158        my @ret = ();          };
159        my $tmp;  
160                  my $sql_count = qq{ select count(files.id) $sql_from $sql_where };
161        while ($tmp = $st->fetchrow_hashref())          my $sql_results = qq{ select $sql_cols $sql_from $sql_where $sql_order };
162          {  
163              push(@ret, {          my $sth = $dbh->prepare($sql_count);
164                             'hname'       => $tmp->{'hname'},          $sth->execute();
165                             'sname'       => $tmp->{'sname'},          my ($results) = $sth->fetchrow_array();
166                             'sharename'   => $tmp->{'sharename'},  
167                             'backupno'    => $tmp->{'backupNum'},          $sth = $dbh->prepare($sql_results);
168                             'fname'       => $tmp->{'filename'},          $sth->execute( $offset );
169                             'fpath'       => $tmp->{'filepath'},  
170                             'networkpath' => $tmp->{'networkPath'},          if ($sth->rows != $results) {
171                             'date'        => $tmp->{'date'},                  my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
172                             'type'        => $tmp->{'filetype'},                  $bug =~ s/\s+/ /gs;
173                             'size'        => $tmp->{'size'},                  print STDERR "$bug\n";
                            'id'          => $tmp->{'fid'},  
                            'dvd'         => $tmp->{'dvd'}  
                        }  
             );  
                                   
174          }          }
175    
176            my @ret;
177                
178        $st->finish();          while (my $row = $sth->fetchrow_hashref()) {
179        $dbh->disconnect();                  push @ret, $row;
       return @ret;  
   }  
   
 sub getBackupsNotBurned()  
   {  
       my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",  
         "", "", { RaiseError => 1, AutoCommit => 1 } );        
       my $sql = q{  
           SELECT  
             hosts.ID         AS hostID,  
             hosts.name       AS host,  
             backups.num      AS backupno,  
             backups.type     AS type,  
             backups.date     AS date  
           FROM backups, shares, files, hosts  
           WHERE  
             backups.num    = files.backupNum  AND  
             shares.ID      = files.shareID    AND            
             backups.hostID = shares.hostID    AND  
             hosts.ID       = backups.hostID   AND  
             files.dvdid    IS NULL  
           GROUP BY  
             backups.hostID, backups.num  
       };  
       my $st = $dbh -> prepare( $sql );  
       my @ret = ();  
       $st -> execute();  
   
       while ( my $tmp = $st -> fetchrow_hashref() )  
         {            
             push(@ret, {  
                          'host'     => $tmp->{'host'},  
                          'hostid'   => $tmp->{'hostID'},  
                          'backupno' => $tmp->{'backupno'},  
                          'type'     => $tmp->{'type'},  
                          'date'     => $tmp->{'date'}  
                        }  
             );  
180          }          }
181              
182        return @ret;                $sth->finish();
183    }          return ($results, \@ret);
184    }
185    
186    sub getHyperEstraier_url($) {
187            my ($use_hest) = @_;
188    
189            return unless $use_hest;
190    
191            use HyperEstraier;
192            my ($index_path, $index_node_url);
193    
194            if ($use_hest =~ m#^http://#) {
195                    $index_node_url = $use_hest;
196            } else {
197                    $index_path = $TopDir . '/' . $index_path;
198                    $index_path =~ s#//#/#g;
199            }
200            return ($index_path, $index_node_url);
201    }
202    
203  sub displayBackupsGrid()  sub getFilesHyperEstraier($) {
204    {          my ($param) = @_;
205        my $retHTML = "";  
206        my $addForm = 1;          my $offset = $param->{'offset'} || 0;
207            $offset *= $on_page;
208    
209            die "no index_path?" unless ($hest_index_path);
210    
211            use HyperEstraier;
212    
213            my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path);
214    
215            # open the database
216            my $db;
217            if ($index_path) {
218                    $db = HyperEstraier::Database->new();
219                    $db->open($index_path, $HyperEstraier::ESTDBREADER);
220            } elsif ($index_node_url) {
221                    $db ||= HyperEstraier::Node->new($index_node_url);
222                    $db->set_auth('admin', 'admin');
223            } else {
224                    die "BUG: unimplemented";
225            }
226    
227            # create a search condition object
228            my $cond = HyperEstraier::Condition->new();
229    
230            my $q = $param->{'search_filename'};
231            my $shareid = $param->{'search_share'};
232    
233            if (length($q) > 0) {
234                    # exact match
235                    $cond->add_attr("filepath ISTRINC $q");
236    
237                    $q =~ s/(.)/$1 /g;
238                    # set the search phrase to the search condition object
239                    $cond->set_phrase($q);
240            }
241    
242            my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
243    
244            $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
245            $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);
246    
247            $cond->add_attr("date NUMGE $files_from") if ($files_from);
248            $cond->add_attr("date NUMLE $files_to") if ($files_to);
249    
250            $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
251    
252    #       $cond->set_max( $offset + $on_page );
253            $cond->set_options( $HyperEstraier::Condition::SURE );
254            $cond->set_order( 'date NUMA' );
255    
256            # get the result of search
257            my @res;
258            my ($result, $hits);
259    
260            if ($index_path) {
261                    $result = $db->search($cond, 0);
262                    $hits = $result->size;
263            } elsif ($index_node_url) {
264                    $result = $db->search($cond, 0);
265                    $hits = $result->doc_num;
266            } else {
267                    die "BUG: unimplemented";
268            }
269    
270            # for each document in result
271            for my $i ($offset .. ($offset + $on_page - 1)) {
272                    last if ($i >= $hits);
273    
274                    my $doc;
275                    if ($index_path) {
276                            my $id = $result->get($i);
277                            $doc = $db->get_doc($id, 0);
278                    } elsif ($index_node_url) {
279                            $doc = $result->get_doc($i);
280                    } else {
281                            die "BUG: unimplemented";
282                    }
283    
284                    my $row;
285                    foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {
286                            $row->{$c} = $doc->attr($c);
287                    }
288                    push @res, $row;
289            }
290    
291            return ($hits, \@res);
292    }
293    
294    sub getGzipName($$$)
295    {
296            my ($host, $share, $backupnum) = @_;
297            my $ret = $Conf{GzipSchema};
298            
299            $share =~ s/\//_/g;
300            $ret =~ s/\\h/$host/ge;
301            $ret =~ s/\\s/$share/ge;
302            $ret =~ s/\\n/$backupnum/ge;
303    
304            $ret =~ s/__+/_/g;
305    
306            return $ret;
307            
308    }
309    
310    sub get_tgz_size_by_name($) {
311            my $name = shift;
312    
313            my $tgz = $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.$name;
314    
315            my $size = -1;
316    
317            if (-f $tgz) {
318                    $size = (stat($tgz))[7];
319            } elsif (-d $tgz) {
320                    opendir(my $dir, $tgz) || die "can't opendir $tgz: $!";
321                    my @parts = grep { !/^\./ && -f "$tgz/$_" } readdir($dir);
322                    $size = 0;
323                    foreach my $part (@parts) {
324                            $size += (stat("$tgz/$part"))[7] || die "can't stat $tgz/$part: $!";
325                    }
326                    closedir $dir;
327            }
328    
329            return $size;
330    }
331    
332    sub getGzipSize($$)
333    {
334            my ($hostID, $backupNum) = @_;
335            my $sql;
336            my $dbh = get_dbh();
337            
338            $sql = q{
339                                    SELECT hosts.name  as host,
340                                               shares.name as share,
341                                               backups.num as backupnum
342                                    FROM hosts, backups, shares
343                                    WHERE shares.id=backups.shareid AND
344                                              hosts.id =backups.hostid AND
345                                              hosts.id=? AND
346                                              backups.num=?
347                            };
348            my $sth = $dbh->prepare($sql);
349            $sth->execute($hostID, $backupNum);
350    
351            my $row = $sth->fetchrow_hashref();
352    
353            return get_tgz_size_by_name(
354                    getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'})
355            );
356    }
357    
358    sub getBackupsNotBurned() {
359    
360            my $dbh = get_dbh();
361    
362            my $sql = q{
363                    SELECT
364                            backups.hostID AS hostID,
365                            hosts.name AS host,
366                            shares.name AS share,
367                            backups.num AS backupnum,
368                            backups.type AS type,
369                            backups.date AS date,
370                            backups.size AS size,
371                            backups.id AS id,
372                            backups.inc_size AS inc_size
373                    FROM backups
374                    INNER JOIN shares       ON backups.shareID=shares.ID
375                    INNER JOIN hosts        ON backups.hostID = hosts.ID
376                    LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
377                    WHERE backups.inc_size > 0 AND backups.inc_deleted is false AND archive_backup.backup_id IS NULL
378                    GROUP BY
379                            backups.hostID,
380                            hosts.name,
381                            shares.name,
382                            backups.num,
383                            backups.shareid,
384                            backups.id,
385                            backups.type,
386                            backups.date,
387                            backups.size,
388                            backups.inc_size
389                    ORDER BY backups.date
390            };
391            my $sth = $dbh->prepare( $sql );
392            my @ret;
393            $sth->execute();
394    
395            while ( my $row = $sth->fetchrow_hashref() ) {
396                    $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
397                    $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
398    
399                    # do some cluster calculation (approximate) and convert to kB
400                    $row->{'inc_size'} = int(($row->{'inc_size'} + 1023 ) / ( 2 * 1024 ) * 2);
401                    push @ret, $row;
402            }
403                
404        if ($addForm)          return @ret;      
405          {  }
406    
407    sub displayBackupsGrid() {
408    
409              $retHTML .= <<EOF3;          my $retHTML .= q{
410  <script language="javascript" type="text/javascript">                  <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
411            };
412    
413            $retHTML .= <<'EOF3';
414    <style type="text/css">
415  <!--  <!--
416    DIV#fixedBox {
417            position: absolute;
418            top: 50em;
419            left: -24%;
420            padding: 0.5em;
421            width: 20%;
422            background-color: #E0F0E0;
423            border: 1px solid #00C000;
424    }
425    
426      function checkAll(location)  DIV#fixedBox, DIV#fixedBox INPUT, DIV#fixedBox TEXTAREA {
427      {          font-size: 10pt;
428        for (var i=0;i<document.forma.elements.length;i++)  }
429        {  
430          var e = document.forma.elements[i];  FORM>DIV#fixedBox {
431          if ((e.checked || !e.checked) && e.name != \'all\') {          position: fixed !important;
432              if (eval("document.forma."+location+".checked")) {          left: 0.5em !important;
433                  e.checked = true;          top: auto !important;
434              } else {          bottom: 1em !important;
435                  e.checked = false;          width: 15% !important;
436              }  }
437          }  
438        }  DIV#fixedBox INPUT[type=text], DIV#fixedBox TEXTAREA {
439      }          border: 1px solid #00C000;
440  //-->  }
441  </script>        
442    DIV#fixedBox #note {
443            display: block;
444            width: 100%;
445    }
446    
447    DIV#fixedBox #submitBurner {
448            display: block;
449            width: 100%;
450            margin-top: 0.5em;
451            cursor: pointer;
452    }
453    
454    * HTML {
455            overflow-y: hidden;
456    }
457    
458    * HTML BODY {
459            overflow-y: auto;
460            height: 100%;
461            font-size: 100%;
462    }
463    
464    * HTML DIV#fixedBox {
465            position: absolute;
466    }
467    
468    #mContainer, #gradient, #mask, #progressIndicator {
469            display: block;
470            width: 100%;
471            font-size: 10pt;
472            font-weight: bold;
473            text-align: center;
474            vertical-align: middle;
475            padding: 1px;
476    }
477    
478    #gradient, #mask, #progressIndicator {
479            left: 0;
480            border-width: 1px;
481            border-style: solid;
482            border-color: #000000;
483            color: #404040;
484            margin: 0.4em;
485            position: absolute;
486            margin-left: -1px;
487            margin-top: -1px;
488            margin-bottom: -1px;
489            overflow: hidden;
490    }
491    
492    #mContainer {
493            display: block;
494            position: relative;
495            padding: 0px;
496            margin-top: 0.4em;
497            margin-bottom: 0.5em;
498    }
499    
500    #gradient {
501            z-index: 1;
502            background-color: #FFFF00;
503    }
504    
505    #mask {
506            z-index: 2;
507            background-color: #FFFFFF;
508    }
509    
510    #progressIndicator {
511            z-index: 3;
512            background-color: transparent;
513    }
514    -->
515    </style>
516    <script type="text/javascript">
517    <!--
518    
519    var debug_div = null;
520  EOF3  EOF3
521                $retHTML .= q{<form name="forma" method="POST" action="}."$MyURL"."?action=burn\"";  
522                $retHTML.= q{<input type="hidden" value="burn" name="action">};          # take maximum archive size from configuration
523                $retHTML .= q{<input type="hidden" value="results" name="search_results">};          $retHTML .= 'var media_size = '. $Conf{MaxArchiveSize} .';';
524          }  
525        $retHTML .= "<table style=\"fview\">";          $retHTML .= <<'EOF3';
526        $retHTML .= "<tr> ";  
527        if ($addForm)  function debug(msg) {
528          {  //      return; // Disable debugging
529              $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";  
530          }          if (! debug_div) debug_div = document.getElementById('debug');
531        $retHTML .=  "<td class=\"tableheader\">Host</td> <td class=\"tableheader\">Backup no</td> <td class=\"tableheader\">Type</td> <td class=\"tableheader\">date</td></tr>";  
532        my @backups = getBackupsNotBurned();          // this will create debug div if it doesn't exist.
533        my $backup;          if (! debug_div) {
534                    debug_div = document.createElement('div');
535        if ($addForm)                  if (document.body) document.body.appendChild(debug_div);
536          {                  else debug_div = null;
537              $retHTML .= "<tr>";          }
538              $retHTML .= "<td colspan=7 style=\"tableheader\">";          if (debug_div) {
539              $retHTML .= "<input type=\"submit\" value=\"Burn selected backups on medium\" name=\"submitBurner\">";                  debug_div.appendChild(document.createTextNode(msg));
540              $retHTML .= "</td>";                  debug_div.appendChild(document.createElement("br"));
541              $retHTML .= "</tr>";          }
542                }
543          }  
544        foreach $backup(@backups)  
545          {  var element_id_cache = Array();
546              my $ftype = "";  
547                function element_id(name,element) {
548              $retHTML .= "<tr>";          if (! element_id_cache[name]) {
549              if ($addForm)                  element_id_cache[name] = self.document.getElementById(name);
550                {          }
551                    $retHTML .= "<td class=\"fview\"> <input type=\"checkbox\" name=\"fcb"          return element_id_cache[name];
552                      .$backup->{'hostid'}."_".$backup->{'backupno'}  }
553                    ."\" value=\"".$backup->{'hostid'}."_".$backup->{'backupno'}."\"> </td>";  
554                }      function checkAll(location) {
555                        var f = element_id('forma') || null;
556              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'host'} . "</td>";          if (!f) return false;
557              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'backupno'} . "</td>";  
558              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'type'} . "</td>";          var len = f.elements.length;
559              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'date'} . "<td>";          var check_all = element_id('allFiles');
560              $retHTML .= "</tr>";          var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
561          }  
562        $retHTML .= "</table>";          for (var i = 0; i < len; i++) {
563        if ($addForm)                  var e = f.elements[i];
564         {                  if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
565             $retHTML .= "</form>";                          if (check_all.checked) {
566         }                                  if (e.checked) continue;
567                                          var el = element_id("fss" + e.name.substr(3));
568        return $retHTML;                                  var size = parseInt(el.value) || 0;
569                                      debug('suma: '+suma+' size: '+size);
570                                      if ((suma + size) < media_size) {
571    }                                                suma += size;
572                                            e.checked = true;
573  sub displayGrid($$$)                                  } else {
574    {                                          break;
575        my ($where, $addForm, $offset) = @_;                                  }
576        my $retHTML = "";                          } else {
577                                          e.checked = false;
578        if ($addForm)                          }
579          {                  }
580                $retHTML .= q{<form name="forma" method="POST" action="}."$MyURL"."?action=search\"";          }
581                $retHTML.= q{<input type="hidden" value="search" name="action">};          update_sum(suma);
582                $retHTML .= q{<input type="hidden" value="results" name="search_results">};  }
583          }  
584        $retHTML .= "<table style=\"fview\">";  function update_sum(suma) {
585        $retHTML .= "<tr> ";          element_id('forma').elements['totalsize'].value = suma;
586        $retHTML .=  "<td class=\"tableheader\">Host</td> <td class=\"tableheader\">Name</td> <td class=\"tableheader\">Type</td> <td class=\"tableheader\">backup no.</td> <td class=\"tableheader\">size</td> <td class=\"tableheader\">date</td>  <td class=\"tableheader\">Media</td></tr>";          pbar_set(suma, media_size);
587        my @files = getFiles($where, $offset);          debug('total size: ' + suma);
588        my $file;  }
589    
590        foreach $file(@files)  function sumiraj(e) {
591          {          var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
592              my $ftype = "";          var len = element_id('forma').elements.length;
593                        if (e) {
594              if ($file->{'type'} == BPC_FTYPE_DIR)                  var size = parseInt( element_id("fss" + e.name.substr(3)).value);
595                {                  if (e.checked) {
596                    $ftype = "dir";                          suma += size;
597                }                  } else {
598              else                          suma -= size;
599                {                  }
600                    $ftype = "file";          } else {
601                }                  suma = 0;
602              $retHTML .= "<tr>";                  for (var i = 0; i < len; i++) {
603              $retHTML .= "<td class=\"fviewborder\">" . $file->{'hname'} ."</td>";                          var e = element_id('forma').elements[i];
604              $retHTML .= "<td class=\"fviewborder\">" . $file->{'fname'} . "</td>";                          if (e.name != 'all' && e.checked && e.name.substr(0,3) == 'fcb') {
605              $retHTML .= "<td class=\"fviewborder\">" . $ftype . "</td>";                                  var el = element_id("fss" + e.name.substr(3));
606              $retHTML .= "<td class=\"fviewborder\">" . $file->{'backupno'} . "</td>";                                  if (el && el.value) suma += parseInt(el.value) || 0;
607              $retHTML .= "<td class=\"fviewborder\">" . $file->{'size'} . "</td>";                          }
608              $retHTML .= "<td class=\"fviewborder\">" . $file->{'date'} . "</td>";                  }
609              $retHTML .= "<td class=\"fviewborder\">" . $file->{'dvd'} . "</td>";          }
610              $retHTML .= "</tr>";          update_sum(suma);
611          }          return suma;
612        $retHTML .= "</table>";  }
613    
614          /* progress bar */
615    
616        $retHTML .= "<INPUT TYPE=\"hidden\" VALUE=\"\" NAME=\"offset\">";  var _pbar_width = null;
617        for (my $ii = 1; $ii <= $#files; $ii++)  var _pbar_warn = 10;    // change color in last 10%
618        {  
619            $retHTML .= "<a href = \"#\" onclick=\"document.forma.offset.value=$ii;document.forma.submit();\">$ii</a>";  function pbar_reset() {
620            if ($ii < $#files)          element_id("mask").style.left = "0px";
621              {          _pbar_width = element_id("mContainer").offsetWidth - 2;
622                  $retHTML .= " | ";          element_id("mask").style.width = _pbar_width + "px";
623              }          element_id("mask").style.display = "block";
624        }          element_id("progressIndicator").style.zIndex  = 10;
625            element_id("progressIndicator").innerHTML = "0";
626    }
627         if ($addForm)  
628         {  function dec2hex(d) {
629             $retHTML .= "</form>";          var hch = '0123456789ABCDEF';
630         }          var a = d % 16;
631            var q = (d - a) / 16;
632            return hch.charAt(q) + hch.charAt(a);
633    }
634    
635    function pbar_set(amount, max) {
636            debug('pbar_set('+amount+', '+max+')');
637    
638            if (_pbar_width == null) {
639                    var _mc = element_id("mContainer");
640                    if (_pbar_width == null) _pbar_width = parseInt(_mc.offsetWidth ? (_mc.offsetWidth - 2) : 0) || null;
641                    if (_pbar_width == null) _pbar_width = parseInt(_mc.clientWidth ? (_mc.clientWidth + 2) : 0) || null;
642                    if (_pbar_width == null) _pbar_width = 0;
643            }
644    
645            var pcnt = Math.floor(amount * 100 / max);
646            var p90 = 100 - _pbar_warn;
647            var pcol = pcnt - p90;
648            if (Math.round(pcnt) <= 100) {
649                    if (pcol < 0) pcol = 0;
650                    var e = element_id("submitBurner");
651                    debug('enable_button');
652                    e.disabled = false;
653                    var a = e.getAttributeNode('disabled') || null;
654                    if (a) e.removeAttributeNode(a);
655            } else {
656                    debug('disable button');
657                    pcol = _pbar_warn;
658                    var e = element_id("submitBurner");
659                    if (!e.disabled) e.disabled = true;
660            }
661            var col_g = Math.floor((_pbar_warn - pcol) * 255 / _pbar_warn);
662            var col = '#FF' + dec2hex(col_g) + '00';
663    
664            //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col);
665            element_id("gradient").style.backgroundColor = col;
666    
667            element_id("progressIndicator").innerHTML = pcnt + '%';
668            //element_id("progressIndicator").innerHTML = amount;
669    
670            element_id("mask").style.clip = 'rect(' + Array(
671                    '0px',
672                    element_id("mask").offsetWidth + 'px',
673                    element_id("mask").offsetHeight + 'px',
674                    Math.round(_pbar_width * amount / max) + 'px'
675            ).join(' ') + ')';
676    }
677    
678    if (!self.body) self.body = new Object();
679    self.onload = self.document.onload = self.body.onload = function() {
680            //pbar_reset();
681            sumiraj();
682    };
683    
684    // -->
685    </script>
686    <div id="fixedBox">
687    
688    Size: <input type="text" name="totalsize" size="7" readonly="readonly" style="text-align:right;" value="0" /> kB
689    
690    <div id="mContainer">
691            <div id="gradient">&nbsp;</div>
692            <div id="mask">&nbsp;</div>
693            <div id="progressIndicator">0%</div>
694    </div>
695    <br/>
696    
697    Note:
698    <textarea name="note" cols="10" rows="5" id="note"></textarea>
699    
700    <input type="submit" id="submitBurner" value="Burn selected" name="submitBurner" />
701    
702    </div>
703    <!--
704    <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
705    no debug output yet
706    </div>
707    -->
708    EOF3
709            $retHTML .= q{
710                            <input type="hidden" value="burn" name="action">
711                            <input type="hidden" value="results" name="search_results">
712                            <table style="fview" border="0" cellspacing="0" cellpadding="2">
713                            <tr class="tableheader">
714                            <td class="tableheader">
715                                    <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
716                            </td>
717                            <td align="center">Share</td>
718                            <td align="center">Backup no</td>
719                            <td align="center">Type</td>
720                            <td align="center">date</td>
721                            <td align="center">age/days</td>
722                            <td align="center">size/MB</td>
723                            <td align="center">gzip size/kB</td>
724                            </tr>
725    
726            };
727    
728            my @color = (' bgcolor="#e0e0e0"', '');
729    
730            my $i = 0;
731            my $host = '';
732    
733            foreach my $backup ( getBackupsNotBurned() ) {
734    
735                    if ($host ne $backup->{'host'}) {
736                            $i++;
737                            $host = $backup->{'host'};
738                    }
739                    my $ftype = "";
740    
741                    my $checkbox_key = $backup->{'hostid'}. '_' .$backup->{'backupnum'} . '_' . $backup->{'id'};
742    
743                    $retHTML .=
744                            '<tr' . $color[$i %2 ] . '>
745                            <td class="fview">';
746    
747                    if (($backup->{'inc_size'} || 0) > 0) {
748                            $retHTML .= '
749                            <input type="checkbox" name="fcb' . $checkbox_key . '" value="' . $checkbox_key . '" onClick="sumiraj(this);">';
750                    }
751    
752                    $retHTML .=
753                            '</td>' .
754                            '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
755                            '<td align="center">' . $backup->{'backupnum'} . '</td>' .
756                            '<td align="center">' . $backup->{'type'} . '</td>' .
757                            '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
758                            '<td align="center">' . $backup->{'age'} . '</td>' .
759                            '<td align="right">' . $backup->{'size'} . '</td>' .
760                            '<td align="right">' . $backup->{'inc_size'} .
761                            '<input type="hidden" iD="fss'.$checkbox_key .'" value="'. $backup->{'inc_size'} .'"></td>' .
762    
763                            "</tr>\n";
764            }
765    
766            $retHTML .= "</table>";
767            $retHTML .= "</form>";
768                
769        return $retHTML;          return $retHTML;
770    }  }      
771    
772    sub displayGrid($) {
773            my ($param) = @_;
774    
775            my $offset = $param->{'offset'};
776            my $hilite = $param->{'search_filename'};
777    
778            my $retHTML = "";
779    
780            my $start_t = time();
781    
782            my ($results, $files);
783            if ($param->{'use_hest'} && length($hilite) > 0) {
784                    ($results, $files) = getFilesHyperEstraier($param);
785            } else {
786                    ($results, $files) = getFiles($param);
787            }
788    
789            my $dur_t = time() - $start_t;
790            my $dur = sprintf("%0.4fs", $dur_t);
791    
792            my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
793    
794            if ($results <= 0) {
795                    $retHTML .= qq{
796                            <p style="color: red;">No results found...</p>
797                    };
798                    return $retHTML;
799            } else {
800                    # DEBUG
801                    #use Data::Dumper;
802                    #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
803            }
804    
805    
806            $retHTML .= qq{
807            <div>
808            Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
809            </div>
810            <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
811                    <tr class="fviewheader">
812                    <td></td>
813                    <td align="center">Share</td>
814                    <td align="center">Type and Name</td>
815                    <td align="center">#</td>
816                    <td align="center">Size</td>
817                    <td align="center">Date</td>
818                    <td align="center">Media</td>
819                    </tr>
820            };
821    
822            my $file;
823    
824            sub hilite_html($$) {
825                    my ($html, $search) = @_;
826                    $html =~ s#($search)#<b>$1</b>#gis;
827                    return $html;
828            }
829    
830            sub restore_link($$$$$$) {
831                    my $type = shift;
832                    my $action = 'RestoreFile';
833                    $action = 'browse' if (lc($type) eq 'dir');
834                    return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
835            }
836    
837            my $i = $offset * $on_page;
838    
839            foreach $file (@{ $files }) {
840                    $i++;
841    
842                    my $typeStr  = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
843                    $retHTML .= qq{<tr class="fviewborder">};
844    
845                    $retHTML .= qq{<td class="fviewborder">$i</td>};
846    
847                    $retHTML .=
848                            qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
849                            qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
850                            qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
851                            qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
852                            qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
853                            qq{<td class="fviewborder">} . '?' . qq{</td>};
854    
855                    $retHTML .= "</tr>";
856            }
857            $retHTML .= "</table>";
858    
859            # all variables which has to be transfered
860            foreach my $n (qw/search_day_from search_month_from search_year_from search_day_to search_month_to search_year_to search_backup_day_from search_backup_month_from search_backup_year_from search_backup_day_to search_backup_month_to search_backup_year_to search_filename offset/) {
861                    $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
862            }
863    
864            my $del = '';
865            my $max_page = int( $results / $on_page );
866            my $page = 0;
867    
868            sub page_link($$$) {
869                    my ($param,$page,$display) = @_;
870    
871                    $param->{'offset'} = $page;
872    
873                    my $html = '<a href = "' . $MyURL;
874                    my $del = '?';
875                    foreach my $k (keys %{ $param }) {
876                            if ($param->{$k}) {
877                                    $html .= $del . $k . '=' . ${EscURI( $param->{$k} )};
878                                    $del = '&';
879                            }
880                    }
881                    $html .= '">' . $display . '</a>';
882            }
883    
884            $retHTML .= '<div style="text-align: center;">';
885    
886            if ($offset > 0) {
887                    $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
888            }
889    
890            while ($page <= $max_page) {
891                    if ($page == $offset) {
892                            $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
893                    } else {
894                            $retHTML .= $del . page_link($param, $page, $page + 1);
895                    }
896    
897                    if ($page < $offset - $pager_pages && $page != 0) {
898                            $retHTML .= " ... ";
899                            $page = $offset - $pager_pages;
900                            $del = '';
901                    } elsif ($page > $offset + $pager_pages && $page != $max_page) {
902                            $retHTML .= " ... ";
903                            $page = $max_page;
904                            $del = '';
905                    } else {
906                            $del = ' | ';
907                            $page++;
908                    }
909            }
910    
911            if ($offset < $max_page) {
912                    $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
913            }
914    
915            $retHTML .= "</div>";
916    
917            return $retHTML;
918    }
919    
920  1;  1;

Legend:
Removed from v.9  
changed lines
  Added in v.194

  ViewVC Help
Powered by ViewVC 1.1.26