/[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 17 by dpavlin, Mon Jul 11 13:22:38 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{
     if ( defined( $param->{'search_day_from'} )   && $param->{'search_day_from'} ne "" ) {  
         push( @conditions,  
             ' strftime("%d", datetime(files.date, "unixepoch","localtime")) >= "'  
               . $param->{'search_day_from'}  ."\"");  
     }  
     if ( defined( $param->{'search_month_from'} ) && $param->{'search_month_from'} ne "") {  
         push( @conditions,  
             ' strftime("%m", datetime(files.date, "unixepoch","localtime")) >= "'  
               . $param->{'search_month_from'}  ."\"");  
     }  
     if ( defined( $param->{'search_year_from'} ) && $param->{'search_year_from'} ne "") {  
         push( @conditions,  
             ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) >= "'  
               . $param->{'search_year_from'}  ."\"");  
     }  
     if ( defined( $param->{'search_day_to'} )   && $param->{'search_day_to'} ne "" ) {  
         push( @conditions,  
             ' strftime("%d", datetime(files.date, "unixepoch","localtime")) <= "'  
               . $param->{'search_day_to'}  ."\"");  
     }  
     if ( defined( $param->{'search_month_to'} ) && $param->{'search_month_to'} ne "" ) {  
         push( @conditions,  
             ' strftime("%m", datetime(files.date, "unixepoch","localtime")) <= "'  
               . $param->{'search_month_to'} ."\"" );  
     }  
     if ( defined( $param->{'search_year_to'} )&& $param->{'search_year_to'} ne "" )  {  
         push( @conditions,  
             ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) <= "'  
               . $param->{'search_year_to'} ."\"");  
     }  
   
     if ( defined( $param->{'search_host'} ) && $param->{'search_host'} ne "") {  
       push( @conditions, ' backups.hostID = ' . $param->{'search_host'} );  
     }  
   
     if ( defined ($param->{'search_filename'}) && $param->{'search_filename'} ne "") {  
         push (@conditions, " files.name LIKE '".$param->{'search_filename'}."%'");  
         }  
       
     $retSQL = "";  
     foreach $cond(@conditions)  
       {  
           if ($retSQL ne "")  
             {  
                 $retSQL .= " AND ";  
             }  
           $retSQL .= $cond;  
       }        
   
       
     return $retSQL;  
 }  
   
 sub getFiles($$)  
   {  
       my ($where, $offset) = @_;  
         
         
       my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",  
         "", "", { RaiseError => 1, AutoCommit => 1 } );  
       my $sql =            
         q{    
                 SELECT  files.id                        AS fid,  
                         hosts.name                      AS hname,  
                         shares.name                     AS sname,  
                         shares.share                    AS sharename,  
                         files.backupNum                 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  
144                  FROM files                  FROM files
145                          INNER JOIN shares       ON files.shareID=shares.ID                          INNER JOIN shares       ON files.shareID=shares.ID
146                          INNER JOIN hosts        ON hosts.ID = shares.hostID                          INNER JOIN hosts        ON hosts.ID = shares.hostID
147                          LEFT  JOIN dvds         ON dvds.ID = files.dvdid                          INNER JOIN backups      ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = files.shareID
148            };          };
149    
150            my $sql_where;
151            my $where = getWhere($param);
152            $sql_where = " WHERE ". $where if ($where);
153    
154            my $sql_order = qq{
155                    ORDER BY files.date
156                    LIMIT $on_page
157                    OFFSET ?
158            };
159    
160            my $sql_count = qq{ select count(files.id) $sql_from $sql_where };
161            my $sql_results = qq{ select $sql_cols $sql_from $sql_where $sql_order };
162    
163            my $sth = $dbh->prepare($sql_count);
164            $sth->execute();
165            my ($results) = $sth->fetchrow_array();
166    
167        if (defined($where) && $where ne "")          $sth = $dbh->prepare($sql_results);
168          {          $sth->execute( $offset );
169              $sql .= " WHERE ". $where;        
170            if ($sth->rows != $results) {
171                    my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
172                    $bug =~ s/\s+/ /gs;
173                    print STDERR "$bug\n";
174          }          }
175    
176        $sql .=          my @ret;
         q{            
             ORDER BY files.id  
               LIMIT 100  
               OFFSET ? * 100 + 1  
         };  
         
         
177                
178        my $st = $dbh->prepare(          while (my $row = $sth->fetchrow_hashref()) {
179            $sql                  push @ret, $row;
           );      
       if (!defined($offset) && $offset ne "")  
       {  
         $st->bind_param(1, $offset);  
       }  
       else  
       {  
         $st->bind_param(1,0);  
       }  
       $st->execute;  
         
       my @ret = ();  
       my $tmp;  
         
       while ($tmp = $st->fetchrow_hashref())  
         {  
             push(@ret, {  
                            'hname'       => $tmp->{'hname'},  
                            'sname'       => $tmp->{'sname'},  
                            'sharename'   => $tmp->{'sharename'},  
                            'backupno'    => $tmp->{'backupNum'},  
                            'fname'       => $tmp->{'filename'},  
                            'fpath'       => $tmp->{'filepath'},  
                            'networkpath' => $tmp->{'networkPath'},  
                            'date'        => $tmp->{'date'},  
                            'type'        => $tmp->{'filetype'},  
                            'size'        => $tmp->{'size'},  
                            'id'          => $tmp->{'fid'},  
                            'dvd'         => $tmp->{'dvd'}  
                        }  
             );  
                                   
180          }          }
181              
182        $st->finish();          $sth->finish();
183        $dbh->disconnect();          return ($results, \@ret);
184        return @ret;  }
185    }  
186    sub getHyperEstraier_url($) {
187  sub getBackupsNotBurned()          my ($use_hest) = @_;
188    {  
189        my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",          return unless $use_hest;
190          "", "", { RaiseError => 1, AutoCommit => 1 } );        
191        my $sql = q{          use HyperEstraier;
192            SELECT          my ($index_path, $index_node_url);
193              hosts.ID         AS hostID,  
194              hosts.name       AS host,          if ($use_hest =~ m#^http://#) {
195              backups.num      AS backupno,                  $index_node_url = $use_hest;
196              backups.type     AS type,          } else {
197              backups.date     AS date                  $index_path = $TopDir . '/' . $index_path;
198            FROM backups, shares, files, hosts                  $index_path =~ s#//#/#g;
199            WHERE          }
200              backups.num    = files.backupNum  AND          return ($index_path, $index_node_url);
201              shares.ID      = files.shareID    AND            }
202              backups.hostID = shares.hostID    AND  
203              hosts.ID       = backups.hostID   AND  sub getFilesHyperEstraier($) {
204              files.dvdid    IS NULL          my ($param) = @_;
205            GROUP BY  
206              backups.hostID, backups.num          my $offset = $param->{'offset'} || 0;
207        };          $offset *= $on_page;
208        my $st = $dbh -> prepare( $sql );  
209        my @ret = ();          die "no index_path?" unless ($hest_index_path);
210        $st -> execute();  
211            use HyperEstraier;
212        while ( my $tmp = $st -> fetchrow_hashref() )  
213          {                    my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path);
214              push(@ret, {  
215                           'host'     => $tmp->{'host'},          # open the database
216                           'hostid'   => $tmp->{'hostID'},          my $db;
217                           'backupno' => $tmp->{'backupno'},          if ($index_path) {
218                           'type'     => $tmp->{'type'},                  $db = HyperEstraier::Database->new();
219                           'date'     => $tmp->{'date'}                  $db->open($index_path, $HyperEstraier::ESTDBREADER);
220                         }          } elsif ($index_node_url) {
221              );                  $db ||= HyperEstraier::Node->new($index_node_url);
222                    $db->set_auth('admin', 'admin');
223            } else {
224                    die "BUG: unimplemented";
225            }
226    
227            # create a search condition object
228            my $cond = HyperEstraier::Condition->new();
229    
230            my $q = $param->{'search_filename'};
231            my $shareid = $param->{'search_share'};
232    
233            if (length($q) > 0) {
234                    # exact match
235                    $cond->add_attr("filepath ISTRINC $q");
236    
237                    $q =~ s/(.)/$1 /g;
238                    # set the search phrase to the search condition object
239                    $cond->set_phrase($q);
240            }
241    
242            my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
243    
244            $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
245            $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);
246    
247            $cond->add_attr("date NUMGE $files_from") if ($files_from);
248            $cond->add_attr("date NUMLE $files_to") if ($files_to);
249    
250            $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
251    
252    #       $cond->set_max( $offset + $on_page );
253            $cond->set_options( $HyperEstraier::Condition::SURE );
254            $cond->set_order( 'date NUMA' );
255    
256            # get the result of search
257            my @res;
258            my ($result, $hits);
259    
260            if ($index_path) {
261                    $result = $db->search($cond, 0);
262                    $hits = $result->size;
263            } elsif ($index_node_url) {
264                    $result = $db->search($cond, 0);
265                    $hits = $result->doc_num;
266            } else {
267                    die "BUG: unimplemented";
268            }
269    
270            # for each document in result
271            for my $i ($offset .. ($offset + $on_page - 1)) {
272                    last if ($i >= $hits);
273    
274                    my $doc;
275                    if ($index_path) {
276                            my $id = $result->get($i);
277                            $doc = $db->get_doc($id, 0);
278                    } elsif ($index_node_url) {
279                            $doc = $result->get_doc($i);
280                    } else {
281                            die "BUG: unimplemented";
282                    }
283    
284                    my $row;
285                    foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {
286                            $row->{$c} = $doc->attr($c);
287                    }
288                    push @res, $row;
289          }          }
         
       return @ret;        
   }  
290    
291  sub displayBackupsGrid()          return ($hits, \@res);
292    {  }
293        my $retHTML = "";  
294        my $addForm = 1;  sub getGzipName($$$)
295    {
296            my ($host, $share, $backupnum) = @_;
297            my $ret = $Conf{GzipSchema};
298            
299            $share =~ s/\//_/g;
300            $ret =~ s/\\h/$host/ge;
301            $ret =~ s/\\s/$share/ge;
302            $ret =~ s/\\n/$backupnum/ge;
303    
304            $ret =~ s/__+/_/g;
305    
306            return $ret;
307            
308    }
309    
310    sub get_tgz_size_by_name($) {
311            my $name = shift;
312    
313            my $tgz = $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.$name;
314    
315            my $size = -1;
316    
317            if (-f $tgz) {
318                    $size = (stat($tgz))[7];
319            } elsif (-d $tgz) {
320                    opendir(my $dir, $tgz) || die "can't opendir $tgz: $!";
321                    my @parts = grep { !/^\./ && -f "$tgz/$_" } readdir($dir);
322                    $size = 0;
323                    foreach my $part (@parts) {
324                            $size += (stat("$tgz/$part"))[7] || die "can't stat $tgz/$part: $!";
325                    }
326                    closedir $dir;
327            }
328    
329            return $size;
330    }
331    
332    sub getGzipSize($$)
333    {
334            my ($hostID, $backupNum) = @_;
335            my $sql;
336            my $dbh = get_dbh();
337            
338            $sql = q{
339                                    SELECT hosts.name  as host,
340                                               shares.name as share,
341                                               backups.num as backupnum
342                                    FROM hosts, backups, shares
343                                    WHERE shares.id=backups.shareid AND
344                                              hosts.id =backups.hostid AND
345                                              hosts.id=? AND
346                                              backups.num=?
347                            };
348            my $sth = $dbh->prepare($sql);
349            $sth->execute($hostID, $backupNum);
350    
351            my $row = $sth->fetchrow_hashref();
352    
353            return get_tgz_size_by_name(
354                    getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'})
355            );
356    }
357    
358    sub getBackupsNotBurned() {
359    
360            my $dbh = get_dbh();
361    
362            my $sql = q{
363                    SELECT
364                            backups.hostID AS hostID,
365                            hosts.name AS host,
366                            shares.name AS share,
367                            backups.num AS backupnum,
368                            backups.type AS type,
369                            backups.date AS date,
370                            backups.size AS size,
371                            backups.id AS id,
372                            backups.inc_size AS inc_size
373                    FROM backups
374                    INNER JOIN shares       ON backups.shareID=shares.ID
375                    INNER JOIN hosts        ON backups.hostID = hosts.ID
376                    LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
377                    WHERE backups.inc_size > 0 AND backups.inc_deleted is false AND archive_backup.backup_id IS NULL
378                    GROUP BY
379                            backups.hostID,
380                            hosts.name,
381                            shares.name,
382                            backups.num,
383                            backups.shareid,
384                            backups.id,
385                            backups.type,
386                            backups.date,
387                            backups.size,
388                            backups.inc_size
389                    ORDER BY backups.date
390            };
391            my $sth = $dbh->prepare( $sql );
392            my @ret;
393            $sth->execute();
394    
395            while ( my $row = $sth->fetchrow_hashref() ) {
396                    $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
397                    $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
398    
399                    # do some cluster calculation (approximate) and convert to kB
400                    $row->{'inc_size'} = int(($row->{'inc_size'} + 1023 ) / ( 2 * 1024 ) * 2);
401                    push @ret, $row;
402            }
403                
404        if ($addForm)          return @ret;      
405          {  }
406    
407    sub displayBackupsGrid() {
408    
409            my $retHTML .= q{
410                    <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
411            };
412    
413              $retHTML .= <<EOF3;          $retHTML .= <<'EOF3';
414  <script language="javascript" type="text/javascript">  <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    DIV#fixedBox, DIV#fixedBox INPUT, DIV#fixedBox TEXTAREA {
427            font-size: 10pt;
428    }
429    
430    FORM>DIV#fixedBox {
431            position: fixed !important;
432            left: 0.5em !important;
433            top: auto !important;
434            bottom: 1em !important;
435            width: 15% !important;
436    }
437    
438    DIV#fixedBox INPUT[type=text], DIV#fixedBox TEXTAREA {
439            border: 1px solid #00C000;
440    }
441    
442    DIV#fixedBox #note {
443            display: block;
444            width: 100%;
445    }
446    
447    DIV#fixedBox #submitBurner {
448            display: block;
449            width: 100%;
450            margin-top: 0.5em;
451            cursor: pointer;
452    }
453    
454    * HTML {
455            overflow-y: hidden;
456    }
457    
458    * HTML BODY {
459            overflow-y: auto;
460            height: 100%;
461            font-size: 100%;
462    }
463    
464    * HTML DIV#fixedBox {
465            position: absolute;
466    }
467    
468    #mContainer, #gradient, #mask, #progressIndicator {
469            display: block;
470            width: 100%;
471            font-size: 10pt;
472            font-weight: bold;
473            text-align: center;
474            vertical-align: middle;
475            padding: 1px;
476    }
477    
478    #gradient, #mask, #progressIndicator {
479            left: 0;
480            border-width: 1px;
481            border-style: solid;
482            border-color: #000000;
483            color: #404040;
484            margin: 0.4em;
485            position: absolute;
486            margin-left: -1px;
487            margin-top: -1px;
488            margin-bottom: -1px;
489            overflow: hidden;
490    }
491    
492    #mContainer {
493            display: block;
494            position: relative;
495            padding: 0px;
496            margin-top: 0.4em;
497            margin-bottom: 0.5em;
498    }
499    
500    #gradient {
501            z-index: 1;
502            background-color: #FFFF00;
503    }
504    
505    #mask {
506            z-index: 2;
507            background-color: #FFFFFF;
508    }
509    
510      function checkAll(location)  #progressIndicator {
511      {          z-index: 3;
512        for (var i=0;i<document.forma.elements.length;i++)          background-color: transparent;
513        {  }
514          var e = document.forma.elements[i];  -->
515          if ((e.checked || !e.checked) && e.name != \'all\') {  </style>
516              if (eval("document.forma."+location+".checked")) {  <script type="text/javascript">
517                  e.checked = true;  <!--
518              } else {  
519                  e.checked = false;  var debug_div = null;
             }  
         }  
       }  
     }  
 //-->  
 </script>        
520  EOF3  EOF3
521                $retHTML .= q{<form name="forma" method="POST" action="}."$MyURL"."?action=burn\"";  
522                $retHTML.= q{<input type="hidden" value="burn" name="action">};          # take maximum archive size from configuration
523                $retHTML .= q{<input type="hidden" value="results" name="search_results">};          $retHTML .= 'var media_size = '. $Conf{MaxArchiveSize} .';';
524          }  
525        $retHTML .= "<table style=\"fview\">";          $retHTML .= <<'EOF3';
526        $retHTML .= "<tr> ";  
527        if ($addForm)  function debug(msg) {
528          {  //      return; // Disable debugging
529              $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";  
530          }          if (! debug_div) debug_div = document.getElementById('debug');
531        $retHTML .=  "<td class=\"tableheader\">Host</td> <td class=\"tableheader\">Backup no</td> <td class=\"tableheader\">Type</td> <td class=\"tableheader\">date</td></tr>";  
532        my @backups = getBackupsNotBurned();          // this will create debug div if it doesn't exist.
533        my $backup;          if (! debug_div) {
534                    debug_div = document.createElement('div');
535        if ($addForm)                  if (document.body) document.body.appendChild(debug_div);
536          {                  else debug_div = null;
537              $retHTML .= "<tr>";          }
538              $retHTML .= "<td colspan=7 style=\"tableheader\">";          if (debug_div) {
539              $retHTML .= "<input type=\"submit\" value=\"Burn selected backups on medium\" name=\"submitBurner\">";                  debug_div.appendChild(document.createTextNode(msg));
540              $retHTML .= "</td>";                  debug_div.appendChild(document.createElement("br"));
541              $retHTML .= "</tr>";          }
542                }
543          }  
544        foreach $backup(@backups)  
545          {  var element_id_cache = Array();
546              my $ftype = "";  
547                function element_id(name,element) {
548              $retHTML .= "<tr>";          if (! element_id_cache[name]) {
549              if ($addForm)                  element_id_cache[name] = self.document.getElementById(name);
550                {          }
551                    $retHTML .= "<td class=\"fview\"> <input type=\"checkbox\" name=\"fcb"          return element_id_cache[name];
552                      .$backup->{'hostid'}."_".$backup->{'backupno'}  }
553                    ."\" value=\"".$backup->{'hostid'}."_".$backup->{'backupno'}."\"> </td>";  
554                }      function checkAll(location) {
555                        var f = element_id('forma') || null;
556              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'host'} . "</td>";          if (!f) return false;
557              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'backupno'} . "</td>";  
558              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'type'} . "</td>";          var len = f.elements.length;
559              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'date'} . "<td>";          var check_all = element_id('allFiles');
560              $retHTML .= "</tr>";          var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
561          }  
562        $retHTML .= "</table>";          for (var i = 0; i < len; i++) {
563        if ($addForm)                  var e = f.elements[i];
564         {                  if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
565             $retHTML .= "</form>";                          if (check_all.checked) {
566         }                                  if (e.checked) continue;
567                                    var el = element_id("fss" + e.name.substr(3));
568                                    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    <!--
704    <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
705    no debug output yet
706    </div>
707    -->
708    EOF3
709            $retHTML .= q{
710                            <input type="hidden" value="burn" name="action">
711                            <input type="hidden" value="results" name="search_results">
712                            <table style="fview" border="0" cellspacing="0" cellpadding="2">
713                            <tr class="tableheader">
714                            <td class="tableheader">
715                                    <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
716                            </td>
717                            <td align="center">Share</td>
718                            <td align="center">Backup no</td>
719                            <td align="center">Type</td>
720                            <td align="center">date</td>
721                            <td align="center">age/days</td>
722                            <td align="center">size/MB</td>
723                            <td align="center">gzip size/kB</td>
724                            </tr>
725    
726            };
727    
728            my @color = (' bgcolor="#e0e0e0"', '');
729    
730            my $i = 0;
731            my $host = '';
732    
733            foreach my $backup ( getBackupsNotBurned() ) {
734    
735                    if ($host ne $backup->{'host'}) {
736                            $i++;
737                            $host = $backup->{'host'};
738                    }
739                    my $ftype = "";
740    
741                    my $checkbox_key = $backup->{'hostid'}. '_' .$backup->{'backupnum'} . '_' . $backup->{'id'};
742    
743                    $retHTML .=
744                            '<tr' . $color[$i %2 ] . '>
745                            <td class="fview">';
746    
747                    if (($backup->{'inc_size'} || 0) > 0) {
748                            $retHTML .= '
749                            <input type="checkbox" name="fcb' . $checkbox_key . '" value="' . $checkbox_key . '" onClick="sumiraj(this);">';
750                    }
751    
752                    $retHTML .=
753                            '</td>' .
754                            '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
755                            '<td align="center">' . $backup->{'backupnum'} . '</td>' .
756                            '<td align="center">' . $backup->{'type'} . '</td>' .
757                            '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
758                            '<td align="center">' . $backup->{'age'} . '</td>' .
759                            '<td align="right">' . $backup->{'size'} . '</td>' .
760                            '<td align="right">' . $backup->{'inc_size'} .
761                            '<input type="hidden" iD="fss'.$checkbox_key .'" value="'. $backup->{'inc_size'} .'"></td>' .
762    
763                            "</tr>\n";
764            }
765    
766            $retHTML .= "</table>";
767            $retHTML .= "</form>";
768                
769        return $retHTML;          return $retHTML;
770      }      
771      
772    }        sub displayGrid($) {
773            my ($param) = @_;
774    
775            my $offset = $param->{'offset'};
776            my $hilite = $param->{'search_filename'};
777    
 sub displayGrid($$$$) {  
         my ($where, $addForm, $offset, $hilite) = @_;  
778          my $retHTML = "";          my $retHTML = "";
779    
780          if ($addForm) {          my $start_t = time();
781                  $retHTML .= qq{<form name="forma" method="POST" action="}.$MyURL.qq{?action=search">};  
782                  $retHTML.= qq{<input type="hidden" value="search" name="action">};          my ($results, $files);
783                  $retHTML .= qq{<input type="hidden" value="results" name="search_results">};          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{          $retHTML .= qq{
807          <table style="fview" width="100%">          <div>
808                  <tr>          Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
809                  <td class="tableheader">Host</td>          </div>
810                  <td class="tableheader">Type</td>          <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
811                  <td class="tableheader">Name</td>                  <tr class="fviewheader">
812                  <td class="tableheader">backup no.</td>                  <td></td>
813                  <td class="tableheader">size</td>                  <td align="center">Share</td>
814                  <td class="tableheader">date</td>                  <td align="center">Type and Name</td>
815                  <td class="tableheader">Media</td>                  <td align="center">#</td>
816                    <td align="center">Size</td>
817                    <td align="center">Date</td>
818                    <td align="center">Media</td>
819                  </tr>                  </tr>
820          };          };
821          my @files = getFiles($where, $offset);  
822          my $file;          my $file;
823    
824          sub hilite_html($$) {          sub hilite_html($$) {
# Line 350  sub displayGrid($$$$) { Line 827  sub displayGrid($$$$) {
827                  return $html;                  return $html;
828          }          }
829    
830          foreach $file (@files) {          sub restore_link($$$$$$) {
831                  my $ftype = "file";                  my $type = shift;
832                  $ftype = "dir" if ($file->{'type'} == BPC_FTYPE_DIR);                  my $action = 'RestoreFile';
833                    $action = 'browse' if (lc($type) eq 'dir');
834                  $retHTML .= "<tr>";                  return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
835            }
836                  foreach my $v ((  
837                          $file->{'hname'},          my $i = $offset * $on_page;
838                          $ftype,  
839                          hilite_html( $file->{'fpath'}, $hilite ),          foreach $file (@{ $files }) {
840                          $file->{'backupno'},                  $i++;
841                          $file->{'size'},  
842                          $file->{'date'},                  my $typeStr  = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
843                          $file->{'dvd'}                  $retHTML .= qq{<tr class="fviewborder">};
844                  )) {  
845                          $retHTML .= qq{<td class="fviewborder">$v</td>};                  $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>";                  $retHTML .= "</tr>";
856          }          }
857          $retHTML .= "</table>";          $retHTML .= "</table>";
858    
859          # skip pager          # all variables which has to be transfered
860          return $retHTML;          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          $retHTML .= "<INPUT TYPE=\"hidden\" VALUE=\"\" NAME=\"offset\">";          while ($page <= $max_page) {
891          for (my $ii = 1; $ii <= $#files; $ii++) {                  if ($page == $offset) {
892                  $retHTML .= "<a href = \"#\" onclick=\"document.forma.offset.value=$ii;document.forma.submit();\">$ii</a>";                          $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
893                  if ($ii < $#files) {                  } else {
894                          $retHTML .= " | ";                          $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          $retHTML .= "</form>" if ($addForm);          if ($offset < $max_page) {
912                          $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
913            }
914    
915            $retHTML .= "</div>";
916    
917          return $retHTML;          return $retHTML;
918  }  }
919    

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

  ViewVC Help
Powered by ViewVC 1.1.26