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

Legend:
Removed from v.6  
changed lines
  Added in v.186

  ViewVC Help
Powered by ViewVC 1.1.26