/[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 109 by dpavlin, Thu Sep 1 18:30:51 2005 UTC revision 378 by iklaric, Tue May 8 12:15:26 2007 UTC
# Line 8  use DBI; Line 8  use DBI;
8  use DateTime;  use DateTime;
9  use vars qw(%In $MyURL);  use vars qw(%In $MyURL);
10  use Time::HiRes qw/time/;  use Time::HiRes qw/time/;
11    use XML::Writer;
12    use IO::File;
13    
14  my $on_page = 100;  my $on_page = 100;
15  my $pager_pages = 10;  my $pager_pages = 10;
# Line 15  my $pager_pages = 10; Line 17  my $pager_pages = 10;
17  my $dsn = $Conf{SearchDSN};  my $dsn = $Conf{SearchDSN};
18  my $db_user = $Conf{SearchUser} || '';  my $db_user = $Conf{SearchUser} || '';
19    
20  my $index_path = $Conf{HyperEstraierIndex};  my $hest_node_url = $Conf{HyperEstraierIndex};
 if ($index_path) {  
         $index_path = $TopDir . '/' . $index_path;  
         $index_path =~ s#//#/#g;  
 }  
21    
22  my $dbh;  my $dbh;
23    my $Dir = $Conf{$InstallDir}."/data/log";
24    open(LOG, ">>", "$Dir/LOG")
25    select(LOG);
26    $|=1;
27    
28    
29  sub get_dbh {  sub get_dbh {
30          $dbh ||= DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );          $dbh ||= DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
# Line 72  sub dates_from_form($) { Line 75  sub dates_from_form($) {
75                  $mm =~ s/\D//g;                  $mm =~ s/\D//g;
76                  $dd =~ s/\D//g;                  $dd =~ s/\D//g;
77    
78                    my $h = my $m = my $s = 0;
79                    if ($suffix eq 'to') {
80                            $h = 23;
81                            $m = 59;
82                            $s = 59;
83                    }
84    
85                  my $dt = new DateTime(                  my $dt = new DateTime(
86                          year => $yyyy,                          year => $yyyy,
87                          month => $mm,                          month => $mm,
88                          day => $dd                          day => $dd,
89                            hour => $h,
90                            minute => $m,
91                            second => $s,
92                  );                  );
93                  print STDERR "mk_epoch_date($name,$suffix) [$yyyy-$mm-$dd] = " . $dt->ymd . " " . $dt->hms . "\n";                  print STDERR "mk_epoch_date($name,$suffix) [$yyyy-$mm-$dd] = " . $dt->ymd . " " . $dt->hms . "\n";
94                  return $dt->epoch || 'NULL';                  return $dt->epoch || 'NULL';
# Line 104  sub getWhere($) { Line 117  sub getWhere($) {
117          push @conditions, qq{ files.date >= $files_from } if ($files_from);          push @conditions, qq{ files.date >= $files_from } if ($files_from);
118          push @conditions, qq{ files.date <= $files_to } if ($files_to);          push @conditions, qq{ files.date <= $files_to } if ($files_to);
119    
120          print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:" . join(" | ",@conditions);          print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:" . join(" and ",@conditions);
121    
122          push( @conditions, ' files.shareid = ' . $param->{'search_share'} ) if ($param->{'search_share'});          push( @conditions, ' files.shareid = ' . $param->{'search_share'} ) if ($param->{'search_share'});
123          push (@conditions, " upper(files.path) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});          push (@conditions, " upper(files.path) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});
124    
125            if ( $param->{burned} ) {
126                    my $is_what = 'is null';
127                    $is_what = '= 1' if ($param->{burned} eq 'burned');
128                    push @conditions, "archive_burned.part $is_what";
129                    push @conditions, "archive_burned.copy $is_what";
130            }
131    
132          return join(" and ", @conditions);          return join(" and ", @conditions);
133  }  }
134    
135    my $sort_def = {
136            search => {
137                    default => 'date_a',
138                    sql => {
139                            share_d => 'shares.name DESC',
140                            share_a => 'shares.name ASC',
141                            path_d => 'files.path DESC',
142                            path_a => 'files.path ASC',
143                            num_d => 'files.backupnum DESC',
144                            num_a => 'files.backupnum ASC',
145                            size_d => 'files.size DESC',
146                            size_a => 'files.size ASC',
147                            date_d => 'files.date DESC',
148                            date_a => 'files.date ASC',
149                    },
150                    est => {
151                            share_d => 'sname STRD',
152                            share_a => 'sname STRA',
153                            path_d => 'filepath STRD',
154                            path_a => 'filepath STRA',
155                            num_d => 'backupnum NUMD',
156                            num_a => 'backupnum NUMA',
157                            size_d => 'size NUMD',
158                            size_a => 'size NUMA',
159                            date_d => 'date NUMD',
160                            date_a => 'date NUMA',
161                    }
162            }, burn => {
163                    default => 'date_a',
164                    sql => {
165                            share_d => 'host DESC, share DESC',
166                            share_a => 'host ASC, share ASC',
167                            num_d => 'backupnum DESC',
168                            num_a => 'backupnum ASC',
169                            date_d => 'date DESC',
170                            date_a => 'date ASC',
171                            age_d => 'age DESC',
172                            age_a => 'age ASC',
173                            size_d => 'size DESC',
174                            size_a => 'size ASC',
175                            incsize_d => 'inc_size DESC',
176                            incsize_a => 'inc_size ASC',
177                    }
178            }
179    };
180    
181    sub getSort($$$) {
182            my ($part,$type, $sort_order) = @_;
183    
184            die "unknown part: $part" unless ($sort_def->{$part});
185            die "unknown type: $type" unless ($sort_def->{$part}->{$type});
186    
187            $sort_order ||= $sort_def->{$part}->{'default'};
188    
189            if (my $ret = $sort_def->{$part}->{$type}->{$sort_order}) {
190                    return $ret;
191            } else {
192                    # fallback to default sort order
193                    return $sort_def->{$part}->{$type}->{ $sort_def->{$part}->{'default'} };
194            }
195    }
196    
197  sub getFiles($) {  sub getFiles($) {
198          my ($param) = @_;          my ($param) = @_;
# Line 143  sub getFiles($) { Line 224  sub getFiles($) {
224          my $where = getWhere($param);          my $where = getWhere($param);
225          $sql_where = " WHERE ". $where if ($where);          $sql_where = " WHERE ". $where if ($where);
226    
227            # do we have to add tables for burned media?
228            if ( $param->{burned} ) {
229                    $sql_from .= qq{
230                            LEFT OUTER JOIN archive_backup on archive_backup.backup_id = backups.id
231                            LEFT OUTER JOIN archive_burned on archive_burned.archive_id = archive_backup.archive_id
232                    };
233            }
234    
235            my $order = getSort('search', 'sql', $param->{'sort'});
236    
237          my $sql_order = qq{          my $sql_order = qq{
238                  ORDER BY files.date                  ORDER BY $order
239                  LIMIT $on_page                  LIMIT $on_page
240                  OFFSET ?                  OFFSET ?
241          };          };
# Line 175  sub getFiles($) { Line 266  sub getFiles($) {
266          return ($results, \@ret);          return ($results, \@ret);
267  }  }
268    
269    sub getHyperEstraier_url($) {
270            my ($use_hest) = @_;
271    
272            return unless $use_hest;
273    
274            use Search::Estraier 0.04;
275            die "direct access to Hyper Estraier datatase is no longer supported. Please use estmaster\n"
276                    unless ($use_hest =~ m#^http://#);
277    
278            return $use_hest;
279    }
280    
281  sub getFilesHyperEstraier($) {  sub getFilesHyperEstraier($) {
282          my ($param) = @_;          my ($param) = @_;
283    
284          my $offset = $param->{'offset'} || 0;          my $offset = $param->{'offset'} || 0;
285          $offset *= $on_page;          $offset *= $on_page;
286    
287          die "no index_path?" unless ($index_path);          die "no Hyper Estraier node URL?" unless ($hest_node_url);
   
         use HyperEstraier;  
288    
289          # open the database          # open the database
290          my $db = HyperEstraier::Database->new();          my $db;
291          $db->open($index_path, $HyperEstraier::ESTDBREADER);          if ($hest_node_url) {
292                    $db ||= Search::Estraier::Node->new($hest_node_url);
293                    $db->set_auth('admin', 'admin');
294            } else {
295                    die "BUG: unimplemented";
296            }
297    
298          # create a search condition object          # create a search condition object
299          my $cond = HyperEstraier::Condition->new();          my $cond = Search::Estraier::Condition->new();
300    
301          my $q = $param->{'search_filename'};          my $q = $param->{'search_filename'};
302          my $shareid = $param->{'search_share'};          my $shareid = $param->{'search_share'};
# Line 214  sub getFilesHyperEstraier($) { Line 320  sub getFilesHyperEstraier($) {
320    
321          $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);          $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
322    
323  #       $cond->set_max( $offset + $on_page );          $cond->set_max( $offset + $on_page );
324          $cond->set_options( $HyperEstraier::Condition::SURE );          $cond->set_options( 'SURE' );
325          $cond->set_order( 'date NUMA' );          $cond->set_order( getSort('search', 'est', $param->{'sort'} ) );
326    
327          # get the result of search          # get the result of search
         my $result = $db->search($cond, 0);  
   
328          my @res;          my @res;
329          my $hits = $result->size;          my ($result, $hits);
330    
331            if ($hest_node_url) {
332                    $result = $db->search($cond, 0);
333                    if ($result) {
334                            $hits = $result->hits;
335                    } else {
336                            $hits = 0;
337                            return ($hits,[]);
338                    }
339            } else {
340                    die "BUG: unimplemented";
341            }
342    
343          # for each document in result          # for each document in result
344          for my $i ($offset .. ($offset + $on_page - 1)) {          for my $i ($offset .. ($offset + $on_page - 1)) {
345                  last if ($i >= $hits);                  last if ($i >= $result->doc_num);
346    
347                  my $id = $result->get($i);                  my $doc;
348                  my $doc = $db->get_doc($id, 0);                  if ($hest_node_url) {
349                            $doc = $result->get_doc($i);
350                    } else {
351                            die "BUG: unimplemented";
352                    }
353    
354                  my $row;                  my $row;
355                  foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {                  foreach my $c (qw/fid hname sname backupnum filepath date type size/) {
356                          $row->{$c} = $doc->attr($c);                          $row->{$c} = $doc->attr($c);
357                  }                  }
358                  push @res, $row;                  push @res, $row;
# Line 250  sub getGzipName($$$) Line 370  sub getGzipName($$$)
370          $ret =~ s/\\h/$host/ge;          $ret =~ s/\\h/$host/ge;
371          $ret =~ s/\\s/$share/ge;          $ret =~ s/\\s/$share/ge;
372          $ret =~ s/\\n/$backupnum/ge;          $ret =~ s/\\n/$backupnum/ge;
373            
374            $ret =~ s/__+/_/g;
375    
376          return $ret;          return $ret;
377                    
378  }  }
379    
380  sub getBackupsNotBurned() {  sub get_tgz_size_by_name($) {
381            my $name = shift;
382    
383            my $tgz = $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.$name;
384            my $size = -1;
385    
386            if (-f "${tgz}.tar.gz") {
387                    print "stating ${tgz}.tar.gz...";
388                    $size = (stat("${tgz}.tar.gz"))[7];
389                    print "size: $size\n";
390            } elsif (-d $tgz) {
391                    print "$tgz is dir, stating files in it...\n";
392                    opendir(my $dir, $tgz) || die "can't opendir $tgz: $!";
393                    my @parts = grep { !/^\./ && !/md5/ && -f "$tgz/$_" } readdir($dir);
394                    $size = 0;
395                    foreach my $part (@parts) {
396                            my $currSize =  (stat("$tgz/$part"))[7];
397                            $size += (stat("$tgz/$part"))[7] || die "can't stat $tgz/$part: $!";
398                            print "\t$tgz/$part: $currSize\n";
399                    }
400                    print "\ttotal $size\n";
401    
402                    closedir $dir;
403            } else {
404                    return -1;
405            }
406    
407            return $size;
408    }
409    
410    sub getGzipSize($$)
411    {
412            my ($hostID, $backupNum) = @_;
413            my $sql;
414            my $dbh = get_dbh();
415            
416            $sql = q{
417                                    SELECT hosts.name  as host,
418                                               shares.name as share,
419                                               backups.num as backupnum
420                                    FROM hosts, backups, shares
421                                    WHERE shares.id=backups.shareid AND
422                                              hosts.id =backups.hostid AND
423                                              hosts.id=? AND
424                                              backups.num=?
425                            };
426            my $sth = $dbh->prepare($sql);
427            $sth->execute($hostID, $backupNum);
428    
429            my $row = $sth->fetchrow_hashref();
430    
431            return get_tgz_size_by_name(
432                    getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'})
433            );
434    }
435    
436    sub getVolumes($) {
437            my $id = shift;
438    
439            my $max_archive_size = $Conf{MaxArchiveSize} || die "no MaxArchiveSize";
440    
441            my $sth = $dbh->prepare(qq{
442                    select
443                            size
444                    from backup_parts
445                    where backup_id = ?
446                    order by part_nr asc
447            });
448    
449            $sth->execute($id);
450    
451            my $cumulative_size = 0;
452            my $volumes = 1;
453    
454            while(my ($size) = $sth->fetchrow_array) {
455                    if ($cumulative_size + $size > $max_archive_size) {
456                            $volumes++;
457                            $cumulative_size = $size;
458                    } else {
459                            $cumulative_size += $size;
460                    }
461            }
462    
463            return ($volumes,$cumulative_size);
464    }
465    
466    sub getBackupsNotBurned($) {
467    
468            my $param = shift;
469          my $dbh = get_dbh();          my $dbh = get_dbh();
470          my $sql = q{  
471          SELECT          my $order = getSort('burn', 'sql', $param->{'sort'});
472                  backups.hostID          AS hostid,  
473                  min(hosts.name)         AS host,  print STDERR "## sort=". ($param->{'sort'} || 'no sort param') . " burn sql order: $order\n";
474                  min(shares.name)        AS share,  
475                  backups.num             AS backupnum,          my $sql = qq{
476                  min(backups.type)       AS type,                  SELECT
477                  min(backups.date)       AS date,                          backups.hostID AS hostID,
478                  min(backups.size)       AS size                          hosts.name AS host,
479          FROM files                          shares.name AS share,
480                  INNER JOIN shares       ON files.shareID=shares.ID                          backups.num AS backupnum,
481                  INNER JOIN hosts        ON hosts.ID = shares.hostID                          backups.type AS type,
482                  INNER JOIN backups      ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = shares.ID                          backups.date AS date,
483          GROUP BY                          date_part('epoch',now()) - backups.date as age,
484                  backups.hostID, backups.num, backups.shareid                          backups.size AS size,
485          ORDER BY min(backups.date)                          backups.id AS id,
486                            backups.inc_size AS inc_size,
487                            backups.parts AS parts
488                    FROM backups
489                    INNER JOIN shares       ON backups.shareID=shares.ID
490                    INNER JOIN hosts        ON backups.hostID = hosts.ID
491                    LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
492                    WHERE backups.inc_size > 0 AND backups.size > 0 AND backups.inc_deleted is false AND archive_backup.backup_id IS NULL AND backups.parts > 0
493                    GROUP BY
494                            backups.hostID,
495                            hosts.name,
496                            shares.name,
497                            backups.num,
498                            backups.shareid,
499                            backups.id,
500                            backups.type,
501                            backups.date,
502                            backups.size,
503                            backups.inc_size,
504                            backups.parts
505                    ORDER BY $order
506          };          };
507          my $sth = $dbh->prepare( $sql );          my $sth = $dbh->prepare( $sql );
508          my @ret;          my @ret;
509          $sth->execute();          $sth->execute();
510    
511          while ( my $row = $sth->fetchrow_hashref() ) {          while ( my $row = $sth->fetchrow_hashref() ) {
512                  $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );                  $row->{'age'} = sprintf("%0.1f", ( $row->{'age'} / 86400 ) );
513                  $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);                  #$row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
514                  my (undef,undef,undef,undef,undef,undef,undef,$fs_size,undef,undef,undef,undef,undef) =  
515                          stat( $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.                  my $max_archive_size = $Conf{MaxArchiveSize} || die "no MaxArchiveSize";
516                                  getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'}));                  if ($row->{size} > $max_archive_size) {
517                  $row->{'fs_size'} = $fs_size;                          ($row->{volumes}, $row->{inc_size_calc}) = getVolumes($row->{id});
518                    }
519    
520                    $row->{size} = sprintf("%0.2f", $row->{size} / 1024 / 1024);
521    
522                    # do some cluster calculation (approximate)
523                    $row->{inc_size} = int(( ($row->{inc_size} + 1023 ) / 2 )  * 2);
524                    $row->{inc_size_calc} ||= $row->{inc_size};
525                  push @ret, $row;                  push @ret, $row;
526          }          }
527                
528          return @ret;                return @ret;
529  }  }
530    
531  sub displayBackupsGrid()  sub displayBackupsGrid($) {
532    {  
533        my $retHTML = "";          my $param = shift;
534          
535          $retHTML .= <<EOF3;          my $max_archive_size = $Conf{MaxArchiveSize} || die "no MaxArchiveSize";
536  <script language="javascript" type="text/javascript">          my $max_archive_file_size = $Conf{MaxArchiveFileSize}  || die "no MaxFileInSize";
537    
538            my $retHTML .= q{
539                    <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
540            };
541    
542            $retHTML .= <<'EOF3';
543    <style type="text/css">
544    <!--
545    DIV#fixedBox {
546            position: absolute;
547            top: 50em;
548            left: -24%;
549            padding: 0.5em;
550            width: 20%;
551            background-color: #E0F0E0;
552            border: 1px solid #00C000;
553    }
554    
555    DIV#fixedBox, DIV#fixedBox INPUT, DIV#fixedBox TEXTAREA {
556            font-size: 10pt;
557    }
558    
559    FORM>DIV#fixedBox {
560            position: fixed !important;
561            left: 0.5em !important;
562            top: auto !important;
563            bottom: 1em !important;
564            width: 15% !important;
565    }
566    
567    DIV#fixedBox INPUT[type=text], DIV#fixedBox TEXTAREA {
568            border: 1px solid #00C000;
569    }
570    
571    DIV#fixedBox #note {
572            display: block;
573            width: 100%;
574    }
575    
576    DIV#fixedBox #submitBurner {
577            display: block;
578            width: 100%;
579            margin-top: 0.5em;
580            cursor: pointer;
581    }
582    
583    * HTML {
584            overflow-y: hidden;
585    }
586    
587    * HTML BODY {
588            overflow-y: auto;
589            height: 100%;
590            font-size: 100%;
591    }
592    
593    * HTML DIV#fixedBox {
594            position: absolute;
595    }
596    
597    #mContainer, #gradient, #mask, #progressIndicator {
598            display: block;
599            width: 100%;
600            font-size: 10pt;
601            font-weight: bold;
602            text-align: center;
603            vertical-align: middle;
604            padding: 1px;
605    }
606    
607    #gradient, #mask, #progressIndicator {
608            left: 0;
609            border-width: 1px;
610            border-style: solid;
611            border-color: #000000;
612            color: #404040;
613            margin: 0.4em;
614            position: absolute;
615            margin-left: -1px;
616            margin-top: -1px;
617            margin-bottom: -1px;
618            overflow: hidden;
619    }
620    
621    #mContainer {
622            display: block;
623            position: relative;
624            padding: 0px;
625            margin-top: 0.4em;
626            margin-bottom: 0.5em;
627    }
628    
629    #gradient {
630            z-index: 1;
631            background-color: #FFFF00;
632    }
633    
634    #mask {
635            z-index: 2;
636            background-color: #FFFFFF;
637    }
638    
639    #progressIndicator {
640            z-index: 3;
641            background-color: transparent;
642    }
643    
644    #volumes {
645            padding: 0.4em;
646            display: none;
647            width: 100%;
648            font-size: 80%;
649            color: #ff0000;
650            text-align: center;
651    }
652    -->
653    </style>
654    <script type="text/javascript">
655  <!--  <!--
656    
657      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>        
658  EOF3  EOF3
         $retHTML .= q{  
                 <form name="forma" method="GET" action="$MyURL?action=burn">  
                 <input type="hidden" value="burn" name="action">  
                 <input type="hidden" value="results" name="search_results">  
                 <table style="fview" border="0" cellspacing="0" cellpadding="2">  
                 <tr class="tableheader">  
                 <td class="tableheader">  
                         <input type="checkbox" name="allFiles" onClick="checkAll('allFiles');">  
                 </td>  
                 <td align="center">Share</td>  
                 <td align="center">Backup no</td>  
                 <td align="center">Type</td>  
                 <td align="center">date</td>  
                 <td align="center">age/days</td>  
                 <td align="center">size/MB</td>  
                 <td align="center">gzip size</td>  
                 </tr>  
659    
660                  <tr><td colspan=7 style="tableheader">          # take maximum archive size from configuration
661                  <input type="submit" value="Burn selected backups on medium" name="submitBurner">          $retHTML .= qq{
662                  </td></tr>  var media_size = $max_archive_size ;
663    var max_file_size = $max_archive_file_size;
664    
665    };
666    
667            $retHTML .= <<'EOF3';
668    
669    function debug(msg) {
670            return; // Disable debugging
671    
672            if (! debug_div) debug_div = document.getElementById('debug');
673    
674            // this will create debug div if it doesn't exist.
675            if (! debug_div) {
676                    debug_div = document.createElement('div');
677                    if (document.body) document.body.appendChild(debug_div);
678                    else debug_div = null;
679            }
680            if (debug_div) {
681                    debug_div.appendChild(document.createTextNode(msg));
682                    debug_div.appendChild(document.createElement("br"));
683            }
684    }
685    
686    
687    var element_id_cache = Array();
688    
689    function element_id(name,element) {
690            if (! element_id_cache[name]) {
691                    element_id_cache[name] = self.document.getElementById(name);
692            }
693            return element_id_cache[name];
694    }
695    
696    function checkAll(location) {
697            var f = element_id('forma') || null;
698            if (!f) return false;
699    
700            var len = f.elements.length;
701            var check_all = element_id('allFiles');
702            var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
703    
704            for (var i = 0; i < len; i++) {
705                    var e = f.elements[i];
706                    if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
707                            if (check_all.checked) {
708                                    if (e.checked) continue;
709                                    var el = element_id("fss" + e.name.substr(3));
710                                    var size = parseInt(el.value) || 0;
711                                    debug('suma: '+suma+' size: '+size);
712                                    if ((suma + size) < media_size) {
713                                            suma += size;
714                                            e.checked = true;
715                                    } else {
716                                            break;
717                                    }
718                            } else {
719                                    e.checked = false;
720                            }
721                    }
722            }
723            update_sum(suma);
724    }
725    
726    function update_sum(suma, suma_disp) {
727            if (! suma_disp) suma_disp = suma;
728            suma_disp = Math.floor(suma_disp / 1024);
729            element_id('forma').elements['totalsize_kb'].value = suma_disp;
730            element_id('forma').elements['totalsize'].value = suma;
731            pbar_set(suma, media_size);
732            debug('total size: ' + suma);
733    }
734    
735    function update_size(name, checked, suma) {
736            var size = parseInt( element_id("fss" + name).value);
737    
738            if (checked) {
739                    suma += size;
740            } else {
741                    suma -= size;
742            }
743    
744            var volumes = parseInt( element_id("prt" + name).value);
745            debug('update_size('+name+','+checked+') suma: '+suma+' volumes: '+volumes);
746            if (volumes > 1) {
747                    if (checked) {
748                            element_id("volumes").innerHTML = "This will take "+volumes+" mediums!";
749                            element_id("volumes").style.display = 'block';
750                            suma = size;
751                            update_sum(suma);
752                    } else {
753                            suma -= size;
754                            element_id("volumes").style.display = 'none';
755                    }
756            }
757    
758            return suma;
759    }
760    
761    function sumiraj(e) {
762            var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
763            var len = element_id('forma').elements.length;
764            if (e) {
765                    suma = update_size(e.name.substr(3), e.checked, suma);
766                    if (suma < 0) suma = 0;
767            } else {
768                    suma = 0;
769                    for (var i = 0; i < len; i++) {
770                            var fel = element_id('forma').elements[i];
771                            if (fel.name != 'all' && fel.checked && fel.name.substr(0,3) == 'fcb') {
772                                    suma = update_size(fel.name.substr(3), fel.checked, suma);
773                            }
774                    }
775            }
776            update_sum(suma);
777            return suma;
778    }
779    
780    /* progress bar */
781    
782    var _pbar_width = null;
783    var _pbar_warn = 10;    // change color in last 10%
784    
785    function pbar_reset() {
786            element_id("mask").style.left = "0px";
787            _pbar_width = element_id("mContainer").offsetWidth - 2;
788            element_id("mask").style.width = _pbar_width + "px";
789            element_id("mask").style.display = "block";
790            element_id("progressIndicator").style.zIndex  = 10;
791            element_id("progressIndicator").innerHTML = "0";
792    }
793    
794    function dec2hex(d) {
795            var hch = '0123456789ABCDEF';
796            var a = d % 16;
797            var q = (d - a) / 16;
798            return hch.charAt(q) + hch.charAt(a);
799    }
800    
801    function pbar_set(amount, max) {
802            debug('pbar_set('+amount+', '+max+')');
803    
804            if (_pbar_width == null) {
805                    var _mc = element_id("mContainer");
806                    if (_pbar_width == null) _pbar_width = parseInt(_mc.offsetWidth ? (_mc.offsetWidth - 2) : 0) || null;
807                    if (_pbar_width == null) _pbar_width = parseInt(_mc.clientWidth ? (_mc.clientWidth + 2) : 0) || null;
808                    if (_pbar_width == null) _pbar_width = 0;
809            }
810    
811            var pcnt = Math.floor(amount * 100 / max);
812            var p90 = 100 - _pbar_warn;
813            var pcol = pcnt - p90;
814            if (Math.round(pcnt) <= 100) {
815                    if (pcol < 0) pcol = 0;
816                    var e = element_id("submitBurner");
817                    debug('enable_button');
818                    e.disabled = false;
819                    var a = e.getAttributeNode('disabled') || null;
820                    if (a) e.removeAttributeNode(a);
821            } else {
822                    debug('disable button');
823                    pcol = _pbar_warn;
824                    var e = element_id("submitBurner");
825                    if (!e.disabled) e.disabled = true;
826            }
827            var col_g = Math.floor((_pbar_warn - pcol) * 255 / _pbar_warn);
828            var col = '#FF' + dec2hex(col_g) + '00';
829    
830            //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col);
831            element_id("gradient").style.backgroundColor = col;
832    
833            element_id("progressIndicator").innerHTML = pcnt + '%';
834            //element_id("progressIndicator").innerHTML = amount;
835    
836            element_id("mask").style.clip = 'rect(' + Array(
837                    '0px',
838                    element_id("mask").offsetWidth + 'px',
839                    element_id("mask").offsetHeight + 'px',
840                    Math.round(_pbar_width * amount / max) + 'px'
841            ).join(' ') + ')';
842    }
843    
844    if (!self.body) self.body = new Object();
845    self.onload = self.document.onload = self.body.onload = function() {
846            //pbar_reset();
847            sumiraj();
848    };
849    
850    // -->
851    </script>
852    <div id="fixedBox">
853    
854    <input type="hidden" name="totalsize"/>
855    Size: <input type="text" name="totalsize_kb" size="7" readonly="readonly" style="text-align:right;" value="0" /> kB
856    
857    <div id="mContainer">
858            <div id="gradient">&nbsp;</div>
859            <div id="mask">&nbsp;</div>
860            <div id="progressIndicator">0%</div>
861    </div>
862    <br/>
863    
864    <div id="volumes">&nbsp;</div>
865    
866    Note:
867    <textarea name="note" cols="10" rows="5" id="note"></textarea>
868    
869    <input type="submit" id="submitBurner" value="Burn selected" name="submitBurner" />
870    
871    </div>
872    <!--
873    <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
874    no debug output yet
875    </div>
876    -->
877    EOF3
878            $retHTML .= q{
879                            <input type="hidden" value="burn" name="action">
880                            <input type="hidden" value="results" name="search_results">
881                            <table style="fview" border="0" cellspacing="0" cellpadding="2">
882                            <tr class="tableheader">
883                            <td class="tableheader">
884                                    <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
885                            </td>
886            } .
887                    sort_header($param, 'Share', 'share', 'center') .
888                    sort_header($param, '#', 'num', 'center') .
889            qq{
890                            <td align="center">Type</td>
891            } .
892                    sort_header($param, 'Date', 'date', 'center') .
893                    sort_header($param, 'Age/days', 'age', 'center') .
894                    sort_header($param, 'Size/Mb', 'size', 'center') .
895                    sort_header($param, 'gzip size/Kb', 'incsize', 'center') .
896            qq{
897                            <td align="center">medias</td></tr>
898          };          };
899    
900          my @color = (' bgcolor="#e0e0e0"', '');          my @color = (' bgcolor="#e0e0e0"', '');
# Line 345  EOF3 Line 902  EOF3
902          my $i = 0;          my $i = 0;
903          my $host = '';          my $host = '';
904    
905          foreach my $backup ( getBackupsNotBurned() ) {          foreach my $backup ( getBackupsNotBurned($param) ) {
906    
907                  if ($host ne $backup->{'host'}) {                  if ($host ne $backup->{'host'}) {
908                          $i++;                          $i++;
909                          $host = $backup->{'host'};                          $host = $backup->{'host'};
910                  }                  }
911                  my $ftype = "";                  my $ftype = "";
912                
913                  $retHTML .= "<tr" . $color[$i %2 ] . ">";                  my $checkbox_key = $backup->{'hostid'}. '_' .$backup->{'backupnum'} . '_' . $backup->{'id'};
914                  $retHTML .= '<td class="fview"><input type="checkbox" name="fcb' .  
                                 $backup->{'hostid'}.'_'.$backup->{'backupnum'} .  
                                 '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupnum'} .  
                                 '"></td>';  
               
915                  $retHTML .=                  $retHTML .=
916                            '<tr' . $color[$i %2 ] . '>
917                            <td class="fview">';
918    
919                    if (($backup->{'inc_size'} || 0) > 0) {
920                            $retHTML .= '
921                            <input type="checkbox" name="fcb' . $checkbox_key . '" value="' . $checkbox_key . '" onClick="sumiraj(this);">';
922                    }
923    
924                    my $img_url = $Conf{CgiImageDirURL};
925    
926                    $retHTML .=
927                            '</td>' .
928                          '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .                          '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
929                          '<td align="center">' . $backup->{'backupnum'} . '</td>' .                          '<td align="center">' . $backup->{'backupnum'} . '</td>' .
930                          '<td align="center">' . $backup->{'type'} . '</td>' .                          '<td align="center">' . $backup->{'type'} . '</td>' .
931                          '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .                          '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
932                          '<td align="center">' . $backup->{'age'} . '</td>' .                          '<td align="center">' . $backup->{'age'} . '</td>' .
933                          '<td align="right">' . $backup->{'size'} . '</td>' .                          '<td align="right">' . $backup->{'size'} . '</td>' .
934                          '<td align="right">' . $backup->{'fs_size'} .'</td>' .                          '<td align="right">' . sprintf("%0.1f", $backup->{'inc_size'} / 1024 ) .
935                          "</tr>\n";                          '<input type="hidden" id="fss'.$checkbox_key .'" value="'. $backup->{'inc_size_calc'} .'"></td>' .
936                            '<input type="hidden" id="prt'.$checkbox_key .'" value="'. $backup->{'volumes'} .'"></td>' .
937                            '<td align="left">' . ( qq{<img src="$img_url/icon-cd.gif" alt="media">} x $backup->{volumes} ) . '</td>' .
938    
939                            "</tr>\n";
940          }          }
941    
942          $retHTML .= "</table>";          $retHTML .= "</table>";
# Line 419  sub displayGrid($) { Line 986  sub displayGrid($) {
986          <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">          <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
987                  <tr class="fviewheader">                  <tr class="fviewheader">
988                  <td></td>                  <td></td>
989                  <td align="center">Share</td>          };
990                  <td align="center">Type and Name</td>  
991                  <td align="center">#</td>          sub sort_header($$$$) {
992                  <td align="center">Size</td>                  my ($param, $display, $name, $align) = @_;
993                  <td align="center">Date</td>  
994                    my ($sort_what, $sort_direction) = split(/_/,$param->{'sort'},2);
995    
996                    my $old_sort = $param->{'sort'};
997    
998                    my $html = qq{<td align="$align"};
999                    my $arrow = '';
1000    
1001                    if (lc($sort_what) eq lc($name)) {
1002                            my $direction = lc($sort_direction);
1003    
1004                            # swap direction or fallback to default
1005                            $direction =~ tr/ad/da/;
1006                            $direction = 'a' unless ($direction =~ /[ad]/);
1007    
1008                            $param->{'sort'} = $name . '_' . $direction;
1009                            $html .= ' style="border: 1px solid #808080;"';
1010                    
1011                            # add unicode arrow for direction
1012                            $arrow .= '&nbsp;';
1013                            $arrow .= $direction eq 'a'  ?  '&#9650;'
1014                                    : $direction eq 'd'  ?  '&#9660;'
1015                                    :                       ''
1016                                    ;
1017    
1018                    } else {
1019                            $param->{'sort'} = $name . '_a';
1020                    }
1021    
1022                    $html .= '><a href="' . page_uri($param) . '">' . $display . '</a>' . $arrow . '</td>';
1023                    $param->{'sort'} = $old_sort;
1024    
1025                    return $html;
1026            }
1027    
1028            $retHTML .=
1029                    sort_header($param, 'Share', 'share', 'center') .
1030                    sort_header($param, 'Type and Name', 'path', 'center') .
1031                    sort_header($param, '#', 'num', 'center') .
1032                    sort_header($param, 'Size', 'size', 'center') .
1033                    sort_header($param, 'Date', 'date', 'center');
1034    
1035            $retHTML .= qq{
1036                  <td align="center">Media</td>                  <td align="center">Media</td>
1037                  </tr>                  </tr>
1038          };          };
# Line 443  sub displayGrid($) { Line 1052  sub displayGrid($) {
1052                  return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);                  return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
1053          }          }
1054    
1055            my $sth_archived;
1056            my %archived_cache;
1057    
1058            sub check_archived($$$) {
1059                    my ($host, $share, $num) = @_;
1060    
1061                    if (my $html = $archived_cache{"$host $share $num"}) {
1062                            return $html;
1063                    }
1064    
1065                    $sth_archived ||= $dbh->prepare(qq{
1066                            select
1067                                    dvd_nr, note,
1068                                    count(archive_burned.copy) as copies
1069                            from archive
1070                            inner join archive_burned on archive_burned.archive_id = archive.id
1071                            inner join archive_backup on archive.id = archive_backup.archive_id
1072                            inner join backups on backups.id = archive_backup.backup_id
1073                            inner join hosts on hosts.id = backups.hostid
1074                            inner join shares on shares.id = backups.shareid
1075                            where hosts.name = ? and shares.name = ? and backups.num = ?
1076                            group by dvd_nr, note
1077                    });
1078    
1079                    my @mediums;
1080    
1081                    $sth_archived->execute($host, $share, $num);
1082                    while (my $row = $sth_archived->fetchrow_hashref()) {
1083                            push @mediums, '<abbr title="' .
1084                                    $row->{'note'} .
1085                                    ' [' . $row->{'copies'} . ']' .
1086                                    '">' .$row->{'dvd_nr'} .
1087                                    '</abbr>';
1088                    }
1089    
1090                    my $html = join(", ",@mediums);
1091                    $archived_cache{"$host $share $num"} = $html;
1092                    return $html;
1093            }
1094    
1095          my $i = $offset * $on_page;          my $i = $offset * $on_page;
1096    
1097          foreach $file (@{ $files }) {          foreach $file (@{ $files }) {
# Line 459  sub displayGrid($) { Line 1108  sub displayGrid($) {
1108                          qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .                          qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
1109                          qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .                          qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
1110                          qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .                          qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
1111                          qq{<td class="fviewborder">} . '?' . qq{</td>};                          qq{<td class="fviewborder">} . check_archived( $file->{'hname'}, $file->{'sname'}, $file->{'backupnum'} ) . qq{</td>};
1112    
1113                  $retHTML .= "</tr>";                  $retHTML .= "</tr>";
1114          }          }
# Line 474  sub displayGrid($) { Line 1123  sub displayGrid($) {
1123          my $max_page = int( $results / $on_page );          my $max_page = int( $results / $on_page );
1124          my $page = 0;          my $page = 0;
1125    
1126          sub page_link($$$) {          sub page_uri($) {
1127                  my ($param,$page,$display) = @_;                  my $param = shift || die "no param?";
   
                 $param->{'offset'} = $page;  
1128    
1129                  my $html = '<a href = "' . $MyURL;                  my $uri = $MyURL;
1130                  my $del = '?';                  my $del = '?';
1131                  foreach my $k (keys %{ $param }) {                  foreach my $k (keys %{ $param }) {
1132                          if ($param->{$k}) {                          if ($param->{$k}) {
1133                                  $html .= $del . $k . '=' . ${EscURI( $param->{$k} )};                                  $uri .= $del . $k . '=' . ${EscURI( $param->{$k} )};
1134                                  $del = '&';                                  $del = '&';
1135                          }                          }
1136                  }                  }
1137                  $html .= '">' . $display . '</a>';                  return $uri;
1138            }
1139    
1140            sub page_link($$$) {
1141                    my ($param,$page,$display) = @_;
1142    
1143                    $param->{'offset'} = $page if (defined($page));
1144    
1145                    my $html = '<a href = "' . page_uri($param) . '">' . $display . '</a>';
1146          }          }
1147    
1148          $retHTML .= '<div style="text-align: center;">';          $retHTML .= '<div style="text-align: center;">';

Legend:
Removed from v.109  
changed lines
  Added in v.378

  ViewVC Help
Powered by ViewVC 1.1.26