/[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 225 - (hide annotations)
Mon Oct 24 14:02:00 2005 UTC (18 years, 7 months ago) by dpavlin
File size: 26747 byte(s)
sort by share in burn sort by host *AND* share (not just share)

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

  ViewVC Help
Powered by ViewVC 1.1.26