/[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 102 - (hide annotations)
Tue Aug 30 22:43:01 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 13012 byte(s)
added share, nicer html

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 51 sub getBackupsNotBurned() {
245    
246 dpavlin 84 my $dbh = get_dbh();
247 dpavlin 53 my $sql = q{
248     SELECT
249 dpavlin 66 backups.hostID AS hostid,
250 dpavlin 53 min(hosts.name) AS host,
251 dpavlin 102 min(shares.name) AS share,
252 dpavlin 86 backups.num AS backupnum,
253 dpavlin 53 min(backups.type) AS type,
254 dpavlin 66 min(backups.date) AS date,
255     min(backups.size) AS size
256 dpavlin 79 FROM files
257     INNER JOIN shares ON files.shareID=shares.ID
258     INNER JOIN hosts ON hosts.ID = shares.hostID
259 dpavlin 86 INNER JOIN backups ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = shares.ID
260 dpavlin 53 GROUP BY
261 dpavlin 102 backups.hostID, backups.num, backups.shareid
262 dpavlin 58 ORDER BY min(backups.date)
263 dpavlin 53 };
264     my $sth = $dbh->prepare( $sql );
265     my @ret;
266     $sth->execute();
267 dpavlin 4
268 dpavlin 66 while ( my $row = $sth->fetchrow_hashref() ) {
269     $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
270     $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
271     push @ret, $row;
272 dpavlin 4 }
273    
274 dpavlin 53 return @ret;
275     }
276 dpavlin 4
277     sub displayBackupsGrid()
278     {
279     my $retHTML = "";
280    
281 dpavlin 102 $retHTML .= <<EOF3;
282 dpavlin 4 <script language="javascript" type="text/javascript">
283     <!--
284    
285     function checkAll(location)
286     {
287     for (var i=0;i<document.forma.elements.length;i++)
288     {
289     var e = document.forma.elements[i];
290     if ((e.checked || !e.checked) && e.name != \'all\') {
291     if (eval("document.forma."+location+".checked")) {
292     e.checked = true;
293     } else {
294     e.checked = false;
295     }
296     }
297     }
298     }
299     //-->
300     </script>
301     EOF3
302 dpavlin 102 $retHTML .= q{
303     <form name="forma" method="GET" action="$MyURL?action=burn">
304     <input type="hidden" value="burn" name="action">
305     <input type="hidden" value="results" name="search_results">
306     <table style="fview" border="0" cellspacing="0" cellpadding="2">
307 dpavlin 79 <tr class="tableheader">
308 dpavlin 102 <td class="tableheader">
309     <input type="checkbox" name="allFiles" onClick="checkAll('allFiles');">
310     </td>
311     <td align="center">Share</td>
312 dpavlin 79 <td align="center">Backup no</td>
313     <td align="center">Type</td>
314     <td align="center">date</td>
315     <td align="center">age/days</td>
316     <td align="center">size/MB</td>
317 dpavlin 58 </tr>
318 dpavlin 102
319     <tr><td colspan=7 style="tableheader">
320     <input type="submit" value="Burn selected backups on medium" name="submitBurner">
321     </td></tr>
322 dpavlin 58 };
323 dpavlin 4
324 dpavlin 102 my @color = (' bgcolor="#e0e0e0"', '');
325 dpavlin 31
326 dpavlin 102 my $i = 0;
327     my $host = '';
328 dpavlin 31
329 dpavlin 102 foreach my $backup ( getBackupsNotBurned() ) {
330 dpavlin 31
331 dpavlin 102 if ($host ne $backup->{'host'}) {
332     $i++;
333     $host = $backup->{'host'};
334     }
335 dpavlin 31 my $ftype = "";
336 dpavlin 4
337 dpavlin 102 $retHTML .= "<tr" . $color[$i %2 ] . ">";
338     $retHTML .= '<td class="fview"><input type="checkbox" name="fcb' .
339 dpavlin 86 $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
340     '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
341 dpavlin 58 '"></td>';
342 dpavlin 4
343 dpavlin 102 $retHTML .=
344     '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
345     '<td align="center">' . $backup->{'backupnum'} . '</td>' .
346     '<td align="center">' . $backup->{'type'} . '</td>' .
347     '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
348     '<td align="center">' . $backup->{'age'} . '</td>' .
349     '<td align="right">' . $backup->{'size'} . '</td>' .
350     "</tr>\n";
351    
352    
353 dpavlin 4 }
354 dpavlin 31
355     $retHTML .= "</table>";
356 dpavlin 102 $retHTML .= "</form>";
357 dpavlin 4
358 dpavlin 31 return $retHTML;
359     }
360 dpavlin 4
361 dpavlin 86 sub displayGrid($) {
362     my ($param) = @_;
363 dpavlin 83
364     my $offset = $param->{'offset'};
365     my $hilite = $param->{'search_filename'};
366    
367 dpavlin 17 my $retHTML = "";
368    
369 dpavlin 55 my $start_t = time();
370    
371 dpavlin 86 my ($results, $files);
372 dpavlin 88 if ($param->{'use_hest'} && length($hilite) > 0) {
373 dpavlin 87 ($results, $files) = getFilesHyperEstraier($param);
374 dpavlin 86 } else {
375 dpavlin 87 ($results, $files) = getFiles($param);
376 dpavlin 86 }
377 dpavlin 31
378 dpavlin 55 my $dur_t = time() - $start_t;
379     my $dur = sprintf("%0.4fs", $dur_t);
380    
381 dpavlin 31 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
382    
383 dpavlin 59 if ($results <= 0) {
384     $retHTML .= qq{
385     <p style="color: red;">No results found...</p>
386     };
387     return $retHTML;
388     } else {
389     # DEBUG
390     #use Data::Dumper;
391     #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
392     }
393    
394    
395 dpavlin 17 $retHTML .= qq{
396 dpavlin 79 <div>
397     Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
398     </div>
399     <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
400     <tr class="fviewheader">
401 dpavlin 87 <td></td>
402 dpavlin 79 <td align="center">Share</td>
403     <td align="center">Type and Name</td>
404     <td align="center">#</td>
405     <td align="center">Size</td>
406     <td align="center">Date</td>
407     <td align="center">Media</td>
408 dpavlin 17 </tr>
409     };
410 dpavlin 31
411 dpavlin 17 my $file;
412 dpavlin 4
413 dpavlin 17 sub hilite_html($$) {
414     my ($html, $search) = @_;
415     $html =~ s#($search)#<b>$1</b>#gis;
416     return $html;
417 dpavlin 4 }
418 dpavlin 9
419 dpavlin 26 sub restore_link($$$$$$) {
420     my $type = shift;
421     my $action = 'RestoreFile';
422     $action = 'browse' if (lc($type) eq 'dir');
423     return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
424     }
425    
426 dpavlin 87 my $i = $offset * $on_page;
427    
428 dpavlin 31 foreach $file (@{ $files }) {
429 dpavlin 87 $i++;
430    
431 dpavlin 24 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
432 dpavlin 79 $retHTML .= qq{<tr class="fviewborder">};
433 dpavlin 9
434 dpavlin 88 $retHTML .= qq{<td class="fviewborder">$i</td>};
435 dpavlin 87
436 dpavlin 79 $retHTML .=
437 dpavlin 86 qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .
438     qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'filepath'}, $hilite ) . qq{</td>} .
439     qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{</td>} .
440 dpavlin 79 qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
441     qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
442 dpavlin 87 qq{<td class="fviewborder">} . '?' . qq{</td>};
443 dpavlin 9
444 dpavlin 17 $retHTML .= "</tr>";
445     }
446     $retHTML .= "</table>";
447    
448 dpavlin 31 # all variables which has to be transfered
449     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/) {
450     $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
451     }
452 dpavlin 17
453 dpavlin 31 my $del = '';
454     my $max_page = int( $results / $on_page );
455     my $page = 0;
456    
457 dpavlin 85 sub page_link($$$) {
458     my ($param,$page,$display) = @_;
459 dpavlin 31
460 dpavlin 85 $param->{'offset'} = $page;
461    
462     my $html = '<a href = "' . $MyURL;
463     my $del = '?';
464     foreach my $k (keys %{ $param }) {
465     if ($param->{$k}) {
466     $html .= $del . $k . '=' . ${EscURI( $param->{$k} )};
467     $del = '&';
468     }
469     }
470     $html .= '">' . $display . '</a>';
471     }
472    
473 dpavlin 31 $retHTML .= '<div style="text-align: center;">';
474    
475     if ($offset > 0) {
476 dpavlin 85 $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
477 dpavlin 31 }
478    
479     while ($page <= $max_page) {
480     if ($page == $offset) {
481     $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
482     } else {
483 dpavlin 85 $retHTML .= $del . page_link($param, $page, $page + 1);
484 dpavlin 17 }
485 dpavlin 31
486     if ($page < $offset - $pager_pages && $page != 0) {
487     $retHTML .= " ... ";
488     $page = $offset - $pager_pages;
489     $del = '';
490     } elsif ($page > $offset + $pager_pages && $page != $max_page) {
491     $retHTML .= " ... ";
492     $page = $max_page;
493     $del = '';
494     } else {
495     $del = ' | ';
496     $page++;
497     }
498 dpavlin 17 }
499    
500 dpavlin 31 if ($offset < $max_page) {
501 dpavlin 85 $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
502 dpavlin 31 }
503    
504     $retHTML .= "</div>";
505    
506 dpavlin 17 return $retHTML;
507     }
508 dpavlin 4
509     1;

  ViewVC Help
Powered by ViewVC 1.1.26