/[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

Annotation of /trunk/lib/BackupPC/SearchLib.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 237 - (hide annotations)
Wed Nov 16 19:24:32 2005 UTC (18 years, 6 months ago) by dpavlin
File size: 27291 byte(s)
fixed path to HyperEstraier index when not using estmaster

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

  ViewVC Help
Powered by ViewVC 1.1.26