/[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 24 by dpavlin, Mon Jul 11 16:48:33 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 getWhere($) {  sub epoch_to_iso {
51          my ($param)    = @_;          my $t = shift || return;
52          my @conditions;          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_iso_date($$) {          sub mk_epoch_date($$) {
61                  my ($name,$suffix) = @_;                  my ($name,$suffix) = @_;
62    
63                  my $yyyy = $param->{ $name . '_year_' . $suffix} || return;                  my $yyyy = $param->{ $name . '_year_' . $suffix} || return undef;
64                  my $mm .= $param->{ $name . '_month_' . $suffix} ||                  my $mm .= $param->{ $name . '_month_' . $suffix} ||
65                          ( $suffix eq 'from' ? 1 : 12);                          ( $suffix eq 'from' ? 1 : 12);
66                  my $dd .= $param->{ $name . '_day_' . $suffix} ||                  my $dd .= $param->{ $name . '_day_' . $suffix} ||
67                          ( $suffix eq 'from' ? 1 : 31);                          ( $suffix eq 'from' ? 1 : 31);
                 return sprintf("%04d-%02d-%02d", $yyyy, $mm, $dd);  
         }  
68    
69          my $backup_from = mk_iso_date('search_backup', 'from');                  $yyyy =~ s/\D//g;
70          push @conditions, qq{ date(backups.date, 'unixepoch','localtime') >= '$backup_from' } if ($backup_from);                  $mm =~ s/\D//g;
71          my $backup_to = mk_iso_date('search_backup', 'to');                  $dd =~ s/\D//g;
72          push @conditions, qq{ date(backups.date, 'unixepoch','localtime') <= '$backup_to' } if ($backup_to);  
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 $files_from = mk_iso_date('search', 'from');                  my $dt = new DateTime(
81          push @conditions, qq{ date(files.date, 'unixepoch','localtime') >= '$files_from' } if ($files_from);                          year => $yyyy,
82          my $files_to = mk_iso_date('search', 'to');                          month => $mm,
83          push @conditions, qq{ date(files.date, 'unixepoch','localtime') <= '$files_to' } if ($files_to);                          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          print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:",join(" | ",@conditions);          return @ret;
       
         push( @conditions, ' backups.hostID = ' . $param->{'search_host'} ) if ($param->{'search_host'});  
100    
101          push (@conditions, " files.name LIKE '".$param->{'search_filename'}."%'") if ($param->{'search_filename'});  }
102    
103          return (  
104                  join(" and ", @conditions),  sub getWhere($) {
105                  $files_from, $files_to,          my $param = shift || return;
106                  $backup_from, $backup_to  
107          );          my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
108    
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            push @conditions, qq{ files.date <= $files_to } if ($files_to);
114    
115            print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:" . join(" and ",@conditions);
116    
117            push( @conditions, ' files.shareid = ' . $param->{'search_share'} ) if ($param->{'search_share'});
118            push (@conditions, " upper(files.path) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});
119    
120            return join(" and ", @conditions);
121  }  }
122    
123    
124  sub getFiles($$)  sub getFiles($) {
125    {          my ($param) = @_;
126        my ($where, $offset) = @_;  
127                  my $offset = $param->{'offset'} || 0;
128                  $offset *= $on_page;
129        my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",  
130          "", "", { RaiseError => 1, AutoCommit => 1 } );          my $dbh = get_dbh();
131        my $sql =            
132          q{            my $sql_cols = qq{
133                  SELECT  files.id                        AS fid,                  files.id                        AS fid,
134                          hosts.name                      AS hname,                  hosts.name                      AS hname,
135                          shares.name                     AS sname,                  shares.name                     AS sname,
136                          shares.share                    AS sharename,                  files.backupnum                 AS backupnum,
137                          files.backupNum                 AS backupNum,                  files.path                      AS filepath,
138                          files.name                      AS filename,                  files.date                      AS date,
139                          files.path                      AS filepath,                  files.type                      AS type,
140                          shares.share||files.fullpath    AS networkPath,                  files.size                      AS size
141                          date(files.date, 'unixepoch', 'localtime') AS date,          };
142                          files.type                      AS filetype,  
143                          files.size                      AS size,          my $sql_from = qq{
                         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                          INNER JOIN backups      ON backups.num = files.backupNum and backups.hostID = hosts.ID                          INNER JOIN backups      ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = files.shareID
148                          LEFT  JOIN dvds         ON dvds.ID = files.dvdid          };
           };  
   
       if (defined($where) && $where ne "")  
         {  
             $sql .= " WHERE ". $where;        
         }  
149    
150        $sql .=          my $sql_where;
151          q{                    my $where = getWhere($param);
152              ORDER BY files.id          $sql_where = " WHERE ". $where if ($where);
153                LIMIT 100  
154                OFFSET ? * 100 + 1          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        my $st = $dbh->prepare(  
163            $sql          my $sth = $dbh->prepare($sql_count);
164            );              $sth->execute();
165        if (!defined($offset) && $offset ne "")          my ($results) = $sth->fetchrow_array();
166        {  
167          $st->bind_param(1, $offset);          $sth = $dbh->prepare($sql_results);
168        }          $sth->execute( $offset );
169        else  
170        {          if ($sth->rows != $results) {
171          $st->bind_param(1,0);                  my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
172        }                  $bug =~ s/\s+/ /gs;
173        $st->execute;                  print STDERR "$bug\n";
         
       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'}  
                        }  
             );  
                                   
174          }          }
175    
176            my @ret;
177                
178        $st->finish();          while (my $row = $sth->fetchrow_hashref()) {
179        $dbh->disconnect();                  push @ret, $row;
       return @ret;  
   }  
   
 sub getBackupsNotBurned()  
   {  
       my $dbh = DBI->connect( "dbi:SQLite:dbname=${TopDir}/$Conf{SearchDB}",  
         "", "", { RaiseError => 1, AutoCommit => 1 } );        
       my $sql = q{  
           SELECT  
             hosts.ID         AS hostID,  
             hosts.name       AS host,  
             backups.num      AS backupno,  
             backups.type     AS type,  
             backups.date     AS date  
           FROM backups, shares, files, hosts  
           WHERE  
             backups.num    = files.backupNum  AND  
             shares.ID      = files.shareID    AND            
             backups.hostID = shares.hostID    AND  
             hosts.ID       = backups.hostID   AND  
             files.dvdid    IS NULL  
           GROUP BY  
             backups.hostID, backups.num  
       };  
       my $st = $dbh -> prepare( $sql );  
       my @ret = ();  
       $st -> execute();  
   
       while ( my $tmp = $st -> fetchrow_hashref() )  
         {            
             push(@ret, {  
                          'host'     => $tmp->{'host'},  
                          'hostid'   => $tmp->{'hostID'},  
                          'backupno' => $tmp->{'backupno'},  
                          'type'     => $tmp->{'type'},  
                          'date'     => $tmp->{'date'}  
                        }  
             );  
180          }          }
181              
182        return @ret;                $sth->finish();
183    }          return ($results, \@ret);
184    }
185    
186    sub getHyperEstraier_url($) {
187            my ($use_hest) = @_;
188    
189            return unless $use_hest;
190    
191            use HyperEstraier;
192            my ($index_path, $index_node_url);
193    
194            if ($use_hest =~ m#^http://#) {
195                    $index_node_url = $use_hest;
196            } else {
197                    $index_path = $TopDir . '/' . $index_path;
198                    $index_path =~ s#//#/#g;
199            }
200            return ($index_path, $index_node_url);
201    }
202    
203    sub getFilesHyperEstraier($) {
204            my ($param) = @_;
205    
206            my $offset = $param->{'offset'} || 0;
207            $offset *= $on_page;
208    
209  sub displayBackupsGrid()          die "no index_path?" unless ($hest_index_path);
210    {  
211        my $retHTML = "";          use HyperEstraier;
212        my $addForm = 1;  
213            my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path);
214    
215            # open the database
216            my $db;
217            if ($index_path) {
218                    $db = HyperEstraier::Database->new();
219                    $db->open($index_path, $HyperEstraier::ESTDBREADER);
220            } elsif ($index_node_url) {
221                    $db ||= HyperEstraier::Node->new($index_node_url);
222                    $db->set_auth('admin', 'admin');
223            } else {
224                    die "BUG: unimplemented";
225            }
226    
227            # create a search condition object
228            my $cond = HyperEstraier::Condition->new();
229    
230            my $q = $param->{'search_filename'};
231            my $shareid = $param->{'search_share'};
232    
233            if (length($q) > 0) {
234                    # exact match
235                    $cond->add_attr("filepath ISTRINC $q");
236    
237                    $q =~ s/(.)/$1 /g;
238                    # set the search phrase to the search condition object
239                    $cond->set_phrase($q);
240            }
241    
242            my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
243    
244            $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
245            $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);
246    
247            $cond->add_attr("date NUMGE $files_from") if ($files_from);
248            $cond->add_attr("date NUMLE $files_to") if ($files_to);
249    
250            $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
251    
252    #       $cond->set_max( $offset + $on_page );
253            $cond->set_options( $HyperEstraier::Condition::SURE );
254            $cond->set_order( 'date NUMA' );
255    
256            # get the result of search
257            my @res;
258            my ($result, $hits);
259    
260            if ($index_path) {
261                    $result = $db->search($cond, 0);
262                    $hits = $result->size;
263            } elsif ($index_node_url) {
264                    $result = $db->search($cond, 0);
265                    $hits = $result->doc_num;
266            } else {
267                    die "BUG: unimplemented";
268            }
269    
270            # for each document in result
271            for my $i ($offset .. ($offset + $on_page - 1)) {
272                    last if ($i >= $hits);
273    
274                    my $doc;
275                    if ($index_path) {
276                            my $id = $result->get($i);
277                            $doc = $db->get_doc($id, 0);
278                    } elsif ($index_node_url) {
279                            $doc = $result->get_doc($i);
280                    } else {
281                            die "BUG: unimplemented";
282                    }
283    
284                    my $row;
285                    foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {
286                            $row->{$c} = $doc->attr($c);
287                    }
288                    push @res, $row;
289            }
290    
291            return ($hits, \@res);
292    }
293    
294    sub getGzipName($$$)
295    {
296            my ($host, $share, $backupnum) = @_;
297            my $ret = $Conf{GzipSchema};
298            
299            $share =~ s/\//_/g;
300            $ret =~ s/\\h/$host/ge;
301            $ret =~ s/\\s/$share/ge;
302            $ret =~ s/\\n/$backupnum/ge;
303    
304            $ret =~ s/__+/_/g;
305    
306            return $ret;
307            
308    }
309    
310    sub get_tgz_size_by_name($) {
311            my $name = shift;
312    
313            my $tgz = $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.$name;
314    
315            my $size = -1;
316    
317            if (-f $tgz) {
318                    $size = (stat($tgz))[7];
319            } elsif (-d $tgz) {
320                    opendir(my $dir, $tgz) || die "can't opendir $tgz: $!";
321                    my @parts = grep { !/^\./ && -f "$tgz/$_" } readdir($dir);
322                    $size = 0;
323                    foreach my $part (@parts) {
324                            $size += (stat("$tgz/$part"))[7] || die "can't stat $tgz/$part: $!";
325                    }
326                    closedir $dir;
327            }
328    
329            return $size;
330    }
331    
332    sub getGzipSize($$)
333    {
334            my ($hostID, $backupNum) = @_;
335            my $sql;
336            my $dbh = get_dbh();
337            
338            $sql = q{
339                                    SELECT hosts.name  as host,
340                                               shares.name as share,
341                                               backups.num as backupnum
342                                    FROM hosts, backups, shares
343                                    WHERE shares.id=backups.shareid AND
344                                              hosts.id =backups.hostid AND
345                                              hosts.id=? AND
346                                              backups.num=?
347                            };
348            my $sth = $dbh->prepare($sql);
349            $sth->execute($hostID, $backupNum);
350    
351            my $row = $sth->fetchrow_hashref();
352    
353            return get_tgz_size_by_name(
354                    getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'})
355            );
356    }
357    
358    sub getBackupsNotBurned() {
359    
360            my $dbh = get_dbh();
361    
362            my $sql = q{
363                    SELECT
364                            backups.hostID AS hostID,
365                            hosts.name AS host,
366                            shares.name AS share,
367                            backups.num AS backupnum,
368                            backups.type AS type,
369                            backups.date AS date,
370                            backups.size AS size,
371                            backups.id AS id,
372                            backups.inc_size AS inc_size
373                    FROM backups
374                    INNER JOIN shares       ON backups.shareID=shares.ID
375                    INNER JOIN hosts        ON backups.hostID = hosts.ID
376                    LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
377                    WHERE backups.inc_size > 0 AND backups.inc_deleted is false AND archive_backup.backup_id IS NULL
378                    GROUP BY
379                            backups.hostID,
380                            hosts.name,
381                            shares.name,
382                            backups.num,
383                            backups.shareid,
384                            backups.id,
385                            backups.type,
386                            backups.date,
387                            backups.size,
388                            backups.inc_size
389                    ORDER BY backups.date
390            };
391            my $sth = $dbh->prepare( $sql );
392            my @ret;
393            $sth->execute();
394    
395            while ( my $row = $sth->fetchrow_hashref() ) {
396                    $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
397                    $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
398    
399                    # do some cluster calculation (approximate) and convert to kB
400                    $row->{'inc_size'} = int(($row->{'inc_size'} + 1023 ) / ( 2 * 1024 ) * 2);
401                    push @ret, $row;
402            }
403                
404        if ($addForm)          return @ret;      
405          {  }
406    
407    sub displayBackupsGrid() {
408    
409            my $retHTML .= q{
410                    <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
411            };
412    
413            $retHTML .= <<'EOF3';
414    <style type="text/css">
415    <!--
416    DIV#fixedBox {
417            position: absolute;
418            top: 50em;
419            left: -24%;
420            padding: 0.5em;
421            width: 20%;
422            background-color: #E0F0E0;
423            border: 1px solid #00C000;
424    }
425    
426    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              $retHTML .= <<EOF3;  #progressIndicator {
511  <script language="javascript" type="text/javascript">          z-index: 3;
512            background-color: transparent;
513    }
514    -->
515    </style>
516    <script type="text/javascript">
517  <!--  <!--
518    
519      function checkAll(location)  var debug_div = null;
     {  
       for (var i=0;i<document.forma.elements.length;i++)  
       {  
         var e = document.forma.elements[i];  
         if ((e.checked || !e.checked) && e.name != \'all\') {  
             if (eval("document.forma."+location+".checked")) {  
                 e.checked = true;  
             } else {  
                 e.checked = false;  
             }  
         }  
       }  
     }  
 //-->  
 </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">Name</td>          <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
811                  <td class="tableheader">Type</td>                  <tr class="fviewheader">
812                  <td class="tableheader">#</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 297  sub displayGrid($$$$) { Line 827  sub displayGrid($$$$) {
827                  return $html;                  return $html;
828          }          }
829    
830          foreach $file (@files) {          sub restore_link($$$$$$) {
831                    my $type = shift;
832                    my $action = 'RestoreFile';
833                    $action = 'browse' if (lc($type) eq 'dir');
834                    return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
835            }
836    
837            my $i = $offset * $on_page;
838    
839            foreach $file (@{ $files }) {
840                    $i++;
841    
842                  my $typeStr  = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});                  my $typeStr  = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
843                  $retHTML .= "<tr>";                  $retHTML .= qq{<tr class="fviewborder">};
844    
845                  foreach my $v ((                  $retHTML .= qq{<td class="fviewborder">$i</td>};
846                          $file->{'hname'},  
847                          qq{<img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" align="center">&nbsp;} . hilite_html( $file->{'fpath'}, $hilite ),                  $retHTML .=
848                          $typeStr,                          qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
849                          $file->{'backupno'},                          qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
850                          $file->{'size'},                          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                          $file->{'date'},                          qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
852                          $file->{'dvd'}                          qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
853                  )) {                          qq{<td class="fviewborder">} . '?' . qq{</td>};
                         $retHTML .= qq{<td class="fviewborder">$v</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.24  
changed lines
  Added in v.194

  ViewVC Help
Powered by ViewVC 1.1.26