/[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 109 - (hide annotations)
Thu Sep 1 18:30:51 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 13584 byte(s)
added Ivan's changes to show increment sizes and other minor fixes
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 dpavlin 4
12 dpavlin 31 my $on_page = 100;
13     my $pager_pages = 10;
14    
15 dpavlin 51 my $dsn = $Conf{SearchDSN};
16     my $db_user = $Conf{SearchUser} || '';
17    
18 dpavlin 86 my $index_path = $Conf{HyperEstraierIndex};
19     if ($index_path) {
20     $index_path = $TopDir . '/' . $index_path;
21     $index_path =~ s#//#/#g;
22     }
23    
24 dpavlin 84 my $dbh;
25    
26     sub get_dbh {
27     $dbh ||= DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
28     return $dbh;
29     }
30    
31 dpavlin 4 sub getUnits() {
32 dpavlin 59 my @ret;
33    
34 dpavlin 84 my $dbh = get_dbh();
35 dpavlin 86 my $sth = $dbh->prepare(qq{
36     SELECT
37     shares.id as id,
38     hosts.name || ':' || shares.name as share
39     FROM shares
40     JOIN hosts on hostid = hosts.id
41     ORDER BY share
42     } );
43 dpavlin 59 $sth->execute();
44     push @ret, { 'id' => '', 'share' => '-'}; # dummy any
45    
46     while ( my $row = $sth->fetchrow_hashref() ) {
47     push @ret, $row;
48     }
49     return @ret;
50 dpavlin 4 }
51    
52 dpavlin 51 sub epoch_to_iso {
53     my $t = shift || return;
54 dpavlin 86 my $iso = BackupPC::Lib::timeStamp(undef, $t);
55 dpavlin 79 $iso =~ s/\s/ /g;
56     return $iso;
57 dpavlin 51 }
58    
59 dpavlin 83 sub dates_from_form($) {
60     my $param = shift || return;
61 dpavlin 4
62 dpavlin 51 sub mk_epoch_date($$) {
63 dpavlin 19 my ($name,$suffix) = @_;
64 dpavlin 4
65 dpavlin 87 my $yyyy = $param->{ $name . '_year_' . $suffix} || return undef;
66 dpavlin 19 my $mm .= $param->{ $name . '_month_' . $suffix} ||
67     ( $suffix eq 'from' ? 1 : 12);
68     my $dd .= $param->{ $name . '_day_' . $suffix} ||
69     ( $suffix eq 'from' ? 1 : 31);
70 dpavlin 87
71     $yyyy =~ s/\D//g;
72     $mm =~ s/\D//g;
73     $dd =~ s/\D//g;
74    
75 dpavlin 51 my $dt = new DateTime(
76     year => $yyyy,
77     month => $mm,
78     day => $dd
79     );
80 dpavlin 87 print STDERR "mk_epoch_date($name,$suffix) [$yyyy-$mm-$dd] = " . $dt->ymd . " " . $dt->hms . "\n";
81 dpavlin 51 return $dt->epoch || 'NULL';
82 dpavlin 19 }
83 dpavlin 4
84 dpavlin 87 my @ret = (
85 dpavlin 83 mk_epoch_date('search_backup', 'from'),
86     mk_epoch_date('search_backup', 'to'),
87     mk_epoch_date('search', 'from'),
88     mk_epoch_date('search', 'to'),
89     );
90 dpavlin 87
91     return @ret;
92    
93 dpavlin 83 }
94    
95    
96     sub getWhere($) {
97     my $param = shift || return;
98    
99     my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
100    
101     my @conditions;
102 dpavlin 51 push @conditions, qq{ backups.date >= $backup_from } if ($backup_from);
103     push @conditions, qq{ backups.date <= $backup_to } if ($backup_to);
104     push @conditions, qq{ files.date >= $files_from } if ($files_from);
105     push @conditions, qq{ files.date <= $files_to } if ($files_to);
106 dpavlin 19
107 dpavlin 59 print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:" . join(" | ",@conditions);
108 dpavlin 83
109 dpavlin 60 push( @conditions, ' files.shareid = ' . $param->{'search_share'} ) if ($param->{'search_share'});
110 dpavlin 62 push (@conditions, " upper(files.path) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});
111 dpavlin 19
112 dpavlin 83 return join(" and ", @conditions);
113 dpavlin 4 }
114    
115 dpavlin 19
116 dpavlin 87 sub getFiles($) {
117     my ($param) = @_;
118 dpavlin 31
119 dpavlin 87 my $offset = $param->{'offset'} || 0;
120     $offset *= $on_page;
121    
122 dpavlin 84 my $dbh = get_dbh();
123 dpavlin 31
124     my $sql_cols = qq{
125     files.id AS fid,
126     hosts.name AS hname,
127     shares.name AS sname,
128 dpavlin 86 files.backupnum AS backupnum,
129 dpavlin 31 files.path AS filepath,
130 dpavlin 51 files.date AS date,
131 dpavlin 86 files.type AS type,
132 dpavlin 87 files.size AS size
133 dpavlin 31 };
134    
135     my $sql_from = qq{
136 dpavlin 16 FROM files
137     INNER JOIN shares ON files.shareID=shares.ID
138     INNER JOIN hosts ON hosts.ID = shares.hostID
139 dpavlin 87 INNER JOIN backups ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = files.shareID
140 dpavlin 55 };
141    
142 dpavlin 31 my $sql_where;
143 dpavlin 83 my $where = getWhere($param);
144 dpavlin 31 $sql_where = " WHERE ". $where if ($where);
145 dpavlin 4
146 dpavlin 31 my $sql_order = qq{
147 dpavlin 64 ORDER BY files.date
148 dpavlin 59 LIMIT $on_page
149     OFFSET ?
150 dpavlin 9 };
151 dpavlin 31
152 dpavlin 59 my $sql_count = qq{ select count(files.id) $sql_from $sql_where };
153 dpavlin 87 my $sql_results = qq{ select $sql_cols $sql_from $sql_where $sql_order };
154 dpavlin 59
155     my $sth = $dbh->prepare($sql_count);
156 dpavlin 31 $sth->execute();
157     my ($results) = $sth->fetchrow_array();
158    
159 dpavlin 59 $sth = $dbh->prepare($sql_results);
160 dpavlin 31 $sth->execute( $offset );
161    
162 dpavlin 59 if ($sth->rows != $results) {
163     my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
164     $bug =~ s/\s+/ /gs;
165     print STDERR "$bug\n";
166     }
167    
168 dpavlin 31 my @ret;
169 dpavlin 4
170 dpavlin 31 while (my $row = $sth->fetchrow_hashref()) {
171 dpavlin 86 push @ret, $row;
172 dpavlin 4 }
173 dpavlin 59
174 dpavlin 31 $sth->finish();
175     return ($results, \@ret);
176     }
177 dpavlin 4
178 dpavlin 87 sub getFilesHyperEstraier($) {
179     my ($param) = @_;
180 dpavlin 86
181 dpavlin 87 my $offset = $param->{'offset'} || 0;
182     $offset *= $on_page;
183    
184 dpavlin 86 die "no index_path?" unless ($index_path);
185    
186     use HyperEstraier;
187    
188     # open the database
189     my $db = HyperEstraier::Database->new();
190     $db->open($index_path, $HyperEstraier::ESTDBREADER);
191    
192     # create a search condition object
193     my $cond = HyperEstraier::Condition->new();
194    
195     my $q = $param->{'search_filename'};
196     my $shareid = $param->{'search_share'};
197    
198 dpavlin 88 if (length($q) > 0) {
199 dpavlin 91 # exact match
200     $cond->add_attr("filepath ISTRINC $q");
201    
202 dpavlin 86 $q =~ s/(.)/$1 /g;
203     # set the search phrase to the search condition object
204     $cond->set_phrase($q);
205 dpavlin 87 }
206 dpavlin 86
207 dpavlin 87 my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
208 dpavlin 86
209 dpavlin 87 $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
210     $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);
211 dpavlin 86
212 dpavlin 87 $cond->add_attr("date NUMGE $files_from") if ($files_from);
213     $cond->add_attr("date NUMLE $files_to") if ($files_to);
214 dpavlin 86
215 dpavlin 87 $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
216 dpavlin 86
217     # $cond->set_max( $offset + $on_page );
218     $cond->set_options( $HyperEstraier::Condition::SURE );
219     $cond->set_order( 'date NUMA' );
220    
221     # get the result of search
222     my $result = $db->search($cond, 0);
223    
224     my @res;
225     my $hits = $result->size;
226    
227     # for each document in result
228 dpavlin 87 for my $i ($offset .. ($offset + $on_page - 1)) {
229     last if ($i >= $hits);
230    
231 dpavlin 86 my $id = $result->get($i);
232     my $doc = $db->get_doc($id, 0);
233    
234     my $row;
235     foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {
236     $row->{$c} = $doc->attr($c);
237     }
238     push @res, $row;
239     }
240    
241     return ($hits, \@res);
242     }
243    
244 dpavlin 109 sub getGzipName($$$)
245     {
246     my ($host, $share, $backupnum) = @_;
247     my $ret = $Conf{GzipSchema};
248    
249     $share =~ s/\//_/g;
250     $ret =~ s/\\h/$host/ge;
251     $ret =~ s/\\s/$share/ge;
252     $ret =~ s/\\n/$backupnum/ge;
253    
254     return $ret;
255    
256     }
257    
258 dpavlin 51 sub getBackupsNotBurned() {
259    
260 dpavlin 84 my $dbh = get_dbh();
261 dpavlin 53 my $sql = q{
262     SELECT
263 dpavlin 66 backups.hostID AS hostid,
264 dpavlin 53 min(hosts.name) AS host,
265 dpavlin 102 min(shares.name) AS share,
266 dpavlin 86 backups.num AS backupnum,
267 dpavlin 53 min(backups.type) AS type,
268 dpavlin 66 min(backups.date) AS date,
269     min(backups.size) AS size
270 dpavlin 79 FROM files
271     INNER JOIN shares ON files.shareID=shares.ID
272     INNER JOIN hosts ON hosts.ID = shares.hostID
273 dpavlin 86 INNER JOIN backups ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = shares.ID
274 dpavlin 53 GROUP BY
275 dpavlin 102 backups.hostID, backups.num, backups.shareid
276 dpavlin 58 ORDER BY min(backups.date)
277 dpavlin 53 };
278     my $sth = $dbh->prepare( $sql );
279     my @ret;
280     $sth->execute();
281 dpavlin 4
282 dpavlin 66 while ( my $row = $sth->fetchrow_hashref() ) {
283     $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
284     $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
285 dpavlin 109 my (undef,undef,undef,undef,undef,undef,undef,$fs_size,undef,undef,undef,undef,undef) =
286     stat( $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.
287     getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'}));
288     $row->{'fs_size'} = $fs_size;
289 dpavlin 66 push @ret, $row;
290 dpavlin 4 }
291    
292 dpavlin 53 return @ret;
293     }
294 dpavlin 4
295     sub displayBackupsGrid()
296     {
297     my $retHTML = "";
298    
299 dpavlin 102 $retHTML .= <<EOF3;
300 dpavlin 4 <script language="javascript" type="text/javascript">
301     <!--
302    
303     function checkAll(location)
304     {
305     for (var i=0;i<document.forma.elements.length;i++)
306     {
307     var e = document.forma.elements[i];
308     if ((e.checked || !e.checked) && e.name != \'all\') {
309     if (eval("document.forma."+location+".checked")) {
310     e.checked = true;
311     } else {
312     e.checked = false;
313     }
314     }
315     }
316     }
317     //-->
318     </script>
319     EOF3
320 dpavlin 102 $retHTML .= q{
321     <form name="forma" method="GET" action="$MyURL?action=burn">
322     <input type="hidden" value="burn" name="action">
323     <input type="hidden" value="results" name="search_results">
324     <table style="fview" border="0" cellspacing="0" cellpadding="2">
325 dpavlin 79 <tr class="tableheader">
326 dpavlin 102 <td class="tableheader">
327     <input type="checkbox" name="allFiles" onClick="checkAll('allFiles');">
328     </td>
329     <td align="center">Share</td>
330 dpavlin 79 <td align="center">Backup no</td>
331     <td align="center">Type</td>
332     <td align="center">date</td>
333     <td align="center">age/days</td>
334     <td align="center">size/MB</td>
335 dpavlin 109 <td align="center">gzip size</td>
336 dpavlin 58 </tr>
337 dpavlin 102
338     <tr><td colspan=7 style="tableheader">
339     <input type="submit" value="Burn selected backups on medium" name="submitBurner">
340     </td></tr>
341 dpavlin 58 };
342 dpavlin 4
343 dpavlin 102 my @color = (' bgcolor="#e0e0e0"', '');
344 dpavlin 31
345 dpavlin 102 my $i = 0;
346     my $host = '';
347 dpavlin 31
348 dpavlin 102 foreach my $backup ( getBackupsNotBurned() ) {
349 dpavlin 31
350 dpavlin 102 if ($host ne $backup->{'host'}) {
351     $i++;
352     $host = $backup->{'host'};
353     }
354 dpavlin 31 my $ftype = "";
355 dpavlin 4
356 dpavlin 102 $retHTML .= "<tr" . $color[$i %2 ] . ">";
357     $retHTML .= '<td class="fview"><input type="checkbox" name="fcb' .
358 dpavlin 86 $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
359     '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
360 dpavlin 58 '"></td>';
361 dpavlin 4
362 dpavlin 102 $retHTML .=
363     '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
364     '<td align="center">' . $backup->{'backupnum'} . '</td>' .
365     '<td align="center">' . $backup->{'type'} . '</td>' .
366     '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
367     '<td align="center">' . $backup->{'age'} . '</td>' .
368     '<td align="right">' . $backup->{'size'} . '</td>' .
369 dpavlin 109 '<td align="right">' . $backup->{'fs_size'} .'</td>' .
370 dpavlin 102 "</tr>\n";
371    
372    
373 dpavlin 4 }
374 dpavlin 31
375     $retHTML .= "</table>";
376 dpavlin 102 $retHTML .= "</form>";
377 dpavlin 4
378 dpavlin 31 return $retHTML;
379     }
380 dpavlin 4
381 dpavlin 86 sub displayGrid($) {
382     my ($param) = @_;
383 dpavlin 83
384     my $offset = $param->{'offset'};
385     my $hilite = $param->{'search_filename'};
386    
387 dpavlin 17 my $retHTML = "";
388    
389 dpavlin 55 my $start_t = time();
390    
391 dpavlin 86 my ($results, $files);
392 dpavlin 88 if ($param->{'use_hest'} && length($hilite) > 0) {
393 dpavlin 87 ($results, $files) = getFilesHyperEstraier($param);
394 dpavlin 86 } else {
395 dpavlin 87 ($results, $files) = getFiles($param);
396 dpavlin 86 }
397 dpavlin 31
398 dpavlin 55 my $dur_t = time() - $start_t;
399     my $dur = sprintf("%0.4fs", $dur_t);
400    
401 dpavlin 31 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
402    
403 dpavlin 59 if ($results <= 0) {
404     $retHTML .= qq{
405     <p style="color: red;">No results found...</p>
406     };
407     return $retHTML;
408     } else {
409     # DEBUG
410     #use Data::Dumper;
411     #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
412     }
413    
414    
415 dpavlin 17 $retHTML .= qq{
416 dpavlin 79 <div>
417     Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
418     </div>
419     <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
420     <tr class="fviewheader">
421 dpavlin 87 <td></td>
422 dpavlin 79 <td align="center">Share</td>
423     <td align="center">Type and Name</td>
424     <td align="center">#</td>
425     <td align="center">Size</td>
426     <td align="center">Date</td>
427     <td align="center">Media</td>
428 dpavlin 17 </tr>
429     };
430 dpavlin 31
431 dpavlin 17 my $file;
432 dpavlin 4
433 dpavlin 17 sub hilite_html($$) {
434     my ($html, $search) = @_;
435     $html =~ s#($search)#<b>$1</b>#gis;
436     return $html;
437 dpavlin 4 }
438 dpavlin 9
439 dpavlin 26 sub restore_link($$$$$$) {
440     my $type = shift;
441     my $action = 'RestoreFile';
442     $action = 'browse' if (lc($type) eq 'dir');
443     return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
444     }
445    
446 dpavlin 87 my $i = $offset * $on_page;
447    
448 dpavlin 31 foreach $file (@{ $files }) {
449 dpavlin 87 $i++;
450    
451 dpavlin 24 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
452 dpavlin 79 $retHTML .= qq{<tr class="fviewborder">};
453 dpavlin 9
454 dpavlin 88 $retHTML .= qq{<td class="fviewborder">$i</td>};
455 dpavlin 87
456 dpavlin 79 $retHTML .=
457 dpavlin 86 qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
458     qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
459     qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
460 dpavlin 79 qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
461     qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
462 dpavlin 87 qq{<td class="fviewborder">} . '?' . qq{</td>};
463 dpavlin 9
464 dpavlin 17 $retHTML .= "</tr>";
465     }
466     $retHTML .= "</table>";
467    
468 dpavlin 31 # all variables which has to be transfered
469     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/) {
470     $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
471     }
472 dpavlin 17
473 dpavlin 31 my $del = '';
474     my $max_page = int( $results / $on_page );
475     my $page = 0;
476    
477 dpavlin 85 sub page_link($$$) {
478     my ($param,$page,$display) = @_;
479 dpavlin 31
480 dpavlin 85 $param->{'offset'} = $page;
481    
482     my $html = '<a href = "' . $MyURL;
483     my $del = '?';
484     foreach my $k (keys %{ $param }) {
485     if ($param->{$k}) {
486     $html .= $del . $k . '=' . ${EscURI( $param->{$k} )};
487     $del = '&';
488     }
489     }
490     $html .= '">' . $display . '</a>';
491     }
492    
493 dpavlin 31 $retHTML .= '<div style="text-align: center;">';
494    
495     if ($offset > 0) {
496 dpavlin 85 $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
497 dpavlin 31 }
498    
499     while ($page <= $max_page) {
500     if ($page == $offset) {
501     $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
502     } else {
503 dpavlin 85 $retHTML .= $del . page_link($param, $page, $page + 1);
504 dpavlin 17 }
505 dpavlin 31
506     if ($page < $offset - $pager_pages && $page != 0) {
507     $retHTML .= " ... ";
508     $page = $offset - $pager_pages;
509     $del = '';
510     } elsif ($page > $offset + $pager_pages && $page != $max_page) {
511     $retHTML .= " ... ";
512     $page = $max_page;
513     $del = '';
514     } else {
515     $del = ' | ';
516     $page++;
517     }
518 dpavlin 17 }
519    
520 dpavlin 31 if ($offset < $max_page) {
521 dpavlin 85 $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
522 dpavlin 31 }
523    
524     $retHTML .= "</div>";
525    
526 dpavlin 17 return $retHTML;
527     }
528 dpavlin 4
529     1;

  ViewVC Help
Powered by ViewVC 1.1.26