/[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 6 by dpavlin, Thu Jun 23 09:47:59 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
141                . $param->{'search_backup_year_to'}  ."\"");          };
142      }  
143            my $sql_from = qq{
144      if ( defined( $param->{'search_day_from'} )   && $param->{'search_day_from'} ne "" ) {                  FROM files
145          push( @conditions,                          INNER JOIN shares       ON files.shareID=shares.ID
146              ' strftime("%d", datetime(files.date, "unixepoch","localtime")) >= "'                          INNER JOIN hosts        ON hosts.ID = shares.hostID
147                . $param->{'search_day_from'}  ."\"");                          INNER JOIN backups      ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = files.shareID
148      }          };
149      if ( defined( $param->{'search_month_from'} ) && $param->{'search_month_from'} ne "") {  
150          push( @conditions,          my $sql_where;
151              ' strftime("%m", datetime(files.date, "unixepoch","localtime")) >= "'          my $where = getWhere($param);
152                . $param->{'search_month_from'}  ."\"");          $sql_where = " WHERE ". $where if ($where);
153      }  
154      if ( defined( $param->{'search_year_from'} ) && $param->{'search_year_from'} ne "") {          my $sql_order = qq{
155          push( @conditions,                  ORDER BY files.date
156              ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) >= "'                  LIMIT $on_page
157                . $param->{'search_year_from'}  ."\"");                  OFFSET ?
158      }          };
159      if ( defined( $param->{'search_day_to'} )   && $param->{'search_day_to'} ne "" ) {  
160          push( @conditions,          my $sql_count = qq{ select count(files.id) $sql_from $sql_where };
161              ' strftime("%d", datetime(files.date, "unixepoch","localtime")) <= "'          my $sql_results = qq{ select $sql_cols $sql_from $sql_where $sql_order };
162                . $param->{'search_day_to'}  ."\"");  
163      }          my $sth = $dbh->prepare($sql_count);
164      if ( defined( $param->{'search_month_to'} ) && $param->{'search_month_to'} ne "" ) {          $sth->execute();
165          push( @conditions,          my ($results) = $sth->fetchrow_array();
166              ' strftime("%m", datetime(files.date, "unixepoch","localtime")) <= "'  
167                . $param->{'search_month_to'} ."\"" );          $sth = $dbh->prepare($sql_results);
168      }          $sth->execute( $offset );
169      if ( defined( $param->{'search_year_to'} )&& $param->{'search_year_to'} ne "" )  {  
170          push( @conditions,          if ($sth->rows != $results) {
171              ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) <= "'                  my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
172                . $param->{'search_year_to'} ."\"");                  $bug =~ s/\s+/ /gs;
173      }                  print STDERR "$bug\n";
   
     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) = @_;  
         
       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;        
174          }          }
175    
176            my @ret;
177                
178        my $st = $dbh->prepare(          while (my $row = $sth->fetchrow_hashref()) {
179            $sql                  push @ret, $row;
180            );              }
181        
182            $sth->finish();
183            return ($results, \@ret);
184    }
185    
186        $st->execute;  sub getHyperEstraier_url($) {
187                  my ($use_hest) = @_;
188        my @ret = ();  
189        my $tmp;          return unless $use_hest;
190          
191        while ($tmp = $st->fetchrow_hashref())          use HyperEstraier;
192          {          my ($index_path, $index_node_url);
193              push(@ret, {  
194                             'hname'       => $tmp->{'hname'},          if ($use_hest =~ m#^http://#) {
195                             'sname'       => $tmp->{'sname'},                  $index_node_url = $use_hest;
196                             'sharename'   => $tmp->{'sharename'},          } else {
197                             'backupno'    => $tmp->{'backupNum'},                  $index_path = $TopDir . '/' . $index_path;
198                             'fname'       => $tmp->{'filename'},                  $index_path =~ s#//#/#g;
                            'fpath'       => $tmp->{'filepath'},  
                            'networkpath' => $tmp->{'networkPath'},  
                            'date'        => $tmp->{'date'},  
                            'type'        => $tmp->{'filetype'},  
                            'size'        => $tmp->{'size'},  
                            'id'          => $tmp->{'fid'},  
                            'dvd'         => $tmp->{'dvd'}  
                        }  
             );  
                                   
199          }          }
200                  return ($index_path, $index_node_url);
201        $st->finish();  }
202        $dbh->disconnect();  
203        return @ret;  sub getFilesHyperEstraier($) {
204    }          my ($param) = @_;
205    
206  sub getBackupsNotBurned()          my $offset = $param->{'offset'} || 0;
207    {          $offset *= $on_page;
208        my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",  
209          "", "", { RaiseError => 1, AutoCommit => 1 } );                die "no index_path?" unless ($hest_index_path);
210        my $sql = q{  
211            SELECT          use HyperEstraier;
212              hosts.ID         AS hostID,  
213              hosts.name       AS host,          my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path);
214              backups.num      AS backupno,  
215              backups.type     AS type,          # open the database
216              backups.date     AS date          my $db;
217            FROM backups, shares, files, hosts          if ($index_path) {
218            WHERE                  $db = HyperEstraier::Database->new();
219              backups.num    = files.backupNum  AND                  $db->open($index_path, $HyperEstraier::ESTDBREADER);
220              shares.ID      = files.shareID    AND                    } elsif ($index_node_url) {
221              backups.hostID = shares.hostID    AND                  $db ||= HyperEstraier::Node->new($index_node_url);
222              hosts.ID       = backups.hostID   AND                  $db->set_auth('admin', 'admin');
223              files.dvdid    IS NULL          } else {
224            GROUP BY                  die "BUG: unimplemented";
             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'}  
                        }  
             );  
225          }          }
         
       return @ret;        
   }  
226    
227  sub displayBackupsGrid()          # create a search condition object
228    {          my $cond = HyperEstraier::Condition->new();
229        my $retHTML = "";  
230        my $addForm = 1;          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              $retHTML .= <<EOF3;  sub displayBackupsGrid() {
408  <script language="javascript" type="text/javascript">  
409            my $retHTML .= q{
410                    <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  EOF3  DIV#fixedBox #note {
443                $retHTML .= q{<form name="forma" method="POST" action="}."$MyURL"."?action=burn\"";          display: block;
444                $retHTML.= q{<input type="hidden" value="burn" name="action">};          width: 100%;
445                $retHTML .= q{<input type="hidden" value="results" name="search_results">};  }
446          }  
447        $retHTML .= "<table style=\"fview\">";  DIV#fixedBox #submitBurner {
448        $retHTML .= "<tr> ";          display: block;
449        if ($addForm)          width: 100%;
450          {          margin-top: 0.5em;
451              $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";          cursor: pointer;
452          }  }
453        $retHTML .=  "<td class=\"tableheader\">Host</td> <td class=\"tableheader\">Backup no</td> <td class=\"tableheader\">Type</td> <td class=\"tableheader\">date</td></tr>";  
454        my @backups = getBackupsNotBurned();  * HTML {
455        my $backup;          overflow-y: hidden;
456    }
457        if ($addForm)  
458          {  * HTML BODY {
459              $retHTML .= "<tr>";          overflow-y: auto;
460              $retHTML .= "<td colspan=7 style=\"tableheader\">";          height: 100%;
461              $retHTML .= "<input type=\"submit\" value=\"Burn selected backups on medium\" name=\"submitBurner\">";          font-size: 100%;
462              $retHTML .= "</td>";  }
463              $retHTML .= "</tr>";  
464                * HTML DIV#fixedBox {
465          }          position: absolute;
466        foreach $backup(@backups)  }
467          {  
468              my $ftype = "";  #mContainer, #gradient, #mask, #progressIndicator {
469                        display: block;
470              $retHTML .= "<tr>";          width: 100%;
471              if ($addForm)          font-size: 10pt;
472                {          font-weight: bold;
473                    $retHTML .= "<td class=\"fview\"> <input type=\"checkbox\" name=\"fcb"          text-align: center;
474                      .$backup->{'hostid'}."_".$backup->{'backupno'}          vertical-align: middle;
475                    ."\" value=\"".$backup->{'hostid'}."_".$backup->{'backupno'}."\"> </td>";          padding: 1px;
476                }      }
477                
478              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'host'} . "</td>";  #gradient, #mask, #progressIndicator {
479              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'backupno'} . "</td>";          left: 0;
480              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'type'} . "</td>";          border-width: 1px;
481              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'date'} . "<td>";          border-style: solid;
482              $retHTML .= "</tr>";          border-color: #000000;
483          }          color: #404040;
484        $retHTML .= "</table>";          margin: 0.4em;
485        if ($addForm)          position: absolute;
486         {          margin-left: -1px;
487             $retHTML .= "</form>";          margin-top: -1px;
488         }          margin-bottom: -1px;
489                  overflow: hidden;
490        return $retHTML;  }
491      
492      #mContainer {
493    }                display: block;
494            position: relative;
495  sub displayGrid($$)          padding: 0px;
496    {          margin-top: 0.4em;
497        my ($where, $addForm) = @_;          margin-bottom: 0.5em;
498        my $retHTML = "";  }
499          
500        if ($addForm)  #gradient {
501          {          z-index: 1;
502        $retHTML .= <<EOF3;          background-color: #FFFF00;
503  <script language="javascript" type="text/javascript">  }
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      function checkAll(location)  var debug_div = null;
520      {  EOF3
521        for (var i=0;i<document.forma.elements.length;i++)  
522        {          # take maximum archive size from configuration
523          var e = document.forma.elements[i];          $retHTML .= 'var media_size = '. $Conf{MaxArchiveSize} .';';
524          if ((e.checked || !e.checked) && e.name != \'all\') {  
525              if (eval("document.forma."+location+".checked")) {          $retHTML .= <<'EOF3';
526                  e.checked = true;  
527              } else {  function debug(msg) {
528                  e.checked = false;  //      return; // Disable debugging
529              }  
530          }          if (! debug_div) debug_div = document.getElementById('debug');
531        }  
532      }          // this will create debug div if it doesn't exist.
533            if (! debug_div) {
534                    debug_div = document.createElement('div');
535                    if (document.body) document.body.appendChild(debug_div);
536                    else debug_div = null;
537            }
538            if (debug_div) {
539                    debug_div.appendChild(document.createTextNode(msg));
540                    debug_div.appendChild(document.createElement("br"));
541            }
542    }
543    
544    
545    var element_id_cache = Array();
546    
547    function element_id(name,element) {
548            if (! element_id_cache[name]) {
549                    element_id_cache[name] = self.document.getElementById(name);
550            }
551            return element_id_cache[name];
552    }
553    
554    function checkAll(location) {
555            var f = element_id('forma') || null;
556            if (!f) return false;
557    
558            var len = f.elements.length;
559            var check_all = element_id('allFiles');
560            var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
561    
562            for (var i = 0; i < len; i++) {
563                    var e = f.elements[i];
564                    if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
565                            if (check_all.checked) {
566                                    if (e.checked) continue;
567                                    var el = element_id("fss" + e.name.substr(3));
568                                    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                                    } else {
574                                            break;
575                                    }
576                            } else {
577                                    e.checked = false;
578                            }
579                    }
580            }
581            update_sum(suma);
582    }
583    
584    function update_sum(suma) {
585            element_id('forma').elements['totalsize'].value = suma;
586            pbar_set(suma, media_size);
587            debug('total size: ' + suma);
588    }
589    
590    function sumiraj(e) {
591            var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
592            var len = element_id('forma').elements.length;
593            if (e) {
594                    var size = parseInt( element_id("fss" + e.name.substr(3)).value);
595                    if (e.checked) {
596                            suma += size;
597                    } else {
598                            suma -= size;
599                    }
600            } else {
601                    suma = 0;
602                    for (var i = 0; i < len; i++) {
603                            var e = element_id('forma').elements[i];
604                            if (e.name != 'all' && e.checked && e.name.substr(0,3) == 'fcb') {
605                                    var el = element_id("fss" + e.name.substr(3));
606                                    if (el && el.value) suma += parseInt(el.value) || 0;
607                            }
608                    }
609            }
610            update_sum(suma);
611            return suma;
612    }
613    
614    /* progress bar */
615    
616    var _pbar_width = null;
617    var _pbar_warn = 10;    // change color in last 10%
618    
619    function pbar_reset() {
620            element_id("mask").style.left = "0px";
621            _pbar_width = element_id("mContainer").offsetWidth - 2;
622            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    
628    function dec2hex(d) {
629            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  </script>        <!--
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  EOF3
709                $retHTML .= q{<form name="forma" method="POST" action="}."$MyURL"."?action=burn\"";          $retHTML .= q{
710                $retHTML.= q{<input type="hidden" value="burn" name="action">};                          <input type="hidden" value="burn" name="action">
711                $retHTML .= q{<input type="hidden" value="results" name="search_results">};                          <input type="hidden" value="results" name="search_results">
712          }                          <table style="fview" border="0" cellspacing="0" cellpadding="2">
713        $retHTML .= "<table style=\"fview\">";                          <tr class="tableheader">
714        $retHTML .= "<tr> ";                          <td class="tableheader">
715        if ($addForm)                                  <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
716          {                          </td>
717              $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";                          <td align="center">Share</td>
718          }                          <td align="center">Backup no</td>
719        $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>";                          <td align="center">Type</td>
720        my @files = getFiles($where);                          <td align="center">date</td>
721        my $file;                          <td align="center">age/days</td>
722                            <td align="center">size/MB</td>
723        if ($addForm)                          <td align="center">gzip size/kB</td>
724          {                          </tr>
725              $retHTML .= "<tr>";  
726              $retHTML .= "<td colspan=7 style=\"tableheader\">";          };
727              $retHTML .= "<input type=\"submit\" value=\"Burn selected files on medium\" name=\"submitBurner\">";  
728              $retHTML .= "</td>";          my @color = (' bgcolor="#e0e0e0"', '');
729              $retHTML .= "</tr>";  
730                        my $i = 0;
731          }          my $host = '';
732        foreach $file(@files)  
733          {          foreach my $backup ( getBackupsNotBurned() ) {
734              my $ftype = "";  
735                                if ($host ne $backup->{'host'}) {
736              if ($file->{'type'} == BPC_FTYPE_DIR)                          $i++;
737                {                          $host = $backup->{'host'};
738                    $ftype = "dir";                  }
739                }                  my $ftype = "";
740              else  
741                {                  my $checkbox_key = $backup->{'hostid'}. '_' .$backup->{'backupnum'} . '_' . $backup->{'id'};
742                    $ftype = "file";  
743                }                  $retHTML .=
744              $retHTML .= "<tr>";                          '<tr' . $color[$i %2 ] . '>
745              if ($addForm)                          <td class="fview">';
746                {  
747                    $retHTML .= "<td class=\"fview\"> <input type=\"checkbox\" name=\"fcb"                  if (($backup->{'inc_size'} || 0) > 0) {
748                      .$file->{'id'}                          $retHTML .= '
749                    ."\" value=\"".$file->{'id'}."\"> </td>";                          <input type="checkbox" name="fcb' . $checkbox_key . '" value="' . $checkbox_key . '" onClick="sumiraj(this);">';
750                }                      }
751                
752              $retHTML .= "<td class=\"fviewborder\">" . $file->{'hname'} ."</td>";                  $retHTML .=
753              $retHTML .= "<td class=\"fviewborder\">" . $file->{'fname'} . "</td>";                          '</td>' .
754              $retHTML .= "<td class=\"fviewborder\">" . $ftype . "</td>";                          '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
755              $retHTML .= "<td class=\"fviewborder\">" . $file->{'backupno'} . "</td>";                          '<td align="center">' . $backup->{'backupnum'} . '</td>' .
756              $retHTML .= "<td class=\"fviewborder\">" . $file->{'size'} . "</td>";                          '<td align="center">' . $backup->{'type'} . '</td>' .
757              $retHTML .= "<td class=\"fviewborder\">" . $file->{'date'} . "</td>";                          '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
758              $retHTML .= "<td class=\"fviewborder\">" . $file->{'dvd'} . "</td>";                          '<td align="center">' . $backup->{'age'} . '</td>' .
759              $retHTML .= "</tr>";                          '<td align="right">' . $backup->{'size'} . '</td>' .
760          }                          '<td align="right">' . $backup->{'inc_size'} .
761        $retHTML .= "</table>";                          '<input type="hidden" iD="fss'.$checkbox_key .'" value="'. $backup->{'inc_size'} .'"></td>' .
762        if ($addForm)  
763         {                          "</tr>\n";
764             $retHTML .= "</form>";          }
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.6  
changed lines
  Added in v.194

  ViewVC Help
Powered by ViewVC 1.1.26