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

  ViewVC Help
Powered by ViewVC 1.1.26