/[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 259 - (hide annotations)
Mon Dec 12 20:59:58 2005 UTC (18 years, 5 months ago) by dpavlin
File size: 28423 byte(s)
 r11645@llin:  dpavlin | 2005-12-12 22:57:51 +0100
 added getVolumes to calculate number of media required, convert to bytes,
 added images of medias required (but it's broken!)

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     $row->{inc_size} = int(($row->{inc_size} + 1023 ) / ( 2 * 1024 ) * 2);
511     $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 197 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 126 function sumiraj(e) {
723 ravilov 141 var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
724 dpavlin 126 var len = element_id('forma').elements.length;
725     if (e) {
726 ravilov 140 var size = parseInt( element_id("fss" + e.name.substr(3)).value);
727 dpavlin 126 if (e.checked) {
728     suma += size;
729     } else {
730     suma -= size;
731     }
732 dpavlin 197
733 dpavlin 259 var volumes = parseInt( element_id("prt" + e.name.substr(3)).value);
734     if (volumes > 1) {
735     if (e.checked) {
736     element_id("volumes").innerHTML = "This will take "+volumes+" mediums!";
737     element_id("volumes").style.display = 'block';
738     suma = size;
739     update_sum(suma);
740     return suma;
741     } else {
742     suma -= size;
743     element_id("volumes").style.display = 'none';
744     }
745 dpavlin 197 }
746    
747     if (suma < 0) suma = 0;
748 dpavlin 126 } else {
749     suma = 0;
750     for (var i = 0; i < len; i++) {
751     var e = element_id('forma').elements[i];
752 dpavlin 127 if (e.name != 'all' && e.checked && e.name.substr(0,3) == 'fcb') {
753 dpavlin 126 var el = element_id("fss" + e.name.substr(3));
754     if (el && el.value) suma += parseInt(el.value) || 0;
755     }
756     }
757     }
758 dpavlin 129 update_sum(suma);
759 iklaric 121 return suma;
760 dpavlin 126 }
761    
762 dpavlin 128 /* progress bar */
763    
764 ravilov 140 var _pbar_width = null;
765 dpavlin 128 var _pbar_warn = 10; // change color in last 10%
766    
767     function pbar_reset() {
768     element_id("mask").style.left = "0px";
769     _pbar_width = element_id("mContainer").offsetWidth - 2;
770     element_id("mask").style.width = _pbar_width + "px";
771 ravilov 140 element_id("mask").style.display = "block";
772 dpavlin 128 element_id("progressIndicator").style.zIndex = 10;
773     element_id("progressIndicator").innerHTML = "0";
774     }
775    
776     function dec2hex(d) {
777 ravilov 140 var hch = '0123456789ABCDEF';
778     var a = d % 16;
779     var q = (d - a) / 16;
780     return hch.charAt(q) + hch.charAt(a);
781 dpavlin 128 }
782    
783     function pbar_set(amount, max) {
784 ravilov 140 debug('pbar_set('+amount+', '+max+')');
785 dpavlin 128
786 ravilov 140 if (_pbar_width == null) {
787     var _mc = element_id("mContainer");
788     if (_pbar_width == null) _pbar_width = parseInt(_mc.offsetWidth ? (_mc.offsetWidth - 2) : 0) || null;
789     if (_pbar_width == null) _pbar_width = parseInt(_mc.clientWidth ? (_mc.clientWidth + 2) : 0) || null;
790     if (_pbar_width == null) _pbar_width = 0;
791     }
792 dpavlin 128
793 ravilov 140 var pcnt = Math.floor(amount * 100 / max);
794 dpavlin 128 var p90 = 100 - _pbar_warn;
795     var pcol = pcnt - p90;
796 ravilov 140 if (Math.round(pcnt) <= 100) {
797 dpavlin 128 if (pcol < 0) pcol = 0;
798     var e = element_id("submitBurner");
799 ravilov 140 debug('enable_button');
800     e.disabled = false;
801     var a = e.getAttributeNode('disabled') || null;
802     if (a) e.removeAttributeNode(a);
803     } else {
804 dpavlin 128 debug('disable button');
805     pcol = _pbar_warn;
806     var e = element_id("submitBurner");
807 ravilov 140 if (!e.disabled) e.disabled = true;
808 dpavlin 128 }
809 ravilov 140 var col_g = Math.floor((_pbar_warn - pcol) * 255 / _pbar_warn);
810     var col = '#FF' + dec2hex(col_g) + '00';
811 dpavlin 128
812     //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col);
813     element_id("gradient").style.backgroundColor = col;
814    
815     element_id("progressIndicator").innerHTML = pcnt + '%';
816     //element_id("progressIndicator").innerHTML = amount;
817    
818 ravilov 140 element_id("mask").style.clip = 'rect(' + Array(
819     '0px',
820     element_id("mask").offsetWidth + 'px',
821     element_id("mask").offsetHeight + 'px',
822     Math.round(_pbar_width * amount / max) + 'px'
823     ).join(' ') + ')';
824 dpavlin 128 }
825    
826 dpavlin 126 if (!self.body) self.body = new Object();
827     self.onload = self.document.onload = self.body.onload = function() {
828 ravilov 140 //pbar_reset();
829 dpavlin 126 sumiraj();
830 ravilov 140 };
831 dpavlin 126
832 ravilov 140 // -->
833 dpavlin 126 </script>
834 dpavlin 127 <div id="fixedBox">
835    
836 dpavlin 259 <input type="hidden" name="totalsize"/>
837     Size: <input type="text" name="totalsize_kb" size="7" readonly="readonly" style="text-align:right;" value="0" /> kB
838 dpavlin 128
839     <div id="mContainer">
840 ravilov 140 <div id="gradient">&nbsp;</div>
841     <div id="mask">&nbsp;</div>
842     <div id="progressIndicator">0%</div>
843 dpavlin 128 </div>
844 ravilov 140 <br/>
845 dpavlin 128
846 dpavlin 259 <div id="volumes">&nbsp;</div>
847 dpavlin 197
848 dpavlin 126 Note:
849 ravilov 140 <textarea name="note" cols="10" rows="5" id="note"></textarea>
850 dpavlin 127
851 ravilov 140 <input type="submit" id="submitBurner" value="Burn selected" name="submitBurner" />
852    
853 dpavlin 126 </div>
854 ravilov 140 <!--
855 dpavlin 127 <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
856     no debug output yet
857     </div>
858 ravilov 140 -->
859 dpavlin 4 EOF3
860 dpavlin 102 $retHTML .= q{
861 iklaric 121 <input type="hidden" value="burn" name="action">
862     <input type="hidden" value="results" name="search_results">
863     <table style="fview" border="0" cellspacing="0" cellpadding="2">
864     <tr class="tableheader">
865     <td class="tableheader">
866 dpavlin 126 <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
867 iklaric 121 </td>
868 dpavlin 217 } .
869     sort_header($param, 'Share', 'share', 'center') .
870     sort_header($param, '#', 'num', 'center') .
871     qq{
872 iklaric 121 <td align="center">Type</td>
873 dpavlin 217 } .
874     sort_header($param, 'Date', 'date', 'center') .
875     sort_header($param, 'Age/days', 'age', 'center') .
876     sort_header($param, 'Size/Mb', 'size', 'center') .
877     sort_header($param, 'gzip size/Kb', 'incsize', 'center') .
878     qq{
879 dpavlin 259 <td align="center">medias</td></tr>
880 dpavlin 58 };
881 dpavlin 4
882 dpavlin 102 my @color = (' bgcolor="#e0e0e0"', '');
883 dpavlin 31
884 dpavlin 102 my $i = 0;
885     my $host = '';
886 dpavlin 31
887 dpavlin 217 foreach my $backup ( getBackupsNotBurned($param) ) {
888 dpavlin 31
889 dpavlin 102 if ($host ne $backup->{'host'}) {
890     $i++;
891     $host = $backup->{'host'};
892     }
893 dpavlin 31 my $ftype = "";
894 dpavlin 125
895 dpavlin 145 my $checkbox_key = $backup->{'hostid'}. '_' .$backup->{'backupnum'} . '_' . $backup->{'id'};
896    
897 dpavlin 102 $retHTML .=
898 dpavlin 125 '<tr' . $color[$i %2 ] . '>
899     <td class="fview">';
900 dpavlin 145
901 dpavlin 161 if (($backup->{'inc_size'} || 0) > 0) {
902 dpavlin 125 $retHTML .= '
903 dpavlin 145 <input type="checkbox" name="fcb' . $checkbox_key . '" value="' . $checkbox_key . '" onClick="sumiraj(this);">';
904 dpavlin 125 }
905 dpavlin 145
906 dpavlin 259 my $img_url = $Conf{CgiImageDirURL};
907    
908 dpavlin 125 $retHTML .=
909     '</td>' .
910 dpavlin 102 '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
911     '<td align="center">' . $backup->{'backupnum'} . '</td>' .
912     '<td align="center">' . $backup->{'type'} . '</td>' .
913     '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
914     '<td align="center">' . $backup->{'age'} . '</td>' .
915     '<td align="right">' . $backup->{'size'} . '</td>' .
916 dpavlin 161 '<td align="right">' . $backup->{'inc_size'} .
917 dpavlin 259 '<input type="hidden" id="fss'.$checkbox_key .'" value="'. $backup->{'inc_size_calc'} .'"></td>' .
918     '<input type="hidden" id="prt'.$checkbox_key .'" value="'. $backup->{'volumes'} .'"></td>' .
919     '<td align="left">' . ( qq{<img src="$img_url/icon-cd.gif" alt="media">} x $backup->{volumes} ) . '</td>' .
920 dpavlin 125
921 dpavlin 102 "</tr>\n";
922 dpavlin 4 }
923 dpavlin 31
924     $retHTML .= "</table>";
925 dpavlin 102 $retHTML .= "</form>";
926 dpavlin 4
927 dpavlin 31 return $retHTML;
928     }
929 dpavlin 4
930 dpavlin 86 sub displayGrid($) {
931     my ($param) = @_;
932 dpavlin 83
933     my $offset = $param->{'offset'};
934     my $hilite = $param->{'search_filename'};
935    
936 dpavlin 17 my $retHTML = "";
937    
938 dpavlin 55 my $start_t = time();
939    
940 dpavlin 86 my ($results, $files);
941 dpavlin 88 if ($param->{'use_hest'} && length($hilite) > 0) {
942 dpavlin 87 ($results, $files) = getFilesHyperEstraier($param);
943 dpavlin 86 } else {
944 dpavlin 87 ($results, $files) = getFiles($param);
945 dpavlin 86 }
946 dpavlin 31
947 dpavlin 55 my $dur_t = time() - $start_t;
948     my $dur = sprintf("%0.4fs", $dur_t);
949    
950 dpavlin 31 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
951    
952 dpavlin 59 if ($results <= 0) {
953     $retHTML .= qq{
954     <p style="color: red;">No results found...</p>
955     };
956     return $retHTML;
957     } else {
958     # DEBUG
959     #use Data::Dumper;
960     #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
961     }
962    
963    
964 dpavlin 17 $retHTML .= qq{
965 dpavlin 79 <div>
966     Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
967     </div>
968     <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
969     <tr class="fviewheader">
970 dpavlin 87 <td></td>
971 dpavlin 211 };
972    
973 dpavlin 217 sub sort_header($$$$) {
974     my ($param, $display, $name, $align) = @_;
975 dpavlin 211
976 dpavlin 229 my ($sort_what, $sort_direction) = split(/_/,$param->{'sort'},2);
977 dpavlin 211
978 dpavlin 217 my $old_sort = $param->{'sort'};
979    
980     my $html = qq{<td align="$align"};
981 dpavlin 229 my $arrow = '';
982    
983 dpavlin 211 if (lc($sort_what) eq lc($name)) {
984 dpavlin 229 my $direction = lc($sort_direction);
985    
986     # swap direction or fallback to default
987     $direction =~ tr/ad/da/;
988     $direction = 'a' unless ($direction =~ /[ad]/);
989    
990     $param->{'sort'} = $name . '_' . $direction;
991 dpavlin 211 $html .= ' style="border: 1px solid #808080;"';
992 dpavlin 229
993     # add unicode arrow for direction
994     $arrow .= '&nbsp;';
995     $arrow .= $direction eq 'a' ? '&#9650;'
996     : $direction eq 'd' ? '&#9660;'
997     : ''
998     ;
999    
1000 dpavlin 211 } else {
1001     $param->{'sort'} = $name . '_a';
1002     }
1003 dpavlin 229
1004     $html .= '><a href="' . page_uri($param) . '">' . $display . '</a>' . $arrow . '</td>';
1005 dpavlin 217 $param->{'sort'} = $old_sort;
1006    
1007 dpavlin 211 return $html;
1008     }
1009    
1010     $retHTML .=
1011 dpavlin 217 sort_header($param, 'Share', 'share', 'center') .
1012     sort_header($param, 'Type and Name', 'path', 'center') .
1013     sort_header($param, '#', 'num', 'center') .
1014     sort_header($param, 'Size', 'size', 'center') .
1015     sort_header($param, 'Date', 'date', 'center');
1016 dpavlin 211
1017     $retHTML .= qq{
1018 dpavlin 79 <td align="center">Media</td>
1019 dpavlin 17 </tr>
1020     };
1021 dpavlin 31
1022 dpavlin 17 my $file;
1023 dpavlin 4
1024 dpavlin 17 sub hilite_html($$) {
1025     my ($html, $search) = @_;
1026     $html =~ s#($search)#<b>$1</b>#gis;
1027     return $html;
1028 dpavlin 4 }
1029 dpavlin 9
1030 dpavlin 26 sub restore_link($$$$$$) {
1031     my $type = shift;
1032     my $action = 'RestoreFile';
1033     $action = 'browse' if (lc($type) eq 'dir');
1034     return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
1035     }
1036    
1037 dpavlin 209 my $sth_archived;
1038     my %archived_cache;
1039    
1040     sub check_archived($$$) {
1041     my ($host, $share, $num) = @_;
1042    
1043     if (my $html = $archived_cache{"$host $share $num"}) {
1044     return $html;
1045     }
1046    
1047     $sth_archived ||= $dbh->prepare(qq{
1048     select
1049     dvd_nr, note,
1050     count(archive_burned.copy) as copies
1051     from archive
1052     inner join archive_burned on archive_burned.archive_id = archive.id
1053     inner join archive_backup on archive.id = archive_backup.archive_id
1054     inner join backups on backups.id = archive_backup.backup_id
1055     inner join hosts on hosts.id = backups.hostid
1056     inner join shares on shares.id = backups.shareid
1057     where hosts.name = ? and shares.name = ? and backups.num = ?
1058     group by dvd_nr, note
1059     });
1060    
1061     my @mediums;
1062    
1063     $sth_archived->execute($host, $share, $num);
1064     while (my $row = $sth_archived->fetchrow_hashref()) {
1065     push @mediums, '<abbr title="' .
1066     $row->{'note'} .
1067     ' [' . $row->{'copies'} . ']' .
1068     '">' .$row->{'dvd_nr'} .
1069     '</abbr>';
1070     }
1071    
1072     my $html = join(", ",@mediums);
1073     $archived_cache{"$host $share $num"} = $html;
1074     return $html;
1075     }
1076    
1077 dpavlin 87 my $i = $offset * $on_page;
1078    
1079 dpavlin 31 foreach $file (@{ $files }) {
1080 dpavlin 87 $i++;
1081    
1082 dpavlin 24 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
1083 dpavlin 79 $retHTML .= qq{<tr class="fviewborder">};
1084 dpavlin 9
1085 dpavlin 88 $retHTML .= qq{<td class="fviewborder">$i</td>};
1086 dpavlin 87
1087 dpavlin 79 $retHTML .=
1088 dpavlin 86 qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
1089     qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
1090     qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
1091 dpavlin 79 qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
1092     qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
1093 dpavlin 209 qq{<td class="fviewborder">} . check_archived( $file->{'hname'}, $file->{'sname'}, $file->{'backupnum'} ) . qq{</td>};
1094 dpavlin 9
1095 dpavlin 17 $retHTML .= "</tr>";
1096     }
1097     $retHTML .= "</table>";
1098    
1099 dpavlin 31 # all variables which has to be transfered
1100     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/) {
1101     $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
1102     }
1103 dpavlin 17
1104 dpavlin 31 my $del = '';
1105     my $max_page = int( $results / $on_page );
1106     my $page = 0;
1107    
1108 dpavlin 211 sub page_uri($) {
1109     my $param = shift || die "no param?";
1110 dpavlin 31
1111 dpavlin 211 my $uri = $MyURL;
1112 dpavlin 85 my $del = '?';
1113     foreach my $k (keys %{ $param }) {
1114     if ($param->{$k}) {
1115 dpavlin 211 $uri .= $del . $k . '=' . ${EscURI( $param->{$k} )};
1116 dpavlin 85 $del = '&';
1117     }
1118     }
1119 dpavlin 211 return $uri;
1120 dpavlin 85 }
1121    
1122 dpavlin 211 sub page_link($$$) {
1123     my ($param,$page,$display) = @_;
1124    
1125     $param->{'offset'} = $page if (defined($page));
1126    
1127     my $html = '<a href = "' . page_uri($param) . '">' . $display . '</a>';
1128     }
1129    
1130 dpavlin 31 $retHTML .= '<div style="text-align: center;">';
1131    
1132     if ($offset > 0) {
1133 dpavlin 85 $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
1134 dpavlin 31 }
1135    
1136     while ($page <= $max_page) {
1137     if ($page == $offset) {
1138     $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
1139     } else {
1140 dpavlin 85 $retHTML .= $del . page_link($param, $page, $page + 1);
1141 dpavlin 17 }
1142 dpavlin 31
1143     if ($page < $offset - $pager_pages && $page != 0) {
1144     $retHTML .= " ... ";
1145     $page = $offset - $pager_pages;
1146     $del = '';
1147     } elsif ($page > $offset + $pager_pages && $page != $max_page) {
1148     $retHTML .= " ... ";
1149     $page = $max_page;
1150     $del = '';
1151     } else {
1152     $del = ' | ';
1153     $page++;
1154     }
1155 dpavlin 17 }
1156    
1157 dpavlin 31 if ($offset < $max_page) {
1158 dpavlin 85 $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
1159 dpavlin 31 }
1160    
1161     $retHTML .= "</div>";
1162    
1163 dpavlin 17 return $retHTML;
1164     }
1165 dpavlin 4
1166     1;

  ViewVC Help
Powered by ViewVC 1.1.26