/[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 211 by dpavlin, Sun Oct 16 10:57:55 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 "") {  my $sort_def = {
124          push( @conditions,          default => 'date_a',
125              ' strftime("%m", datetime(backups.date, "unixepoch","localtime")) >= "'          sql => {
126                . $param->{'search_backup_month_from'}  ."\"");                  share_d => 'shares.name DESC',
127      }                  share_a => 'shares.name ASC',
128      if ( defined( $param->{'search_backup_month_to'} ) && $param->{'search_backup_month_to'} ne "") {                  path_d => 'files.path DESC',
129          push( @conditions,                  path_a => 'files.path ASC',
130              ' strftime("%m", datetime(backups.date, "unixepoch","localtime")) <= "'                  num_d => 'files.backupnum DESC',
131                . $param->{'search_backup_month_to'}  ."\"");                  num_a => 'files.backupnum ASC',
132      }                  size_d => 'files.size DESC',
133      if ( defined( $param->{'search_backup_year_from'} ) && $param->{'search_backup_year_from'} ne "") {                  size_a => 'files.size ASC',
134          push( @conditions,                  date_d => 'files.date DESC',
135              ' strftime("%Y", datetime(backups.date, "unixepoch","localtime")) >= "'                  date_a => 'files.date ASC',
136                . $param->{'search_backup_year_from'}  ."\"");          },
137      }          est => {
138      if ( defined( $param->{'search_backup_year_to'} ) && $param->{'search_backup_year_to'} ne "") {                  share_d => 'sname STRD',
139          push( @conditions,                  share_a => 'sname STRA',
140              ' strftime("%Y", datetime(backups.date, "unixepoch","localtime")) <= "'                  path_d => 'filepath STRD',
141                . $param->{'search_backup_year_to'}  ."\"");                  path_a => 'filepath STRA',
142      }                  num_d => 'backupnum NUMD',
143                    num_a => 'backupnum NUMA',
144      if ( defined( $param->{'search_day_from'} )   && $param->{'search_day_from'} ne "" ) {                  size_d => 'size NUMD',
145          push( @conditions,                  size_a => 'size NUMA',
146              ' strftime("%d", datetime(files.date, "unixepoch","localtime")) >= "'                  date_d => 'date NUMD',
147                . $param->{'search_day_from'}  ."\"");                  date_a => 'date NUMA',
148      }          }
149      if ( defined( $param->{'search_month_from'} ) && $param->{'search_month_from'} ne "") {  };
150          push( @conditions,  
151              ' strftime("%m", datetime(files.date, "unixepoch","localtime")) >= "'  sub getSort($$) {
152                . $param->{'search_month_from'}  ."\"");          my ($type, $sort_order) = @_;
153      }  
154      if ( defined( $param->{'search_year_from'} ) && $param->{'search_year_from'} ne "") {          $sort_order ||= $sort_def->{'default'};
155          push( @conditions,  
156              ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) >= "'          die "unknown type: $type" unless ($sort_def->{$type});
157                . $param->{'search_year_from'}  ."\"");  
158      }          if (my $ret = $sort_def->{$type}->{$sort_order}) {
159      if ( defined( $param->{'search_day_to'} )   && $param->{'search_day_to'} ne "" ) {                  return $ret;
160          push( @conditions,          } else {
161              ' strftime("%d", datetime(files.date, "unixepoch","localtime")) <= "'                  # fallback to default sort order
162                . $param->{'search_day_to'}  ."\"");                  return $sort_def->{$type}->{ $sort_def->{'default'} };
163      }          }
164      if ( defined( $param->{'search_month_to'} ) && $param->{'search_month_to'} ne "" ) {  }
165          push( @conditions,  
166              ' strftime("%m", datetime(files.date, "unixepoch","localtime")) <= "'  sub getFiles($) {
167                . $param->{'search_month_to'} ."\"" );          my ($param) = @_;
168      }  
169      if ( defined( $param->{'search_year_to'} )&& $param->{'search_year_to'} ne "" )  {          my $offset = $param->{'offset'} || 0;
170          push( @conditions,          $offset *= $on_page;
171              ' strftime("%Y", datetime(files.date, "unixepoch","localtime")) <= "'  
172                . $param->{'search_year_to'} ."\"");          my $dbh = get_dbh();
173      }  
174            my $sql_cols = qq{
175      if ( defined( $param->{'search_host'} ) && $param->{'search_host'} ne "") {                  files.id                        AS fid,
176        push( @conditions, ' backups.hostID = ' . $param->{'search_host'} );                  hosts.name                      AS hname,
177      }                  shares.name                     AS sname,
178                    files.backupnum                 AS backupnum,
179      if ( defined ($param->{'search_filename'}) && $param->{'search_filename'} ne "") {                  files.path                      AS filepath,
180          push (@conditions, " files.name LIKE '".$param->{'search_filename'}."%'");                  files.date                      AS date,
181          }                  files.type                      AS type,
182                        files.size                      AS size
183      $retSQL = "";          };
184      foreach $cond(@conditions)  
185        {          my $sql_from = qq{
           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  
186                  FROM files                  FROM files
187                          INNER JOIN shares       ON files.shareID=shares.ID                          INNER JOIN shares       ON files.shareID=shares.ID
188                          INNER JOIN hosts        ON hosts.ID = shares.hostID                          INNER JOIN hosts        ON hosts.ID = shares.hostID
189                          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
190            };          };
191    
192            my $sql_where;
193            my $where = getWhere($param);
194            $sql_where = " WHERE ". $where if ($where);
195    
196            my $order = getSort('sql', $param->{'sort'});
197    
198            my $sql_order = qq{
199                    ORDER BY $order
200                    LIMIT $on_page
201                    OFFSET ?
202            };
203    
204            my $sql_count = qq{ select count(files.id) $sql_from $sql_where };
205            my $sql_results = qq{ select $sql_cols $sql_from $sql_where $sql_order };
206    
207        if (defined($where) && $where ne "")          my $sth = $dbh->prepare($sql_count);
208          {          $sth->execute();
209              $sql .= " WHERE ". $where;                my ($results) = $sth->fetchrow_array();
210    
211            $sth = $dbh->prepare($sql_results);
212            $sth->execute( $offset );
213    
214            if ($sth->rows != $results) {
215                    my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
216                    $bug =~ s/\s+/ /gs;
217                    print STDERR "$bug\n";
218          }          }
219    
220        $sql .=          my @ret;
         q{            
             ORDER BY files.id  
               LIMIT 100  
               OFFSET ? * 100 + 1  
         };  
         
         
         
       my $st = $dbh->prepare(  
           $sql  
           );      
       if (!defined($offset) && $offset ne "")  
       {  
         $st->bind_param(1, $offset);  
       }  
       else  
       {  
         $st->bind_param(1,0);  
       }  
       $st->execute;  
221                
222        my @ret = ();          while (my $row = $sth->fetchrow_hashref()) {
223        my $tmp;                  push @ret, $row;
         
       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'}  
                        }  
             );  
                                   
224          }          }
225              
226        $st->finish();          $sth->finish();
227        $dbh->disconnect();          return ($results, \@ret);
228        return @ret;  }
229    }  
230    sub getHyperEstraier_url($) {
231  sub getBackupsNotBurned()          my ($use_hest) = @_;
232    {  
233        my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",          return unless $use_hest;
234          "", "", { RaiseError => 1, AutoCommit => 1 } );        
235        my $sql = q{          use HyperEstraier;
236            SELECT          my ($index_path, $index_node_url);
237              hosts.ID         AS hostID,  
238              hosts.name       AS host,          if ($use_hest =~ m#^http://#) {
239              backups.num      AS backupno,                  $index_node_url = $use_hest;
240              backups.type     AS type,          } else {
241              backups.date     AS date                  $index_path = $TopDir . '/' . $index_path;
242            FROM backups, shares, files, hosts                  $index_path =~ s#//#/#g;
           WHERE  
             backups.num    = files.backupNum  AND  
             shares.ID      = files.shareID    AND            
             backups.hostID = shares.hostID    AND  
             hosts.ID       = backups.hostID   AND  
             files.dvdid    IS NULL  
           GROUP BY  
             backups.hostID, backups.num  
       };  
       my $st = $dbh -> prepare( $sql );  
       my @ret = ();  
       $st -> execute();  
   
       while ( my $tmp = $st -> fetchrow_hashref() )  
         {            
             push(@ret, {  
                          'host'     => $tmp->{'host'},  
                          'hostid'   => $tmp->{'hostID'},  
                          'backupno' => $tmp->{'backupno'},  
                          'type'     => $tmp->{'type'},  
                          'date'     => $tmp->{'date'}  
                        }  
             );  
243          }          }
244                  return ($index_path, $index_node_url);
245        return @ret;        }
246    }  
247    sub getFilesHyperEstraier($) {
248            my ($param) = @_;
249    
250            my $offset = $param->{'offset'} || 0;
251            $offset *= $on_page;
252    
253            die "no index_path?" unless ($hest_index_path);
254    
255  sub displayBackupsGrid()          use HyperEstraier;
256    {  
257        my $retHTML = "";          my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path);
258        my $addForm = 1;  
259            # open the database
260            my $db;
261            if ($index_path) {
262                    $db = HyperEstraier::Database->new();
263                    $db->open($index_path, $HyperEstraier::ESTDBREADER);
264            } elsif ($index_node_url) {
265                    $db ||= HyperEstraier::Node->new($index_node_url);
266                    $db->set_auth('admin', 'admin');
267            } else {
268                    die "BUG: unimplemented";
269            }
270    
271            # create a search condition object
272            my $cond = HyperEstraier::Condition->new();
273    
274            my $q = $param->{'search_filename'};
275            my $shareid = $param->{'search_share'};
276    
277            if (length($q) > 0) {
278                    # exact match
279                    $cond->add_attr("filepath ISTRINC $q");
280    
281                    $q =~ s/(.)/$1 /g;
282                    # set the search phrase to the search condition object
283                    $cond->set_phrase($q);
284            }
285    
286            my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
287    
288            $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
289            $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);
290    
291            $cond->add_attr("date NUMGE $files_from") if ($files_from);
292            $cond->add_attr("date NUMLE $files_to") if ($files_to);
293    
294            $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
295    
296    #       $cond->set_max( $offset + $on_page );
297            $cond->set_options( $HyperEstraier::Condition::SURE );
298            $cond->set_order( getSort('est', $param->{'sort'} ) );
299    
300            # get the result of search
301            my @res;
302            my ($result, $hits);
303    
304            if ($index_path) {
305                    $result = $db->search($cond, 0);
306                    $hits = $result->size;
307            } elsif ($index_node_url) {
308                    $result = $db->search($cond, 0);
309                    $hits = $result->doc_num;
310            } else {
311                    die "BUG: unimplemented";
312            }
313    
314            # for each document in result
315            for my $i ($offset .. ($offset + $on_page - 1)) {
316                    last if ($i >= $hits);
317    
318                    my $doc;
319                    if ($index_path) {
320                            my $id = $result->get($i);
321                            $doc = $db->get_doc($id, 0);
322                    } elsif ($index_node_url) {
323                            $doc = $result->get_doc($i);
324                    } else {
325                            die "BUG: unimplemented";
326                    }
327    
328                    my $row;
329                    foreach my $c (qw/fid hname sname backupnum filepath date type size/) {
330                            $row->{$c} = $doc->attr($c);
331                    }
332                    push @res, $row;
333            }
334    
335            return ($hits, \@res);
336    }
337    
338    sub getGzipName($$$)
339    {
340            my ($host, $share, $backupnum) = @_;
341            my $ret = $Conf{GzipSchema};
342            
343            $share =~ s/\//_/g;
344            $ret =~ s/\\h/$host/ge;
345            $ret =~ s/\\s/$share/ge;
346            $ret =~ s/\\n/$backupnum/ge;
347    
348            $ret =~ s/__+/_/g;
349    
350            return $ret;
351            
352    }
353    
354    sub get_tgz_size_by_name($) {
355            my $name = shift;
356    
357            my $tgz = $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.$name;
358    
359            my $size = -1;
360    
361            if (-f $tgz) {
362                    $size = (stat($tgz))[7];
363            } elsif (-d $tgz) {
364                    opendir(my $dir, $tgz) || die "can't opendir $tgz: $!";
365                    my @parts = grep { !/^\./ && -f "$tgz/$_" } readdir($dir);
366                    $size = 0;
367                    foreach my $part (@parts) {
368                            $size += (stat("$tgz/$part"))[7] || die "can't stat $tgz/$part: $!";
369                    }
370                    closedir $dir;
371            }
372    
373            return $size;
374    }
375    
376    sub getGzipSize($$)
377    {
378            my ($hostID, $backupNum) = @_;
379            my $sql;
380            my $dbh = get_dbh();
381            
382            $sql = q{
383                                    SELECT hosts.name  as host,
384                                               shares.name as share,
385                                               backups.num as backupnum
386                                    FROM hosts, backups, shares
387                                    WHERE shares.id=backups.shareid AND
388                                              hosts.id =backups.hostid AND
389                                              hosts.id=? AND
390                                              backups.num=?
391                            };
392            my $sth = $dbh->prepare($sql);
393            $sth->execute($hostID, $backupNum);
394    
395            my $row = $sth->fetchrow_hashref();
396    
397            return get_tgz_size_by_name(
398                    getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'})
399            );
400    }
401    
402    sub getBackupsNotBurned() {
403    
404            my $dbh = get_dbh();
405    
406            my $sql = q{
407                    SELECT
408                            backups.hostID AS hostID,
409                            hosts.name AS host,
410                            shares.name AS share,
411                            backups.num AS backupnum,
412                            backups.type AS type,
413                            backups.date AS date,
414                            backups.size AS size,
415                            backups.id AS id,
416                            backups.inc_size AS inc_size,
417                            backups.parts AS parts
418                    FROM backups
419                    INNER JOIN shares       ON backups.shareID=shares.ID
420                    INNER JOIN hosts        ON backups.hostID = hosts.ID
421                    LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
422                    WHERE backups.inc_size > 0 AND backups.inc_deleted is false AND archive_backup.backup_id IS NULL
423                    GROUP BY
424                            backups.hostID,
425                            hosts.name,
426                            shares.name,
427                            backups.num,
428                            backups.shareid,
429                            backups.id,
430                            backups.type,
431                            backups.date,
432                            backups.size,
433                            backups.inc_size,
434                            backups.parts
435                    ORDER BY backups.date
436            };
437            my $sth = $dbh->prepare( $sql );
438            my @ret;
439            $sth->execute();
440    
441            while ( my $row = $sth->fetchrow_hashref() ) {
442                    $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
443                    $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
444    
445                    # do some cluster calculation (approximate) and convert to kB
446                    $row->{'inc_size'} = int(($row->{'inc_size'} + 1023 ) / ( 2 * 1024 ) * 2);
447                    push @ret, $row;
448            }
449                
450        if ($addForm)          return @ret;      
451          {  }
452    
453    sub displayBackupsGrid() {
454    
455            my $retHTML .= q{
456                    <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
457            };
458    
459            $retHTML .= <<'EOF3';
460    <style type="text/css">
461    <!--
462    DIV#fixedBox {
463            position: absolute;
464            top: 50em;
465            left: -24%;
466            padding: 0.5em;
467            width: 20%;
468            background-color: #E0F0E0;
469            border: 1px solid #00C000;
470    }
471    
472    DIV#fixedBox, DIV#fixedBox INPUT, DIV#fixedBox TEXTAREA {
473            font-size: 10pt;
474    }
475    
476    FORM>DIV#fixedBox {
477            position: fixed !important;
478            left: 0.5em !important;
479            top: auto !important;
480            bottom: 1em !important;
481            width: 15% !important;
482    }
483    
484    DIV#fixedBox INPUT[type=text], DIV#fixedBox TEXTAREA {
485            border: 1px solid #00C000;
486    }
487    
488    DIV#fixedBox #note {
489            display: block;
490            width: 100%;
491    }
492    
493    DIV#fixedBox #submitBurner {
494            display: block;
495            width: 100%;
496            margin-top: 0.5em;
497            cursor: pointer;
498    }
499    
500    * HTML {
501            overflow-y: hidden;
502    }
503    
504    * HTML BODY {
505            overflow-y: auto;
506            height: 100%;
507            font-size: 100%;
508    }
509    
510    * HTML DIV#fixedBox {
511            position: absolute;
512    }
513    
514    #mContainer, #gradient, #mask, #progressIndicator {
515            display: block;
516            width: 100%;
517            font-size: 10pt;
518            font-weight: bold;
519            text-align: center;
520            vertical-align: middle;
521            padding: 1px;
522    }
523    
524    #gradient, #mask, #progressIndicator {
525            left: 0;
526            border-width: 1px;
527            border-style: solid;
528            border-color: #000000;
529            color: #404040;
530            margin: 0.4em;
531            position: absolute;
532            margin-left: -1px;
533            margin-top: -1px;
534            margin-bottom: -1px;
535            overflow: hidden;
536    }
537    
538    #mContainer {
539            display: block;
540            position: relative;
541            padding: 0px;
542            margin-top: 0.4em;
543            margin-bottom: 0.5em;
544    }
545    
546    #gradient {
547            z-index: 1;
548            background-color: #FFFF00;
549    }
550    
551    #mask {
552            z-index: 2;
553            background-color: #FFFFFF;
554    }
555    
556    #progressIndicator {
557            z-index: 3;
558            background-color: transparent;
559    }
560    
561              $retHTML .= <<EOF3;  #parts {
562  <script language="javascript" type="text/javascript">          padding: 0.4em;
563            display: none;
564            width: 100%;
565            font-size: 80%;
566            color: #ff0000;
567            text-align: center;
568    }
569    -->
570    </style>
571    <script type="text/javascript">
572  <!--  <!--
573    
574      function checkAll(location)  var debug_div = null;
575      {  EOF3
576        for (var i=0;i<document.forma.elements.length;i++)  
577        {          # take maximum archive size from configuration
578          var e = document.forma.elements[i];          $retHTML .= 'var media_size = '. $Conf{MaxArchiveSize} .';';
579          if ((e.checked || !e.checked) && e.name != \'all\') {  
580              if (eval("document.forma."+location+".checked")) {          $retHTML .= <<'EOF3';
581                  e.checked = true;  
582              } else {  function debug(msg) {
583                  e.checked = false;          return; // Disable debugging
584              }  
585          }          if (! debug_div) debug_div = document.getElementById('debug');
586        }  
587      }          // this will create debug div if it doesn't exist.
588  //-->          if (! debug_div) {
589  </script>                        debug_div = document.createElement('div');
590                    if (document.body) document.body.appendChild(debug_div);
591                    else debug_div = null;
592            }
593            if (debug_div) {
594                    debug_div.appendChild(document.createTextNode(msg));
595                    debug_div.appendChild(document.createElement("br"));
596            }
597    }
598    
599    
600    var element_id_cache = Array();
601    
602    function element_id(name,element) {
603            if (! element_id_cache[name]) {
604                    element_id_cache[name] = self.document.getElementById(name);
605            }
606            return element_id_cache[name];
607    }
608    
609    function checkAll(location) {
610            var f = element_id('forma') || null;
611            if (!f) return false;
612    
613            var len = f.elements.length;
614            var check_all = element_id('allFiles');
615            var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
616    
617            for (var i = 0; i < len; i++) {
618                    var e = f.elements[i];
619                    if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
620                            if (check_all.checked) {
621                                    if (e.checked) continue;
622                                    var el = element_id("fss" + e.name.substr(3));
623                                    var size = parseInt(el.value) || 0;
624                                    debug('suma: '+suma+' size: '+size);
625                                    if ((suma + size) < media_size) {
626                                            suma += size;
627                                            e.checked = true;
628                                    } else {
629                                            break;
630                                    }
631                            } else {
632                                    e.checked = false;
633                            }
634                    }
635            }
636            update_sum(suma);
637    }
638    
639    function update_sum(suma, suma_disp) {
640            if (! suma_disp) suma_disp = suma;
641            element_id('forma').elements['totalsize'].value = suma_disp;
642            pbar_set(suma, media_size);
643            debug('total size: ' + suma);
644    }
645    
646    function sumiraj(e) {
647            var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
648            var len = element_id('forma').elements.length;
649            if (e) {
650                    var size = parseInt( element_id("fss" + e.name.substr(3)).value);
651                    if (e.checked) {
652                            suma += size;
653                    } else {
654                            suma -= size;
655                    }
656    
657                    var parts = parseInt( element_id("prt" + e.name.substr(3)).value);
658                    if (suma > media_size && suma == size && parts > 1) {
659                            element_id("parts").innerHTML = "This will take "+parts+" mediums!";
660                            element_id("parts").style.display = 'block';
661                            update_sum(media_size, suma);
662                            suma = media_size;
663                            return suma;
664                    } else {
665                            element_id("parts").style.display = 'none';
666                    }
667    
668                    if (suma < 0) suma = 0;
669            } else {
670                    suma = 0;
671                    for (var i = 0; i < len; i++) {
672                            var e = element_id('forma').elements[i];
673                            if (e.name != 'all' && e.checked && e.name.substr(0,3) == 'fcb') {
674                                    var el = element_id("fss" + e.name.substr(3));
675                                    if (el && el.value) suma += parseInt(el.value) || 0;
676                            }
677                    }
678            }
679            update_sum(suma);
680            return suma;
681    }
682    
683    /* progress bar */
684    
685    var _pbar_width = null;
686    var _pbar_warn = 10;    // change color in last 10%
687    
688    function pbar_reset() {
689            element_id("mask").style.left = "0px";
690            _pbar_width = element_id("mContainer").offsetWidth - 2;
691            element_id("mask").style.width = _pbar_width + "px";
692            element_id("mask").style.display = "block";
693            element_id("progressIndicator").style.zIndex  = 10;
694            element_id("progressIndicator").innerHTML = "0";
695    }
696    
697    function dec2hex(d) {
698            var hch = '0123456789ABCDEF';
699            var a = d % 16;
700            var q = (d - a) / 16;
701            return hch.charAt(q) + hch.charAt(a);
702    }
703    
704    function pbar_set(amount, max) {
705            debug('pbar_set('+amount+', '+max+')');
706    
707            if (_pbar_width == null) {
708                    var _mc = element_id("mContainer");
709                    if (_pbar_width == null) _pbar_width = parseInt(_mc.offsetWidth ? (_mc.offsetWidth - 2) : 0) || null;
710                    if (_pbar_width == null) _pbar_width = parseInt(_mc.clientWidth ? (_mc.clientWidth + 2) : 0) || null;
711                    if (_pbar_width == null) _pbar_width = 0;
712            }
713    
714            var pcnt = Math.floor(amount * 100 / max);
715            var p90 = 100 - _pbar_warn;
716            var pcol = pcnt - p90;
717            if (Math.round(pcnt) <= 100) {
718                    if (pcol < 0) pcol = 0;
719                    var e = element_id("submitBurner");
720                    debug('enable_button');
721                    e.disabled = false;
722                    var a = e.getAttributeNode('disabled') || null;
723                    if (a) e.removeAttributeNode(a);
724            } else {
725                    debug('disable button');
726                    pcol = _pbar_warn;
727                    var e = element_id("submitBurner");
728                    if (!e.disabled) e.disabled = true;
729            }
730            var col_g = Math.floor((_pbar_warn - pcol) * 255 / _pbar_warn);
731            var col = '#FF' + dec2hex(col_g) + '00';
732    
733            //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col);
734            element_id("gradient").style.backgroundColor = col;
735    
736            element_id("progressIndicator").innerHTML = pcnt + '%';
737            //element_id("progressIndicator").innerHTML = amount;
738    
739            element_id("mask").style.clip = 'rect(' + Array(
740                    '0px',
741                    element_id("mask").offsetWidth + 'px',
742                    element_id("mask").offsetHeight + 'px',
743                    Math.round(_pbar_width * amount / max) + 'px'
744            ).join(' ') + ')';
745    }
746    
747    if (!self.body) self.body = new Object();
748    self.onload = self.document.onload = self.body.onload = function() {
749            //pbar_reset();
750            sumiraj();
751    };
752    
753    // -->
754    </script>
755    <div id="fixedBox">
756    
757    Size: <input type="text" name="totalsize" size="7" readonly="readonly" style="text-align:right;" value="0" /> kB
758    
759    <div id="mContainer">
760            <div id="gradient">&nbsp;</div>
761            <div id="mask">&nbsp;</div>
762            <div id="progressIndicator">0%</div>
763    </div>
764    <br/>
765    
766    <div id="parts">&nbsp;</div>
767    
768    Note:
769    <textarea name="note" cols="10" rows="5" id="note"></textarea>
770    
771    <input type="submit" id="submitBurner" value="Burn selected" name="submitBurner" />
772    
773    </div>
774    <!--
775    <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
776    no debug output yet
777    </div>
778    -->
779  EOF3  EOF3
780                $retHTML .= q{<form name="forma" method="POST" action="}."$MyURL"."?action=burn\"";          $retHTML .= q{
781                $retHTML.= q{<input type="hidden" value="burn" name="action">};                          <input type="hidden" value="burn" name="action">
782                $retHTML .= q{<input type="hidden" value="results" name="search_results">};                          <input type="hidden" value="results" name="search_results">
783          }                          <table style="fview" border="0" cellspacing="0" cellpadding="2">
784        $retHTML .= "<table style=\"fview\">";                          <tr class="tableheader">
785        $retHTML .= "<tr> ";                          <td class="tableheader">
786        if ($addForm)                                  <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
787          {                          </td>
788              $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";                          <td align="center">Share</td>
789          }                          <td align="center">Backup no</td>
790        $retHTML .=  "<td class=\"tableheader\">Host</td> <td class=\"tableheader\">Backup no</td> <td class=\"tableheader\">Type</td> <td class=\"tableheader\">date</td></tr>";                          <td align="center">Type</td>
791        my @backups = getBackupsNotBurned();                          <td align="center">date</td>
792        my $backup;                          <td align="center">age/days</td>
793                            <td align="center">size/MB</td>
794        if ($addForm)                          <td align="center">gzip size/kB</td>
795          {                          </tr>
796              $retHTML .= "<tr>";  
797              $retHTML .= "<td colspan=7 style=\"tableheader\">";          };
798              $retHTML .= "<input type=\"submit\" value=\"Burn selected backups on medium\" name=\"submitBurner\">";  
799              $retHTML .= "</td>";          my @color = (' bgcolor="#e0e0e0"', '');
800              $retHTML .= "</tr>";  
801                        my $i = 0;
802          }          my $host = '';
803        foreach $backup(@backups)  
804          {          foreach my $backup ( getBackupsNotBurned() ) {
805              my $ftype = "";  
806                                if ($host ne $backup->{'host'}) {
807              $retHTML .= "<tr>";                          $i++;
808              if ($addForm)                          $host = $backup->{'host'};
809                {                  }
810                    $retHTML .= "<td class=\"fview\"> <input type=\"checkbox\" name=\"fcb"                  my $ftype = "";
811                      .$backup->{'hostid'}."_".$backup->{'backupno'}  
812                    ."\" value=\"".$backup->{'hostid'}."_".$backup->{'backupno'}."\"> </td>";                  my $checkbox_key = $backup->{'hostid'}. '_' .$backup->{'backupnum'} . '_' . $backup->{'id'};
813                }      
814                                $retHTML .=
815              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'host'} . "</td>";                          '<tr' . $color[$i %2 ] . '>
816              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'backupno'} . "</td>";                          <td class="fview">';
817              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'type'} . "</td>";  
818              $retHTML .= "<td class=\"fviewborder\">" . $backup->{'date'} . "<td>";                  if (($backup->{'inc_size'} || 0) > 0) {
819              $retHTML .= "</tr>";                          $retHTML .= '
820          }                          <input type="checkbox" name="fcb' . $checkbox_key . '" value="' . $checkbox_key . '" onClick="sumiraj(this);">';
821        $retHTML .= "</table>";                  }
822        if ($addForm)  
823         {                  $retHTML .=
824             $retHTML .= "</form>";                          '</td>' .
825         }                          '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
826                            '<td align="center">' . $backup->{'backupnum'} . '</td>' .
827                            '<td align="center">' . $backup->{'type'} . '</td>' .
828                            '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
829                            '<td align="center">' . $backup->{'age'} . '</td>' .
830                            '<td align="right">' . $backup->{'size'} . '</td>' .
831                            '<td align="right">' . $backup->{'inc_size'} .
832                            '<input type="hidden" id="fss'.$checkbox_key .'" value="'. $backup->{'inc_size'} .'"></td>' .
833                            '<input type="hidden" id="prt'.$checkbox_key .'" value="'. $backup->{'parts'} .'"></td>' .
834    
835                            "</tr>\n";
836            }
837    
838            $retHTML .= "</table>";
839            $retHTML .= "</form>";
840                
841        return $retHTML;          return $retHTML;
842      }      
843      
844    }        sub displayGrid($) {
845            my ($param) = @_;
846    
847            my $offset = $param->{'offset'};
848            my $hilite = $param->{'search_filename'};
849    
 sub displayGrid($$$$) {  
         my ($where, $addForm, $offset, $hilite) = @_;  
850          my $retHTML = "";          my $retHTML = "";
851    
852          if ($addForm) {          my $start_t = time();
853                  $retHTML .= qq{<form name="forma" method="POST" action="}.$MyURL.qq{?action=search">};  
854                  $retHTML.= qq{<input type="hidden" value="search" name="action">};          my ($results, $files);
855                  $retHTML .= qq{<input type="hidden" value="results" name="search_results">};          if ($param->{'use_hest'} && length($hilite) > 0) {
856                    ($results, $files) = getFilesHyperEstraier($param);
857            } else {
858                    ($results, $files) = getFiles($param);
859          }          }
860    
861            my $dur_t = time() - $start_t;
862            my $dur = sprintf("%0.4fs", $dur_t);
863    
864            my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
865    
866            if ($results <= 0) {
867                    $retHTML .= qq{
868                            <p style="color: red;">No results found...</p>
869                    };
870                    return $retHTML;
871            } else {
872                    # DEBUG
873                    #use Data::Dumper;
874                    #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
875            }
876    
877    
878            $retHTML .= qq{
879            <div>
880            Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
881            </div>
882            <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
883                    <tr class="fviewheader">
884                    <td></td>
885            };
886    
887            my ($sort_what, $sort_dir) = split(/_/,$param->{'sort'},2);
888    
889            sub sort_header($$$) {
890                    my ($param, $display, $name) = @_;
891    
892                    my $html = '<td align="center"';
893                    if (lc($sort_what) eq lc($name)) {
894                            my $dir = lc($sort_dir);
895                            $dir =~ tr/ad/da/;
896                            $param->{'sort'} = $name . '_' . $dir;
897                            $html .= ' style="border: 1px solid #808080;"';
898                    } else {
899                            $param->{'sort'} = $name . '_a';
900                    }
901                    $html .= '<a href="' . page_uri($param) . '">' . $display . '</a></td>';
902                    return $html;
903            }
904    
905            $retHTML .=
906                    sort_header($param, 'Share', 'share') .
907                    sort_header($param, 'Type and Name', 'path') .
908                    sort_header($param, '#', 'num') .
909                    sort_header($param, 'Size', 'size') .
910                    sort_header($param, 'Date', 'date');
911    
912          $retHTML .= qq{          $retHTML .= qq{
913          <table style="fview" width="100%">                  <td align="center">Media</td>
                 <tr>  
                 <td class="tableheader">Host</td>  
                 <td class="tableheader">Type</td>  
                 <td class="tableheader">Name</td>  
                 <td class="tableheader">backup no.</td>  
                 <td class="tableheader">size</td>  
                 <td class="tableheader">date</td>  
                 <td class="tableheader">Media</td>  
914                  </tr>                  </tr>
915          };          };
916          my @files = getFiles($where, $offset);  
917          my $file;          my $file;
918    
919          sub hilite_html($$) {          sub hilite_html($$) {
# Line 350  sub displayGrid($$$$) { Line 922  sub displayGrid($$$$) {
922                  return $html;                  return $html;
923          }          }
924    
925          foreach $file (@files) {          sub restore_link($$$$$$) {
926                  my $ftype = "file";                  my $type = shift;
927                  $ftype = "dir" if ($file->{'type'} == BPC_FTYPE_DIR);                  my $action = 'RestoreFile';
928                    $action = 'browse' if (lc($type) eq 'dir');
929                  $retHTML .= "<tr>";                  return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
930            }
931                  foreach my $v ((  
932                          $file->{'hname'},          my $sth_archived;
933                          $ftype,          my %archived_cache;
934                          hilite_html( $file->{'fpath'}, $hilite ),  
935                          $file->{'backupno'},          sub check_archived($$$) {
936                          $file->{'size'},                  my ($host, $share, $num) = @_;
937                          $file->{'date'},  
938                          $file->{'dvd'}                  if (my $html = $archived_cache{"$host $share $num"}) {
939                  )) {                          return $html;
940                          $retHTML .= qq{<td class="fviewborder">$v</td>};                  }
941    
942                    $sth_archived ||= $dbh->prepare(qq{
943                            select
944                                    dvd_nr, note,
945                                    count(archive_burned.copy) as copies
946                            from archive
947                            inner join archive_burned on archive_burned.archive_id = archive.id
948                            inner join archive_backup on archive.id = archive_backup.archive_id
949                            inner join backups on backups.id = archive_backup.backup_id
950                            inner join hosts on hosts.id = backups.hostid
951                            inner join shares on shares.id = backups.shareid
952                            where hosts.name = ? and shares.name = ? and backups.num = ?
953                            group by dvd_nr, note
954                    });
955    
956                    my @mediums;
957    
958                    $sth_archived->execute($host, $share, $num);
959                    while (my $row = $sth_archived->fetchrow_hashref()) {
960                            push @mediums, '<abbr title="' .
961                                    $row->{'note'} .
962                                    ' [' . $row->{'copies'} . ']' .
963                                    '">' .$row->{'dvd_nr'} .
964                                    '</abbr>';
965                  }                  }
966    
967                    my $html = join(", ",@mediums);
968                    $archived_cache{"$host $share $num"} = $html;
969                    return $html;
970            }
971    
972            my $i = $offset * $on_page;
973    
974            foreach $file (@{ $files }) {
975                    $i++;
976    
977                    my $typeStr  = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
978                    $retHTML .= qq{<tr class="fviewborder">};
979    
980                    $retHTML .= qq{<td class="fviewborder">$i</td>};
981    
982                    $retHTML .=
983                            qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
984                            qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
985                            qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
986                            qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
987                            qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
988                            qq{<td class="fviewborder">} . check_archived( $file->{'hname'}, $file->{'sname'}, $file->{'backupnum'} ) . qq{</td>};
989    
990                  $retHTML .= "</tr>";                  $retHTML .= "</tr>";
991          }          }
992          $retHTML .= "</table>";          $retHTML .= "</table>";
993    
994          # skip pager          # all variables which has to be transfered
995          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/) {
996                    $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
997            }
998    
999          $retHTML .= "<INPUT TYPE=\"hidden\" VALUE=\"\" NAME=\"offset\">";          my $del = '';
1000          for (my $ii = 1; $ii <= $#files; $ii++) {          my $max_page = int( $results / $on_page );
1001                  $retHTML .= "<a href = \"#\" onclick=\"document.forma.offset.value=$ii;document.forma.submit();\">$ii</a>";          my $page = 0;
1002                  if ($ii < $#files) {  
1003                          $retHTML .= " | ";          sub page_uri($) {
1004                    my $param = shift || die "no param?";
1005    
1006                    my $uri = $MyURL;
1007                    my $del = '?';
1008                    foreach my $k (keys %{ $param }) {
1009                            if ($param->{$k}) {
1010                                    $uri .= $del . $k . '=' . ${EscURI( $param->{$k} )};
1011                                    $del = '&';
1012                            }
1013                  }                  }
1014                    return $uri;
1015          }          }
1016    
1017          $retHTML .= "</form>" if ($addForm);          sub page_link($$$) {
1018                          my ($param,$page,$display) = @_;
1019    
1020                    $param->{'offset'} = $page if (defined($page));
1021    
1022                    my $html = '<a href = "' . page_uri($param) . '">' . $display . '</a>';
1023            }
1024    
1025            $retHTML .= '<div style="text-align: center;">';
1026    
1027            if ($offset > 0) {
1028                    $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
1029            }
1030    
1031            while ($page <= $max_page) {
1032                    if ($page == $offset) {
1033                            $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
1034                    } else {
1035                            $retHTML .= $del . page_link($param, $page, $page + 1);
1036                    }
1037    
1038                    if ($page < $offset - $pager_pages && $page != 0) {
1039                            $retHTML .= " ... ";
1040                            $page = $offset - $pager_pages;
1041                            $del = '';
1042                    } elsif ($page > $offset + $pager_pages && $page != $max_page) {
1043                            $retHTML .= " ... ";
1044                            $page = $max_page;
1045                            $del = '';
1046                    } else {
1047                            $del = ' | ';
1048                            $page++;
1049                    }
1050            }
1051    
1052            if ($offset < $max_page) {
1053                    $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
1054            }
1055    
1056            $retHTML .= "</div>";
1057    
1058          return $retHTML;          return $retHTML;
1059  }  }
1060    

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

  ViewVC Help
Powered by ViewVC 1.1.26