/[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

Contents of /trunk/lib/BackupPC/SearchLib.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 143 - (show annotations)
Fri Oct 7 09:36:10 2005 UTC (18 years, 6 months ago) by iklaric
File size: 21461 byte(s)
 r155@klaxLaptop:  klax | 2005-10-07 11:36:01 +0200
 added sub getGzipSize() in SearchLib.pm

1 #!/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 use DateTime;
9 use vars qw(%In $MyURL);
10 use Time::HiRes qw/time/;
11
12 my $on_page = 100;
13 my $pager_pages = 10;
14
15 my $dsn = $Conf{SearchDSN};
16 my $db_user = $Conf{SearchUser} || '';
17
18 my $hest_index_path = $Conf{HyperEstraierIndex};
19
20 my $dbh;
21
22 sub get_dbh {
23 $dbh ||= DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
24 return $dbh;
25 }
26
27 sub getUnits() {
28 my @ret;
29
30 my $dbh = get_dbh();
31 my $sth = $dbh->prepare(qq{
32 SELECT
33 shares.id as id,
34 hosts.name || ':' || shares.name as share
35 FROM shares
36 JOIN hosts on hostid = hosts.id
37 ORDER BY share
38 } );
39 $sth->execute();
40 push @ret, { 'id' => '', 'share' => '-'}; # dummy any
41
42 while ( my $row = $sth->fetchrow_hashref() ) {
43 push @ret, $row;
44 }
45 return @ret;
46 }
47
48 sub epoch_to_iso {
49 my $t = shift || return;
50 my $iso = BackupPC::Lib::timeStamp(undef, $t);
51 $iso =~ s/\s/ /g;
52 return $iso;
53 }
54
55 sub dates_from_form($) {
56 my $param = shift || return;
57
58 sub mk_epoch_date($$) {
59 my ($name,$suffix) = @_;
60
61 my $yyyy = $param->{ $name . '_year_' . $suffix} || return undef;
62 my $mm .= $param->{ $name . '_month_' . $suffix} ||
63 ( $suffix eq 'from' ? 1 : 12);
64 my $dd .= $param->{ $name . '_day_' . $suffix} ||
65 ( $suffix eq 'from' ? 1 : 31);
66
67 $yyyy =~ s/\D//g;
68 $mm =~ s/\D//g;
69 $dd =~ s/\D//g;
70
71 my $dt = new DateTime(
72 year => $yyyy,
73 month => $mm,
74 day => $dd
75 );
76 print STDERR "mk_epoch_date($name,$suffix) [$yyyy-$mm-$dd] = " . $dt->ymd . " " . $dt->hms . "\n";
77 return $dt->epoch || 'NULL';
78 }
79
80 my @ret = (
81 mk_epoch_date('search_backup', 'from'),
82 mk_epoch_date('search_backup', 'to'),
83 mk_epoch_date('search', 'from'),
84 mk_epoch_date('search', 'to'),
85 );
86
87 return @ret;
88
89 }
90
91
92 sub getWhere($) {
93 my $param = shift || return;
94
95 my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
96
97 my @conditions;
98 push @conditions, qq{ backups.date >= $backup_from } if ($backup_from);
99 push @conditions, qq{ backups.date <= $backup_to } if ($backup_to);
100 push @conditions, qq{ files.date >= $files_from } if ($files_from);
101 push @conditions, qq{ files.date <= $files_to } if ($files_to);
102
103 print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:" . join(" | ",@conditions);
104
105 push( @conditions, ' files.shareid = ' . $param->{'search_share'} ) if ($param->{'search_share'});
106 push (@conditions, " upper(files.path) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});
107
108 return join(" and ", @conditions);
109 }
110
111
112 sub getFiles($) {
113 my ($param) = @_;
114
115 my $offset = $param->{'offset'} || 0;
116 $offset *= $on_page;
117
118 my $dbh = get_dbh();
119
120 my $sql_cols = qq{
121 files.id AS fid,
122 hosts.name AS hname,
123 shares.name AS sname,
124 files.backupnum AS backupnum,
125 files.path AS filepath,
126 files.date AS date,
127 files.type AS type,
128 files.size AS size
129 };
130
131 my $sql_from = qq{
132 FROM files
133 INNER JOIN shares ON files.shareID=shares.ID
134 INNER JOIN hosts ON hosts.ID = shares.hostID
135 INNER JOIN backups ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = files.shareID
136 };
137
138 my $sql_where;
139 my $where = getWhere($param);
140 $sql_where = " WHERE ". $where if ($where);
141
142 my $sql_order = qq{
143 ORDER BY files.date
144 LIMIT $on_page
145 OFFSET ?
146 };
147
148 my $sql_count = qq{ select count(files.id) $sql_from $sql_where };
149 my $sql_results = qq{ select $sql_cols $sql_from $sql_where $sql_order };
150
151 my $sth = $dbh->prepare($sql_count);
152 $sth->execute();
153 my ($results) = $sth->fetchrow_array();
154
155 $sth = $dbh->prepare($sql_results);
156 $sth->execute( $offset );
157
158 if ($sth->rows != $results) {
159 my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
160 $bug =~ s/\s+/ /gs;
161 print STDERR "$bug\n";
162 }
163
164 my @ret;
165
166 while (my $row = $sth->fetchrow_hashref()) {
167 push @ret, $row;
168 }
169
170 $sth->finish();
171 return ($results, \@ret);
172 }
173
174 sub getHyperEstraier_url($) {
175 my ($use_hest) = @_;
176
177 return unless $use_hest;
178
179 use HyperEstraier;
180 my ($index_path, $index_node_url);
181
182 if ($use_hest =~ m#^http://#) {
183 $index_node_url = $use_hest;
184 } else {
185 $index_path = $TopDir . '/' . $index_path;
186 $index_path =~ s#//#/#g;
187 }
188 return ($index_path, $index_node_url);
189 }
190
191 sub getFilesHyperEstraier($) {
192 my ($param) = @_;
193
194 my $offset = $param->{'offset'} || 0;
195 $offset *= $on_page;
196
197 die "no index_path?" unless ($hest_index_path);
198
199 use HyperEstraier;
200
201 my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path);
202
203 # open the database
204 my $db;
205 if ($index_path) {
206 $db = HyperEstraier::Database->new();
207 $db->open($index_path, $HyperEstraier::ESTDBREADER);
208 } elsif ($index_node_url) {
209 $db ||= HyperEstraier::Node->new($index_node_url);
210 $db->set_auth('admin', 'admin');
211 } else {
212 die "BUG: unimplemented";
213 }
214
215 # create a search condition object
216 my $cond = HyperEstraier::Condition->new();
217
218 my $q = $param->{'search_filename'};
219 my $shareid = $param->{'search_share'};
220
221 if (length($q) > 0) {
222 # exact match
223 $cond->add_attr("filepath ISTRINC $q");
224
225 $q =~ s/(.)/$1 /g;
226 # set the search phrase to the search condition object
227 $cond->set_phrase($q);
228 }
229
230 my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
231
232 $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
233 $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);
234
235 $cond->add_attr("date NUMGE $files_from") if ($files_from);
236 $cond->add_attr("date NUMLE $files_to") if ($files_to);
237
238 $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
239
240 # $cond->set_max( $offset + $on_page );
241 $cond->set_options( $HyperEstraier::Condition::SURE );
242 $cond->set_order( 'date NUMA' );
243
244 # get the result of search
245 my @res;
246 my ($result, $hits);
247
248 if ($index_path) {
249 $result = $db->search($cond, 0);
250 $hits = $result->size;
251 } elsif ($index_node_url) {
252 $result = $db->search($cond, 0);
253 $hits = $result->doc_num;
254 } else {
255 die "BUG: unimplemented";
256 }
257
258 # for each document in result
259 for my $i ($offset .. ($offset + $on_page - 1)) {
260 last if ($i >= $hits);
261
262 my $doc;
263 if ($index_path) {
264 my $id = $result->get($i);
265 $doc = $db->get_doc($id, 0);
266 } elsif ($index_node_url) {
267 $doc = $result->get_doc($i);
268 } else {
269 die "BUG: unimplemented";
270 }
271
272 my $row;
273 foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {
274 $row->{$c} = $doc->attr($c);
275 }
276 push @res, $row;
277 }
278
279 return ($hits, \@res);
280 }
281
282 sub getGzipName($$$)
283 {
284 my ($host, $share, $backupnum) = @_;
285 my $ret = $Conf{GzipSchema};
286
287 $share =~ s/\//_/g;
288 $ret =~ s/\\h/$host/ge;
289 $ret =~ s/\\s/$share/ge;
290 $ret =~ s/\\n/$backupnum/ge;
291
292 return $ret;
293
294 }
295
296 sub getGzipSize($$)
297 {
298 my ($hostID, $backupNum) = @_;
299 my $ret;
300 my $sql;
301 my $dbh = get_dbh();
302
303 $sql = q{
304 SELECT hosts.name as host,
305 shares.name as share,
306 backups.num as backupnum
307 FROM hosts, backups, shares
308 WHERE shares.id=backups.shareid AND
309 hosts.id =backups.hostid AND
310 hosts.id=? AND
311 backups.num=?;
312 };
313 my $sth = $dbh->prepare($sql);
314 $sth->execute($hostID, $backupNUM);
315 my $row = $res->fetchrow_hashref();
316
317 my (undef,undef,undef,undef,undef,undef,undef,$ret,undef,undef,undef,undef,undef) =
318 stat( $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.
319 getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'}));
320
321 return $ret;
322 }
323
324 sub getBackupsNotBurned() {
325
326 my $dbh = get_dbh();
327
328 my $sql = q{
329 SELECT
330 backups.hostID AS hostID,
331 hosts.name AS host,
332 shares.name AS share,
333 backups.id AS backupnum,
334 backups.type AS type,
335 backups.date AS date,
336 backups.size AS size
337 FROM backups
338 INNER JOIN shares ON backups.shareID=shares.ID
339 INNER JOIN hosts ON backups.hostID = hosts.ID
340 LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
341 WHERE backups.size > 0 AND archive_backup.backup_id IS NULL
342 GROUP BY
343 backups.hostID,
344 hosts.name,
345 shares.name,
346 backups.num,
347 backups.shareid,
348 backups.id,
349 backups.type,
350 backups.date,
351 backups.size
352 ORDER BY backups.date
353 };
354 my $sth = $dbh->prepare( $sql );
355 my @ret;
356 $sth->execute();
357
358 while ( my $row = $sth->fetchrow_hashref() ) {
359 $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
360 $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
361 my (undef,undef,undef,undef,undef,undef,undef,$fs_size,undef,undef,undef,undef,undef) =
362 stat( $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.
363 getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'}));
364 $row->{'fs_size'} = $fs_size;
365 push @ret, $row;
366 }
367
368 return @ret;
369 }
370
371 sub displayBackupsGrid() {
372
373 my $retHTML .= q{
374 <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
375 };
376
377 $retHTML .= <<'EOF3';
378 <style type="text/css">
379 <!--
380 DIV#fixedBox {
381 position: absolute;
382 top: 50em;
383 left: -24%;
384 padding: 0.5em;
385 width: 20%;
386 background-color: #E0F0E0;
387 border: 1px solid #00C000;
388 }
389
390 DIV#fixedBox, DIV#fixedBox INPUT, DIV#fixedBox TEXTAREA {
391 font-size: 10pt;
392 }
393
394 FORM>DIV#fixedBox {
395 position: fixed !important;
396 left: 0.5em !important;
397 top: auto !important;
398 bottom: 1em !important;
399 width: 15% !important;
400 }
401
402 DIV#fixedBox INPUT[type=text], DIV#fixedBox TEXTAREA {
403 border: 1px solid #00C000;
404 }
405
406 DIV#fixedBox #note {
407 display: block;
408 width: 100%;
409 }
410
411 DIV#fixedBox #submitBurner {
412 display: block;
413 width: 100%;
414 margin-top: 0.5em;
415 cursor: pointer;
416 }
417
418 * HTML {
419 overflow-y: hidden;
420 }
421
422 * HTML BODY {
423 overflow-y: auto;
424 height: 100%;
425 font-size: 100%;
426 }
427
428 * HTML DIV#fixedBox {
429 position: absolute;
430 }
431
432 #mContainer, #gradient, #mask, #progressIndicator {
433 display: block;
434 width: 100%;
435 font-size: 10pt;
436 font-weight: bold;
437 text-align: center;
438 vertical-align: middle;
439 padding: 1px;
440 }
441
442 #gradient, #mask, #progressIndicator {
443 left: 0;
444 border-width: 1px;
445 border-style: solid;
446 border-color: #000000;
447 color: #404040;
448 margin: 0.4em;
449 position: absolute;
450 margin-left: -1px;
451 margin-top: -1px;
452 margin-bottom: -1px;
453 overflow: hidden;
454 }
455
456 #mContainer {
457 display: block;
458 position: relative;
459 padding: 0px;
460 margin-top: 0.4em;
461 margin-bottom: 0.5em;
462 }
463
464 #gradient {
465 z-index: 1;
466 background-color: #FFFF00;
467 }
468
469 #mask {
470 z-index: 2;
471 background-color: #FFFFFF;
472 }
473
474 #progressIndicator {
475 z-index: 3;
476 background-color: transparent;
477 }
478 -->
479 </style>
480 <script type="text/javascript">
481 <!--
482
483 var debug_div = null;
484 var media_size = 4400 * 1024;
485
486 function debug(msg) {
487 // return; // Disable debugging
488
489 if (! debug_div) debug_div = document.getElementById('debug');
490
491 // this will create debug div if it doesn't exist.
492 if (! debug_div) {
493 debug_div = document.createElement('div');
494 if (document.body) document.body.appendChild(debug_div);
495 else debug_div = null;
496 }
497 if (debug_div) {
498 debug_div.appendChild(document.createTextNode(msg));
499 debug_div.appendChild(document.createElement("br"));
500 }
501 }
502
503
504 var element_id_cache = Array();
505
506 function element_id(name,element) {
507 if (! element_id_cache[name]) {
508 element_id_cache[name] = self.document.getElementById(name);
509 }
510 return element_id_cache[name];
511 }
512
513 function checkAll(location) {
514 var f = element_id('forma') || null;
515 if (!f) return false;
516
517 var len = f.elements.length;
518 var check_all = element_id('allFiles');
519 var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
520
521 for (var i = 0; i < len; i++) {
522 var e = f.elements[i];
523 if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
524 if (check_all.checked) {
525 if (e.checked) continue;
526 var el = element_id("fss" + e.name.substr(3));
527 var size = parseInt(el.value) || 0;
528 debug('suma: '+suma+' size: '+size);
529 if ((suma + size) < media_size) {
530 suma += size;
531 e.checked = true;
532 } else {
533 break;
534 }
535 } else {
536 e.checked = false;
537 }
538 }
539 }
540 update_sum(suma);
541 }
542
543 function update_sum(suma) {
544 element_id('forma').elements['totalsize'].value = suma;
545 pbar_set(suma, media_size);
546 debug('total size: ' + suma);
547 }
548
549 function sumiraj(e) {
550 var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
551 var len = element_id('forma').elements.length;
552 if (e) {
553 var size = parseInt( element_id("fss" + e.name.substr(3)).value);
554 if (e.checked) {
555 suma += size;
556 } else {
557 suma -= size;
558 }
559 } else {
560 suma = 0;
561 for (var i = 0; i < len; i++) {
562 var e = element_id('forma').elements[i];
563 if (e.name != 'all' && e.checked && e.name.substr(0,3) == 'fcb') {
564 var el = element_id("fss" + e.name.substr(3));
565 if (el && el.value) suma += parseInt(el.value) || 0;
566 }
567 }
568 }
569 update_sum(suma);
570 return suma;
571 }
572
573 /* progress bar */
574
575 var _pbar_width = null;
576 var _pbar_warn = 10; // change color in last 10%
577
578 function pbar_reset() {
579 element_id("mask").style.left = "0px";
580 _pbar_width = element_id("mContainer").offsetWidth - 2;
581 element_id("mask").style.width = _pbar_width + "px";
582 element_id("mask").style.display = "block";
583 element_id("progressIndicator").style.zIndex = 10;
584 element_id("progressIndicator").innerHTML = "0";
585 }
586
587 function dec2hex(d) {
588 var hch = '0123456789ABCDEF';
589 var a = d % 16;
590 var q = (d - a) / 16;
591 return hch.charAt(q) + hch.charAt(a);
592 }
593
594 function pbar_set(amount, max) {
595 debug('pbar_set('+amount+', '+max+')');
596
597 if (_pbar_width == null) {
598 var _mc = element_id("mContainer");
599 if (_pbar_width == null) _pbar_width = parseInt(_mc.offsetWidth ? (_mc.offsetWidth - 2) : 0) || null;
600 if (_pbar_width == null) _pbar_width = parseInt(_mc.clientWidth ? (_mc.clientWidth + 2) : 0) || null;
601 if (_pbar_width == null) _pbar_width = 0;
602 }
603
604 var pcnt = Math.floor(amount * 100 / max);
605 var p90 = 100 - _pbar_warn;
606 var pcol = pcnt - p90;
607 if (Math.round(pcnt) <= 100) {
608 if (pcol < 0) pcol = 0;
609 var e = element_id("submitBurner");
610 debug('enable_button');
611 e.disabled = false;
612 var a = e.getAttributeNode('disabled') || null;
613 if (a) e.removeAttributeNode(a);
614 } else {
615 debug('disable button');
616 pcol = _pbar_warn;
617 var e = element_id("submitBurner");
618 if (!e.disabled) e.disabled = true;
619 }
620 var col_g = Math.floor((_pbar_warn - pcol) * 255 / _pbar_warn);
621 var col = '#FF' + dec2hex(col_g) + '00';
622
623 //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col);
624 element_id("gradient").style.backgroundColor = col;
625
626 element_id("progressIndicator").innerHTML = pcnt + '%';
627 //element_id("progressIndicator").innerHTML = amount;
628
629 element_id("mask").style.clip = 'rect(' + Array(
630 '0px',
631 element_id("mask").offsetWidth + 'px',
632 element_id("mask").offsetHeight + 'px',
633 Math.round(_pbar_width * amount / max) + 'px'
634 ).join(' ') + ')';
635 }
636
637 if (!self.body) self.body = new Object();
638 self.onload = self.document.onload = self.body.onload = function() {
639 //pbar_reset();
640 sumiraj();
641 };
642
643 // -->
644 </script>
645 <div id="fixedBox">
646
647 Size: <input type="text" name="totalsize" size="7" readonly="readonly" style="text-align:right;" value="0" /> kB
648
649 <div id="mContainer">
650 <div id="gradient">&nbsp;</div>
651 <div id="mask">&nbsp;</div>
652 <div id="progressIndicator">0%</div>
653 </div>
654 <br/>
655
656 Note:
657 <textarea name="note" cols="10" rows="5" id="note"></textarea>
658
659 <input type="submit" id="submitBurner" value="Burn selected" name="submitBurner" />
660
661 </div>
662 <!--
663 <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
664 no debug output yet
665 </div>
666 -->
667 EOF3
668 $retHTML .= q{
669 <input type="hidden" value="burn" name="action">
670 <input type="hidden" value="results" name="search_results">
671 <table style="fview" border="0" cellspacing="0" cellpadding="2">
672 <tr class="tableheader">
673 <td class="tableheader">
674 <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
675 </td>
676 <td align="center">Share</td>
677 <td align="center">Backup no</td>
678 <td align="center">Type</td>
679 <td align="center">date</td>
680 <td align="center">age/days</td>
681 <td align="center">size/MB</td>
682 <td align="center">gzip size</td>
683 </tr>
684
685 };
686
687 my @color = (' bgcolor="#e0e0e0"', '');
688
689 my $i = 0;
690 my $host = '';
691
692 foreach my $backup ( getBackupsNotBurned() ) {
693
694 if ($host ne $backup->{'host'}) {
695 $i++;
696 $host = $backup->{'host'};
697 }
698 my $ftype = "";
699
700 $retHTML .=
701 '<tr' . $color[$i %2 ] . '>
702 <td class="fview">';
703 # FIXME
704 $backup->{'fs_size'} = int($backup->{'size'} * 1024);
705 if (($backup->{'fs_size'} || 0) > 0) {
706 $retHTML .= '
707 <input type="checkbox" name="fcb' .
708 $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
709 '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
710 '" onClick="sumiraj(this);">';
711 }
712 $retHTML .=
713 '</td>' .
714 '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
715 '<td align="center">' . $backup->{'backupnum'} . '</td>' .
716 '<td align="center">' . $backup->{'type'} . '</td>' .
717 '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
718 '<td align="center">' . $backup->{'age'} . '</td>' .
719 '<td align="right">' . $backup->{'size'} . '</td>' .
720 '<td align="right">' . $backup->{'fs_size'} .
721 '<input type="hidden" iD="fss'.$backup->{'hostid'}.'_'.$backup->{'backupnum'} . '" value="'. $backup->{'fs_size'} .'"></td>' .
722
723 "</tr>\n";
724 }
725
726 $retHTML .= "</table>";
727 $retHTML .= "</form>";
728
729 return $retHTML;
730 }
731
732 sub displayGrid($) {
733 my ($param) = @_;
734
735 my $offset = $param->{'offset'};
736 my $hilite = $param->{'search_filename'};
737
738 my $retHTML = "";
739
740 my $start_t = time();
741
742 my ($results, $files);
743 if ($param->{'use_hest'} && length($hilite) > 0) {
744 ($results, $files) = getFilesHyperEstraier($param);
745 } else {
746 ($results, $files) = getFiles($param);
747 }
748
749 my $dur_t = time() - $start_t;
750 my $dur = sprintf("%0.4fs", $dur_t);
751
752 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
753
754 if ($results <= 0) {
755 $retHTML .= qq{
756 <p style="color: red;">No results found...</p>
757 };
758 return $retHTML;
759 } else {
760 # DEBUG
761 #use Data::Dumper;
762 #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
763 }
764
765
766 $retHTML .= qq{
767 <div>
768 Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
769 </div>
770 <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
771 <tr class="fviewheader">
772 <td></td>
773 <td align="center">Share</td>
774 <td align="center">Type and Name</td>
775 <td align="center">#</td>
776 <td align="center">Size</td>
777 <td align="center">Date</td>
778 <td align="center">Media</td>
779 </tr>
780 };
781
782 my $file;
783
784 sub hilite_html($$) {
785 my ($html, $search) = @_;
786 $html =~ s#($search)#<b>$1</b>#gis;
787 return $html;
788 }
789
790 sub restore_link($$$$$$) {
791 my $type = shift;
792 my $action = 'RestoreFile';
793 $action = 'browse' if (lc($type) eq 'dir');
794 return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
795 }
796
797 my $i = $offset * $on_page;
798
799 foreach $file (@{ $files }) {
800 $i++;
801
802 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
803 $retHTML .= qq{<tr class="fviewborder">};
804
805 $retHTML .= qq{<td class="fviewborder">$i</td>};
806
807 $retHTML .=
808 qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
809 qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
810 qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
811 qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
812 qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
813 qq{<td class="fviewborder">} . '?' . qq{</td>};
814
815 $retHTML .= "</tr>";
816 }
817 $retHTML .= "</table>";
818
819 # all variables which has to be transfered
820 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/) {
821 $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
822 }
823
824 my $del = '';
825 my $max_page = int( $results / $on_page );
826 my $page = 0;
827
828 sub page_link($$$) {
829 my ($param,$page,$display) = @_;
830
831 $param->{'offset'} = $page;
832
833 my $html = '<a href = "' . $MyURL;
834 my $del = '?';
835 foreach my $k (keys %{ $param }) {
836 if ($param->{$k}) {
837 $html .= $del . $k . '=' . ${EscURI( $param->{$k} )};
838 $del = '&';
839 }
840 }
841 $html .= '">' . $display . '</a>';
842 }
843
844 $retHTML .= '<div style="text-align: center;">';
845
846 if ($offset > 0) {
847 $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
848 }
849
850 while ($page <= $max_page) {
851 if ($page == $offset) {
852 $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
853 } else {
854 $retHTML .= $del . page_link($param, $page, $page + 1);
855 }
856
857 if ($page < $offset - $pager_pages && $page != 0) {
858 $retHTML .= " ... ";
859 $page = $offset - $pager_pages;
860 $del = '';
861 } elsif ($page > $offset + $pager_pages && $page != $max_page) {
862 $retHTML .= " ... ";
863 $page = $max_page;
864 $del = '';
865 } else {
866 $del = ' | ';
867 $page++;
868 }
869 }
870
871 if ($offset < $max_page) {
872 $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
873 }
874
875 $retHTML .= "</div>";
876
877 return $retHTML;
878 }
879
880 1;

  ViewVC Help
Powered by ViewVC 1.1.26