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

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

  ViewVC Help
Powered by ViewVC 1.1.26