/[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 382 - (hide annotations)
Mon May 14 08:06:52 2007 UTC (17 years ago) by iklaric
File size: 29280 byte(s)
- fixed bug that occured while calculating total dvd size

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

  ViewVC Help
Powered by ViewVC 1.1.26