/[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 267 - (hide annotations)
Tue Dec 13 01:24:09 2005 UTC (18 years, 5 months ago) by dpavlin
File size: 28542 byte(s)
remove debug div

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 dpavlin 253 if (-f "${tgz}.tar.gz") {
381     $size = (stat("${tgz}.tar.gz"))[7];
382 dpavlin 194 } elsif (-d $tgz) {
383     opendir(my $dir, $tgz) || die "can't opendir $tgz: $!";
384 dpavlin 254 my @parts = grep { !/^\./ && !/md5/ && -f "$tgz/$_" } readdir($dir);
385 dpavlin 194 $size = 0;
386     foreach my $part (@parts) {
387     $size += (stat("$tgz/$part"))[7] || die "can't stat $tgz/$part: $!";
388     }
389     closedir $dir;
390 dpavlin 254 } else {
391     return -1;
392 dpavlin 194 }
393    
394     return $size;
395     }
396    
397 iklaric 143 sub getGzipSize($$)
398     {
399     my ($hostID, $backupNum) = @_;
400     my $sql;
401     my $dbh = get_dbh();
402    
403     $sql = q{
404     SELECT hosts.name as host,
405     shares.name as share,
406     backups.num as backupnum
407     FROM hosts, backups, shares
408     WHERE shares.id=backups.shareid AND
409     hosts.id =backups.hostid AND
410     hosts.id=? AND
411 dpavlin 145 backups.num=?
412 iklaric 143 };
413     my $sth = $dbh->prepare($sql);
414 dpavlin 145 $sth->execute($hostID, $backupNum);
415    
416     my $row = $sth->fetchrow_hashref();
417 dpavlin 194
418     return get_tgz_size_by_name(
419     getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'})
420     );
421 iklaric 143 }
422    
423 dpavlin 259 sub getVolumes($) {
424     my $id = shift;
425    
426     my $max_archive_size = $Conf{MaxArchiveSize} || die "no MaxArchiveSize";
427    
428     my $sth = $dbh->prepare(qq{
429     select
430     size
431     from backup_parts
432     where backup_id = ?
433     order by part_nr asc
434     });
435    
436     $sth->execute($id);
437    
438     my $cumulative_size = 0;
439     my $volumes = 1;
440    
441     while(my ($size) = $sth->fetchrow_array) {
442     if ($cumulative_size + $size > $max_archive_size) {
443     $volumes++;
444     $cumulative_size = $size;
445     } else {
446     $cumulative_size += $size;
447     }
448     }
449    
450     return ($volumes,$cumulative_size);
451     }
452    
453 dpavlin 217 sub getBackupsNotBurned($) {
454 dpavlin 51
455 dpavlin 217 my $param = shift;
456 dpavlin 84 my $dbh = get_dbh();
457 iklaric 121
458 dpavlin 217 my $order = getSort('burn', 'sql', $param->{'sort'});
459    
460     print STDERR "## sort=". ($param->{'sort'} || 'no sort param') . " burn sql order: $order\n";
461    
462     my $sql = qq{
463 iklaric 121 SELECT
464     backups.hostID AS hostID,
465     hosts.name AS host,
466     shares.name AS share,
467 dpavlin 145 backups.num AS backupnum,
468 iklaric 121 backups.type AS type,
469     backups.date AS date,
470 dpavlin 217 date_part('epoch',now()) - backups.date as age,
471 dpavlin 145 backups.size AS size,
472 dpavlin 161 backups.id AS id,
473 dpavlin 197 backups.inc_size AS inc_size,
474     backups.parts AS parts
475 iklaric 121 FROM backups
476 dpavlin 122 INNER JOIN shares ON backups.shareID=shares.ID
477     INNER JOIN hosts ON backups.hostID = hosts.ID
478 iklaric 137 LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
479 dpavlin 171 WHERE backups.inc_size > 0 AND backups.inc_deleted is false AND archive_backup.backup_id IS NULL
480 dpavlin 122 GROUP BY
481     backups.hostID,
482     hosts.name,
483     shares.name,
484     backups.num,
485     backups.shareid,
486     backups.id,
487     backups.type,
488     backups.date,
489 dpavlin 161 backups.size,
490 dpavlin 197 backups.inc_size,
491     backups.parts
492 dpavlin 217 ORDER BY $order
493 dpavlin 53 };
494     my $sth = $dbh->prepare( $sql );
495     my @ret;
496     $sth->execute();
497 dpavlin 4
498 dpavlin 66 while ( my $row = $sth->fetchrow_hashref() ) {
499 dpavlin 217 $row->{'age'} = sprintf("%0.1f", ( $row->{'age'} / 86400 ) );
500     #$row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
501 dpavlin 161
502 dpavlin 259 my $max_archive_size = $Conf{MaxArchiveSize} || die "no MaxArchiveSize";
503     if ($row->{size} > $max_archive_size) {
504     ($row->{volumes}, $row->{inc_size_calc}) = getVolumes($row->{id});
505     }
506    
507     $row->{size} = sprintf("%0.2f", $row->{size} / 1024 / 1024);
508    
509     # do some cluster calculation (approximate)
510 dpavlin 262 $row->{inc_size} = int(( ($row->{inc_size} + 1023 ) / 2 ) * 2);
511 dpavlin 259 $row->{inc_size_calc} ||= $row->{inc_size};
512 dpavlin 66 push @ret, $row;
513 dpavlin 4 }
514    
515 dpavlin 259 return @ret;
516 dpavlin 53 }
517 dpavlin 4
518 dpavlin 217 sub displayBackupsGrid($) {
519 dpavlin 126
520 dpavlin 217 my $param = shift;
521    
522 dpavlin 230 my $max_archive_size = $Conf{MaxArchiveSize} || die "no MaxArchiveSize";
523     my $max_archive_file_size = $Conf{MaxArchiveFileSize} || die "no MaxFileInSize";
524    
525 dpavlin 126 my $retHTML .= q{
526 ravilov 140 <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
527 dpavlin 126 };
528    
529 dpavlin 127 $retHTML .= <<'EOF3';
530 ravilov 140 <style type="text/css">
531 dpavlin 127 <!--
532 ravilov 140 DIV#fixedBox {
533 dpavlin 128 position: absolute;
534 ravilov 140 top: 50em;
535     left: -24%;
536 dpavlin 128 padding: 0.5em;
537 ravilov 140 width: 20%;
538     background-color: #E0F0E0;
539     border: 1px solid #00C000;
540 dpavlin 128 }
541 ravilov 140
542     DIV#fixedBox, DIV#fixedBox INPUT, DIV#fixedBox TEXTAREA {
543     font-size: 10pt;
544 dpavlin 128 }
545 dpavlin 127
546 ravilov 140 FORM>DIV#fixedBox {
547     position: fixed !important;
548     left: 0.5em !important;
549     top: auto !important;
550     bottom: 1em !important;
551     width: 15% !important;
552     }
553    
554     DIV#fixedBox INPUT[type=text], DIV#fixedBox TEXTAREA {
555     border: 1px solid #00C000;
556     }
557    
558     DIV#fixedBox #note {
559     display: block;
560 dpavlin 128 width: 100%;
561     }
562    
563 ravilov 140 DIV#fixedBox #submitBurner {
564     display: block;
565 dpavlin 128 width: 100%;
566 ravilov 140 margin-top: 0.5em;
567     cursor: pointer;
568     }
569    
570     * HTML {
571     overflow-y: hidden;
572     }
573    
574     * HTML BODY {
575     overflow-y: auto;
576 dpavlin 128 height: 100%;
577 ravilov 140 font-size: 100%;
578     }
579    
580     * HTML DIV#fixedBox {
581     position: absolute;
582     }
583    
584     #mContainer, #gradient, #mask, #progressIndicator {
585 dpavlin 128 display: block;
586 ravilov 140 width: 100%;
587     font-size: 10pt;
588     font-weight: bold;
589     text-align: center;
590     vertical-align: middle;
591     padding: 1px;
592 dpavlin 128 }
593    
594 ravilov 140 #gradient, #mask, #progressIndicator {
595     left: 0;
596     border-width: 1px;
597     border-style: solid;
598     border-color: #000000;
599     color: #404040;
600     margin: 0.4em;
601 dpavlin 128 position: absolute;
602 ravilov 140 margin-left: -1px;
603     margin-top: -1px;
604     margin-bottom: -1px;
605     overflow: hidden;
606     }
607    
608     #mContainer {
609 dpavlin 128 display: block;
610 ravilov 140 position: relative;
611     padding: 0px;
612     margin-top: 0.4em;
613     margin-bottom: 0.5em;
614     }
615    
616     #gradient {
617     z-index: 1;
618     background-color: #FFFF00;
619     }
620    
621     #mask {
622     z-index: 2;
623 dpavlin 128 background-color: #FFFFFF;
624     }
625    
626     #progressIndicator {
627 ravilov 140 z-index: 3;
628     background-color: transparent;
629 dpavlin 128 }
630 dpavlin 197
631 dpavlin 259 #volumes {
632 dpavlin 197 padding: 0.4em;
633     display: none;
634     width: 100%;
635     font-size: 80%;
636     color: #ff0000;
637     text-align: center;
638     }
639 dpavlin 127 -->
640     </style>
641 ravilov 140 <script type="text/javascript">
642 dpavlin 4 <!--
643    
644 dpavlin 126 var debug_div = null;
645 dpavlin 149 EOF3
646 dpavlin 126
647 dpavlin 149 # take maximum archive size from configuration
648 dpavlin 230 $retHTML .= qq{
649     var media_size = $max_archive_size ;
650     var max_file_size = $max_archive_file_size;
651 dpavlin 149
652 dpavlin 230 };
653    
654 dpavlin 149 $retHTML .= <<'EOF3';
655    
656 dpavlin 126 function debug(msg) {
657 dpavlin 262 // return; // Disable debugging
658 dpavlin 126
659     if (! debug_div) debug_div = document.getElementById('debug');
660    
661     // this will create debug div if it doesn't exist.
662     if (! debug_div) {
663     debug_div = document.createElement('div');
664     if (document.body) document.body.appendChild(debug_div);
665     else debug_div = null;
666     }
667     if (debug_div) {
668     debug_div.appendChild(document.createTextNode(msg));
669     debug_div.appendChild(document.createElement("br"));
670     }
671     }
672    
673    
674     var element_id_cache = Array();
675    
676     function element_id(name,element) {
677     if (! element_id_cache[name]) {
678     element_id_cache[name] = self.document.getElementById(name);
679     }
680     return element_id_cache[name];
681     }
682    
683     function checkAll(location) {
684 ravilov 142 var f = element_id('forma') || null;
685     if (!f) return false;
686    
687     var len = f.elements.length;
688 dpavlin 126 var check_all = element_id('allFiles');
689 ravilov 142 var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
690 dpavlin 126
691     for (var i = 0; i < len; i++) {
692 ravilov 142 var e = f.elements[i];
693     if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
694 dpavlin 126 if (check_all.checked) {
695 ravilov 142 if (e.checked) continue;
696 dpavlin 129 var el = element_id("fss" + e.name.substr(3));
697     var size = parseInt(el.value) || 0;
698     debug('suma: '+suma+' size: '+size);
699     if ((suma + size) < media_size) {
700     suma += size;
701     e.checked = true;
702     } else {
703     break;
704     }
705 dpavlin 126 } else {
706     e.checked = false;
707     }
708     }
709     }
710 dpavlin 129 update_sum(suma);
711     }
712 dpavlin 126
713 dpavlin 197 function update_sum(suma, suma_disp) {
714     if (! suma_disp) suma_disp = suma;
715 dpavlin 259 suma_disp = Math.floor(suma_disp / 1024);
716     element_id('forma').elements['totalsize_kb'].value = suma_disp;
717     element_id('forma').elements['totalsize'].value = suma;
718 dpavlin 129 pbar_set(suma, media_size);
719 ravilov 141 debug('total size: ' + suma);
720 dpavlin 126 }
721 dpavlin 129
722 dpavlin 262 function update_size(name, checked, suma) {
723     var size = parseInt( element_id("fss" + name).value);
724    
725     if (checked) {
726     suma += size;
727     } else {
728     suma -= size;
729     }
730    
731     var volumes = parseInt( element_id("prt" + name).value);
732     debug('update_size('+name+','+checked+') suma: '+suma+' volumes: '+volumes);
733     if (volumes > 1) {
734     if (checked) {
735     element_id("volumes").innerHTML = "This will take "+volumes+" mediums!";
736     element_id("volumes").style.display = 'block';
737     suma = size;
738     update_sum(suma);
739 dpavlin 126 } else {
740     suma -= size;
741 dpavlin 262 element_id("volumes").style.display = 'none';
742 dpavlin 126 }
743 dpavlin 262 }
744 dpavlin 197
745 dpavlin 262 return suma;
746     }
747 dpavlin 197
748 dpavlin 262 function sumiraj(e) {
749     var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
750     var len = element_id('forma').elements.length;
751     if (e) {
752     suma = update_size(e.name.substr(3), e.checked, suma);
753 dpavlin 197 if (suma < 0) suma = 0;
754 dpavlin 126 } else {
755     suma = 0;
756     for (var i = 0; i < len; i++) {
757 dpavlin 262 var fel = element_id('forma').elements[i];
758     if (fel.name != 'all' && fel.checked && fel.name.substr(0,3) == 'fcb') {
759     suma = update_size(fel.name.substr(3), fel.checked, suma);
760 dpavlin 126 }
761     }
762     }
763 dpavlin 129 update_sum(suma);
764 iklaric 121 return suma;
765 dpavlin 126 }
766    
767 dpavlin 128 /* progress bar */
768    
769 ravilov 140 var _pbar_width = null;
770 dpavlin 128 var _pbar_warn = 10; // change color in last 10%
771    
772     function pbar_reset() {
773     element_id("mask").style.left = "0px";
774     _pbar_width = element_id("mContainer").offsetWidth - 2;
775     element_id("mask").style.width = _pbar_width + "px";
776 ravilov 140 element_id("mask").style.display = "block";
777 dpavlin 128 element_id("progressIndicator").style.zIndex = 10;
778     element_id("progressIndicator").innerHTML = "0";
779     }
780    
781     function dec2hex(d) {
782 ravilov 140 var hch = '0123456789ABCDEF';
783     var a = d % 16;
784     var q = (d - a) / 16;
785     return hch.charAt(q) + hch.charAt(a);
786 dpavlin 128 }
787    
788     function pbar_set(amount, max) {
789 ravilov 140 debug('pbar_set('+amount+', '+max+')');
790 dpavlin 128
791 ravilov 140 if (_pbar_width == null) {
792     var _mc = element_id("mContainer");
793     if (_pbar_width == null) _pbar_width = parseInt(_mc.offsetWidth ? (_mc.offsetWidth - 2) : 0) || null;
794     if (_pbar_width == null) _pbar_width = parseInt(_mc.clientWidth ? (_mc.clientWidth + 2) : 0) || null;
795     if (_pbar_width == null) _pbar_width = 0;
796     }
797 dpavlin 128
798 ravilov 140 var pcnt = Math.floor(amount * 100 / max);
799 dpavlin 128 var p90 = 100 - _pbar_warn;
800     var pcol = pcnt - p90;
801 ravilov 140 if (Math.round(pcnt) <= 100) {
802 dpavlin 128 if (pcol < 0) pcol = 0;
803     var e = element_id("submitBurner");
804 ravilov 140 debug('enable_button');
805     e.disabled = false;
806     var a = e.getAttributeNode('disabled') || null;
807     if (a) e.removeAttributeNode(a);
808     } else {
809 dpavlin 128 debug('disable button');
810     pcol = _pbar_warn;
811     var e = element_id("submitBurner");
812 ravilov 140 if (!e.disabled) e.disabled = true;
813 dpavlin 128 }
814 ravilov 140 var col_g = Math.floor((_pbar_warn - pcol) * 255 / _pbar_warn);
815     var col = '#FF' + dec2hex(col_g) + '00';
816 dpavlin 128
817     //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col);
818     element_id("gradient").style.backgroundColor = col;
819    
820     element_id("progressIndicator").innerHTML = pcnt + '%';
821     //element_id("progressIndicator").innerHTML = amount;
822    
823 ravilov 140 element_id("mask").style.clip = 'rect(' + Array(
824     '0px',
825     element_id("mask").offsetWidth + 'px',
826     element_id("mask").offsetHeight + 'px',
827     Math.round(_pbar_width * amount / max) + 'px'
828     ).join(' ') + ')';
829 dpavlin 128 }
830    
831 dpavlin 126 if (!self.body) self.body = new Object();
832     self.onload = self.document.onload = self.body.onload = function() {
833 ravilov 140 //pbar_reset();
834 dpavlin 126 sumiraj();
835 ravilov 140 };
836 dpavlin 126
837 ravilov 140 // -->
838 dpavlin 126 </script>
839 dpavlin 127 <div id="fixedBox">
840    
841 dpavlin 259 <input type="hidden" name="totalsize"/>
842     Size: <input type="text" name="totalsize_kb" size="7" readonly="readonly" style="text-align:right;" value="0" /> kB
843 dpavlin 128
844     <div id="mContainer">
845 ravilov 140 <div id="gradient">&nbsp;</div>
846     <div id="mask">&nbsp;</div>
847     <div id="progressIndicator">0%</div>
848 dpavlin 128 </div>
849 ravilov 140 <br/>
850 dpavlin 128
851 dpavlin 259 <div id="volumes">&nbsp;</div>
852 dpavlin 197
853 dpavlin 126 Note:
854 ravilov 140 <textarea name="note" cols="10" rows="5" id="note"></textarea>
855 dpavlin 127
856 ravilov 140 <input type="submit" id="submitBurner" value="Burn selected" name="submitBurner" />
857    
858 dpavlin 126 </div>
859 dpavlin 267 <!--
860 dpavlin 127 <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
861     no debug output yet
862     </div>
863 dpavlin 267 -->
864 dpavlin 4 EOF3
865 dpavlin 102 $retHTML .= q{
866 iklaric 121 <input type="hidden" value="burn" name="action">
867     <input type="hidden" value="results" name="search_results">
868     <table style="fview" border="0" cellspacing="0" cellpadding="2">
869     <tr class="tableheader">
870     <td class="tableheader">
871 dpavlin 126 <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
872 iklaric 121 </td>
873 dpavlin 217 } .
874     sort_header($param, 'Share', 'share', 'center') .
875     sort_header($param, '#', 'num', 'center') .
876     qq{
877 iklaric 121 <td align="center">Type</td>
878 dpavlin 217 } .
879     sort_header($param, 'Date', 'date', 'center') .
880     sort_header($param, 'Age/days', 'age', 'center') .
881     sort_header($param, 'Size/Mb', 'size', 'center') .
882     sort_header($param, 'gzip size/Kb', 'incsize', 'center') .
883     qq{
884 dpavlin 259 <td align="center">medias</td></tr>
885 dpavlin 58 };
886 dpavlin 4
887 dpavlin 102 my @color = (' bgcolor="#e0e0e0"', '');
888 dpavlin 31
889 dpavlin 102 my $i = 0;
890     my $host = '';
891 dpavlin 31
892 dpavlin 217 foreach my $backup ( getBackupsNotBurned($param) ) {
893 dpavlin 31
894 dpavlin 102 if ($host ne $backup->{'host'}) {
895     $i++;
896     $host = $backup->{'host'};
897     }
898 dpavlin 31 my $ftype = "";
899 dpavlin 125
900 dpavlin 145 my $checkbox_key = $backup->{'hostid'}. '_' .$backup->{'backupnum'} . '_' . $backup->{'id'};
901    
902 dpavlin 102 $retHTML .=
903 dpavlin 125 '<tr' . $color[$i %2 ] . '>
904     <td class="fview">';
905 dpavlin 145
906 dpavlin 161 if (($backup->{'inc_size'} || 0) > 0) {
907 dpavlin 125 $retHTML .= '
908 dpavlin 145 <input type="checkbox" name="fcb' . $checkbox_key . '" value="' . $checkbox_key . '" onClick="sumiraj(this);">';
909 dpavlin 125 }
910 dpavlin 145
911 dpavlin 259 my $img_url = $Conf{CgiImageDirURL};
912    
913 dpavlin 125 $retHTML .=
914     '</td>' .
915 dpavlin 102 '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
916     '<td align="center">' . $backup->{'backupnum'} . '</td>' .
917     '<td align="center">' . $backup->{'type'} . '</td>' .
918     '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
919     '<td align="center">' . $backup->{'age'} . '</td>' .
920     '<td align="right">' . $backup->{'size'} . '</td>' .
921 dpavlin 262 '<td align="right">' . sprintf("%0.1f", $backup->{'inc_size'} / 1024 ) .
922 dpavlin 259 '<input type="hidden" id="fss'.$checkbox_key .'" value="'. $backup->{'inc_size_calc'} .'"></td>' .
923     '<input type="hidden" id="prt'.$checkbox_key .'" value="'. $backup->{'volumes'} .'"></td>' .
924     '<td align="left">' . ( qq{<img src="$img_url/icon-cd.gif" alt="media">} x $backup->{volumes} ) . '</td>' .
925 dpavlin 125
926 dpavlin 102 "</tr>\n";
927 dpavlin 4 }
928 dpavlin 31
929     $retHTML .= "</table>";
930 dpavlin 102 $retHTML .= "</form>";
931 dpavlin 4
932 dpavlin 31 return $retHTML;
933     }
934 dpavlin 4
935 dpavlin 86 sub displayGrid($) {
936     my ($param) = @_;
937 dpavlin 83
938     my $offset = $param->{'offset'};
939     my $hilite = $param->{'search_filename'};
940    
941 dpavlin 17 my $retHTML = "";
942    
943 dpavlin 55 my $start_t = time();
944    
945 dpavlin 86 my ($results, $files);
946 dpavlin 88 if ($param->{'use_hest'} && length($hilite) > 0) {
947 dpavlin 87 ($results, $files) = getFilesHyperEstraier($param);
948 dpavlin 86 } else {
949 dpavlin 87 ($results, $files) = getFiles($param);
950 dpavlin 86 }
951 dpavlin 31
952 dpavlin 55 my $dur_t = time() - $start_t;
953     my $dur = sprintf("%0.4fs", $dur_t);
954    
955 dpavlin 31 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
956    
957 dpavlin 59 if ($results <= 0) {
958     $retHTML .= qq{
959     <p style="color: red;">No results found...</p>
960     };
961     return $retHTML;
962     } else {
963     # DEBUG
964     #use Data::Dumper;
965     #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
966     }
967    
968    
969 dpavlin 17 $retHTML .= qq{
970 dpavlin 79 <div>
971     Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
972     </div>
973     <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
974     <tr class="fviewheader">
975 dpavlin 87 <td></td>
976 dpavlin 211 };
977    
978 dpavlin 217 sub sort_header($$$$) {
979     my ($param, $display, $name, $align) = @_;
980 dpavlin 211
981 dpavlin 229 my ($sort_what, $sort_direction) = split(/_/,$param->{'sort'},2);
982 dpavlin 211
983 dpavlin 217 my $old_sort = $param->{'sort'};
984    
985     my $html = qq{<td align="$align"};
986 dpavlin 229 my $arrow = '';
987    
988 dpavlin 211 if (lc($sort_what) eq lc($name)) {
989 dpavlin 229 my $direction = lc($sort_direction);
990    
991     # swap direction or fallback to default
992     $direction =~ tr/ad/da/;
993     $direction = 'a' unless ($direction =~ /[ad]/);
994    
995     $param->{'sort'} = $name . '_' . $direction;
996 dpavlin 211 $html .= ' style="border: 1px solid #808080;"';
997 dpavlin 229
998     # add unicode arrow for direction
999     $arrow .= '&nbsp;';
1000     $arrow .= $direction eq 'a' ? '&#9650;'
1001     : $direction eq 'd' ? '&#9660;'
1002     : ''
1003     ;
1004    
1005 dpavlin 211 } else {
1006     $param->{'sort'} = $name . '_a';
1007     }
1008 dpavlin 229
1009     $html .= '><a href="' . page_uri($param) . '">' . $display . '</a>' . $arrow . '</td>';
1010 dpavlin 217 $param->{'sort'} = $old_sort;
1011    
1012 dpavlin 211 return $html;
1013     }
1014    
1015     $retHTML .=
1016 dpavlin 217 sort_header($param, 'Share', 'share', 'center') .
1017     sort_header($param, 'Type and Name', 'path', 'center') .
1018     sort_header($param, '#', 'num', 'center') .
1019     sort_header($param, 'Size', 'size', 'center') .
1020     sort_header($param, 'Date', 'date', 'center');
1021 dpavlin 211
1022     $retHTML .= qq{
1023 dpavlin 79 <td align="center">Media</td>
1024 dpavlin 17 </tr>
1025     };
1026 dpavlin 31
1027 dpavlin 17 my $file;
1028 dpavlin 4
1029 dpavlin 17 sub hilite_html($$) {
1030     my ($html, $search) = @_;
1031     $html =~ s#($search)#<b>$1</b>#gis;
1032     return $html;
1033 dpavlin 4 }
1034 dpavlin 9
1035 dpavlin 26 sub restore_link($$$$$$) {
1036     my $type = shift;
1037     my $action = 'RestoreFile';
1038     $action = 'browse' if (lc($type) eq 'dir');
1039     return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
1040     }
1041    
1042 dpavlin 209 my $sth_archived;
1043     my %archived_cache;
1044    
1045     sub check_archived($$$) {
1046     my ($host, $share, $num) = @_;
1047    
1048     if (my $html = $archived_cache{"$host $share $num"}) {
1049     return $html;
1050     }
1051    
1052     $sth_archived ||= $dbh->prepare(qq{
1053     select
1054     dvd_nr, note,
1055     count(archive_burned.copy) as copies
1056     from archive
1057     inner join archive_burned on archive_burned.archive_id = archive.id
1058     inner join archive_backup on archive.id = archive_backup.archive_id
1059     inner join backups on backups.id = archive_backup.backup_id
1060     inner join hosts on hosts.id = backups.hostid
1061     inner join shares on shares.id = backups.shareid
1062     where hosts.name = ? and shares.name = ? and backups.num = ?
1063     group by dvd_nr, note
1064     });
1065    
1066     my @mediums;
1067    
1068     $sth_archived->execute($host, $share, $num);
1069     while (my $row = $sth_archived->fetchrow_hashref()) {
1070     push @mediums, '<abbr title="' .
1071     $row->{'note'} .
1072     ' [' . $row->{'copies'} . ']' .
1073     '">' .$row->{'dvd_nr'} .
1074     '</abbr>';
1075     }
1076    
1077     my $html = join(", ",@mediums);
1078     $archived_cache{"$host $share $num"} = $html;
1079     return $html;
1080     }
1081    
1082 dpavlin 87 my $i = $offset * $on_page;
1083    
1084 dpavlin 31 foreach $file (@{ $files }) {
1085 dpavlin 87 $i++;
1086    
1087 dpavlin 24 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
1088 dpavlin 79 $retHTML .= qq{<tr class="fviewborder">};
1089 dpavlin 9
1090 dpavlin 88 $retHTML .= qq{<td class="fviewborder">$i</td>};
1091 dpavlin 87
1092 dpavlin 79 $retHTML .=
1093 dpavlin 86 qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
1094     qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
1095     qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
1096 dpavlin 79 qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
1097     qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
1098 dpavlin 209 qq{<td class="fviewborder">} . check_archived( $file->{'hname'}, $file->{'sname'}, $file->{'backupnum'} ) . qq{</td>};
1099 dpavlin 9
1100 dpavlin 17 $retHTML .= "</tr>";
1101     }
1102     $retHTML .= "</table>";
1103    
1104 dpavlin 31 # all variables which has to be transfered
1105     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/) {
1106     $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
1107     }
1108 dpavlin 17
1109 dpavlin 31 my $del = '';
1110     my $max_page = int( $results / $on_page );
1111     my $page = 0;
1112    
1113 dpavlin 211 sub page_uri($) {
1114     my $param = shift || die "no param?";
1115 dpavlin 31
1116 dpavlin 211 my $uri = $MyURL;
1117 dpavlin 85 my $del = '?';
1118     foreach my $k (keys %{ $param }) {
1119     if ($param->{$k}) {
1120 dpavlin 211 $uri .= $del . $k . '=' . ${EscURI( $param->{$k} )};
1121 dpavlin 85 $del = '&';
1122     }
1123     }
1124 dpavlin 211 return $uri;
1125 dpavlin 85 }
1126    
1127 dpavlin 211 sub page_link($$$) {
1128     my ($param,$page,$display) = @_;
1129    
1130     $param->{'offset'} = $page if (defined($page));
1131    
1132     my $html = '<a href = "' . page_uri($param) . '">' . $display . '</a>';
1133     }
1134    
1135 dpavlin 31 $retHTML .= '<div style="text-align: center;">';
1136    
1137     if ($offset > 0) {
1138 dpavlin 85 $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
1139 dpavlin 31 }
1140    
1141     while ($page <= $max_page) {
1142     if ($page == $offset) {
1143     $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
1144     } else {
1145 dpavlin 85 $retHTML .= $del . page_link($param, $page, $page + 1);
1146 dpavlin 17 }
1147 dpavlin 31
1148     if ($page < $offset - $pager_pages && $page != 0) {
1149     $retHTML .= " ... ";
1150     $page = $offset - $pager_pages;
1151     $del = '';
1152     } elsif ($page > $offset + $pager_pages && $page != $max_page) {
1153     $retHTML .= " ... ";
1154     $page = $max_page;
1155     $del = '';
1156     } else {
1157     $del = ' | ';
1158     $page++;
1159     }
1160 dpavlin 17 }
1161    
1162 dpavlin 31 if ($offset < $max_page) {
1163 dpavlin 85 $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
1164 dpavlin 31 }
1165    
1166     $retHTML .= "</div>";
1167    
1168 dpavlin 17 return $retHTML;
1169     }
1170 dpavlin 4
1171     1;

  ViewVC Help
Powered by ViewVC 1.1.26