/[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 85 - (show annotations)
Sun Aug 28 10:45:51 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 11717 byte(s)
rewrite pager to transfer all parametars via URL instead of form POST

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 $dbh;
19
20 sub get_dbh {
21 $dbh ||= DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
22 return $dbh;
23 }
24
25 sub getUnits() {
26 my @ret;
27
28 my $dbh = get_dbh();
29 my $sth = $dbh->prepare(qq{ SELECT id, share FROM shares ORDER BY share} );
30 $sth->execute();
31 push @ret, { 'id' => '', 'share' => '-'}; # dummy any
32
33 while ( my $row = $sth->fetchrow_hashref() ) {
34 push @ret, $row;
35 }
36 return @ret;
37 }
38
39 sub epoch_to_iso {
40 my $t = shift || return;
41 my $iso = BackupPC::Lib::timeStamp($t);
42 $iso =~ s/\s/ /g;
43 return $iso;
44 }
45
46 sub dates_from_form($) {
47 my $param = shift || return;
48
49 sub mk_epoch_date($$) {
50 my ($name,$suffix) = @_;
51
52 my $yyyy = $param->{ $name . '_year_' . $suffix} || return;
53 my $mm .= $param->{ $name . '_month_' . $suffix} ||
54 ( $suffix eq 'from' ? 1 : 12);
55 my $dd .= $param->{ $name . '_day_' . $suffix} ||
56 ( $suffix eq 'from' ? 1 : 31);
57 my $dt = new DateTime(
58 year => $yyyy,
59 month => $mm,
60 day => $dd
61 );
62 return $dt->epoch || 'NULL';
63 }
64
65 return (
66 mk_epoch_date('search_backup', 'from'),
67 mk_epoch_date('search_backup', 'to'),
68 mk_epoch_date('search', 'from'),
69 mk_epoch_date('search', 'to'),
70 );
71 }
72
73
74 sub getWhere($) {
75 my $param = shift || return;
76
77 my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param);
78
79 my @conditions;
80 push @conditions, qq{ backups.date >= $backup_from } if ($backup_from);
81 push @conditions, qq{ backups.date <= $backup_to } if ($backup_to);
82 push @conditions, qq{ files.date >= $files_from } if ($files_from);
83 push @conditions, qq{ files.date <= $files_to } if ($files_to);
84
85 print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:" . join(" | ",@conditions);
86
87 push( @conditions, ' files.shareid = ' . $param->{'search_share'} ) if ($param->{'search_share'});
88 push (@conditions, " upper(files.path) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});
89
90 return join(" and ", @conditions);
91 }
92
93
94 sub getFiles($$) {
95 my ($param, $offset) = @_;
96
97 my $dbh = get_dbh();
98
99 my $sql_cols = qq{
100 files.id AS fid,
101 hosts.name AS hname,
102 shares.name AS sname,
103 shares.share AS sharename,
104 files.backupNum AS backupNum,
105 files.name AS filename,
106 files.path AS filepath,
107 files.date AS date,
108 files.type AS filetype,
109 files.size AS size,
110 -- dvds.name AS dvd
111 null AS dvd
112 };
113
114 my $sql_from = qq{
115 FROM files
116 INNER JOIN shares ON files.shareID=shares.ID
117 INNER JOIN hosts ON hosts.ID = shares.hostID
118 INNER JOIN backups ON backups.num = files.backupNum and backups.hostID = hosts.ID AND backups.shareID = shares.ID
119 };
120
121 my $sql_dvd_from = qq{
122 -- LEFT JOIN dvds ON dvds.ID = files.dvdid
123 };
124
125 my $sql_where;
126 my $where = getWhere($param);
127 $sql_where = " WHERE ". $where if ($where);
128
129 my $sql_order = qq{
130 ORDER BY files.date
131 LIMIT $on_page
132 OFFSET ?
133 };
134
135 my $sql_count = qq{ select count(files.id) $sql_from $sql_where };
136 my $sql_results = qq{ select $sql_cols $sql_from $sql_dvd_from $sql_where $sql_order };
137
138 $offset ||= 0;
139 $offset = ($offset * $on_page);
140
141 my $sth = $dbh->prepare($sql_count);
142 $sth->execute();
143 my ($results) = $sth->fetchrow_array();
144
145 $sth = $dbh->prepare($sql_results);
146 $sth->execute( $offset );
147
148 if ($sth->rows != $results) {
149 my $bug = "$0 BUG: [[ $sql_count ]] = $results while [[ $sql_results ]] = " . $sth->rows;
150 $bug =~ s/\s+/ /gs;
151 print STDERR "$bug\n";
152 }
153
154 my @ret;
155
156 while (my $row = $sth->fetchrow_hashref()) {
157 push(@ret, {
158 'hname' => $row->{'hname'},
159 'sname' => $row->{'sname'},
160 'sharename' => $row->{'sharename'},
161 'backupno' => $row->{'backupnum'},
162 'fname' => $row->{'filename'},
163 'fpath' => $row->{'filepath'},
164 'networkpath' => $row->{'networkpath'},
165 'date' => $row->{'date'},
166 'type' => $row->{'filetype'},
167 'size' => $row->{'size'},
168 'id' => $row->{'fid'},
169 'dvd' => $row->{'dvd'}
170 });
171 }
172
173 $sth->finish();
174 return ($results, \@ret);
175 }
176
177 sub getBackupsNotBurned() {
178
179 my $dbh = get_dbh();
180 my $sql = q{
181 SELECT
182 backups.hostID AS hostid,
183 min(hosts.name) AS host,
184 backups.num AS backupno,
185 min(backups.type) AS type,
186 min(backups.date) AS date,
187 min(backups.size) AS size
188 FROM files
189 INNER JOIN shares ON files.shareID=shares.ID
190 INNER JOIN hosts ON hosts.ID = shares.hostID
191 INNER JOIN backups ON backups.num = files.backupNum and backups.hostID = hosts.ID AND backups.shareID = shares.ID
192 WHERE
193 files.dvdid IS NULL
194 GROUP BY
195 backups.hostID, backups.num
196 ORDER BY min(backups.date)
197 };
198 my $sth = $dbh->prepare( $sql );
199 my @ret;
200 $sth->execute();
201
202 while ( my $row = $sth->fetchrow_hashref() ) {
203 $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
204 $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
205 push @ret, $row;
206 }
207
208 return @ret;
209 }
210
211 sub displayBackupsGrid()
212 {
213 my $retHTML = "";
214 my $addForm = 1;
215
216 if ($addForm) {
217
218 $retHTML .= <<EOF3;
219 <script language="javascript" type="text/javascript">
220 <!--
221
222 function checkAll(location)
223 {
224 for (var i=0;i<document.forma.elements.length;i++)
225 {
226 var e = document.forma.elements[i];
227 if ((e.checked || !e.checked) && e.name != \'all\') {
228 if (eval("document.forma."+location+".checked")) {
229 e.checked = true;
230 } else {
231 e.checked = false;
232 }
233 }
234 }
235 }
236 //-->
237 </script>
238 EOF3
239 $retHTML .= q{<form name="forma" method="GET" action="}."$MyURL"."?action=burn\"";
240 $retHTML.= q{<input type="hidden" value="burn" name="action">};
241 $retHTML .= q{<input type="hidden" value="results" name="search_results">};
242 }
243 $retHTML .= qq{
244 <table style="fview" border="1" cellspacing="0" cellpadding="3">
245 <tr class="tableheader">
246 };
247
248 if ($addForm) {
249 $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";
250 }
251 $retHTML .= qq{
252 <td align="center">Host</td>
253 <td align="center">Backup no</td>
254 <td align="center">Type</td>
255 <td align="center">date</td>
256 <td align="center">age/days</td>
257 <td align="center">size/MB</td>
258 </tr>
259 };
260
261 my @backups = getBackupsNotBurned();
262 my $backup;
263
264 if ($addForm) {
265 $retHTML .= qq{
266 <tr><td colspan=7 style="tableheader">
267 <input type="submit" value="Burn selected backups on medium" name="submitBurner">
268 </td></tr>
269 };
270 }
271
272 foreach $backup(@backups) {
273
274 my $ftype = "";
275
276 $retHTML .= "<tr>";
277 if ($addForm) {
278 $retHTML .= '<td class="fview"><input type="checkbox" name="fcb' .
279 $backup->{'hostid'}.'_'.$backup->{'backupno'} .
280 '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupno'} .
281 '"></td>';
282 }
283
284 $retHTML .= '<td class="fviewborder">' . $backup->{'host'} . '</td>' .
285 '<td class="fviewborder">' . $backup->{'backupno'} . '</td>' .
286 '<td class="fviewborder">' . $backup->{'type'} . '</td>' .
287 '<td class="fviewborder">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
288 '<td class="fviewborder">' . $backup->{'age'} . '</td>' .
289 '<td class="fviewborder">' . $backup->{'size'} . '</td>' .
290 '</tr>';
291 }
292
293 $retHTML .= "</table>";
294
295 if ($addForm) {
296 $retHTML .= "</form>";
297 }
298
299 return $retHTML;
300 }
301
302 sub displayGrid($$) {
303 my ($param, $addForm) = @_;
304
305 my $offset = $param->{'offset'};
306 my $hilite = $param->{'search_filename'};
307
308 my $retHTML = "";
309
310 my $start_t = time();
311
312 my ($results, $files) = getFiles($param, $offset);
313
314 my $dur_t = time() - $start_t;
315 my $dur = sprintf("%0.4fs", $dur_t);
316
317 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
318
319 if ($results <= 0) {
320 $retHTML .= qq{
321 <p style="color: red;">No results found...</p>
322 };
323 return $retHTML;
324 } else {
325 # DEBUG
326 #use Data::Dumper;
327 #$retHTML .= '<pre>' . Dumper($files) . '</pre>';
328 }
329
330
331 if ($addForm) {
332 $retHTML .= qq{<form name="forma" method="GET" action="$MyURL">};
333 $retHTML.= qq{<input type="hidden" value="search" name="action">};
334 $retHTML .= qq{<input type="hidden" value="results" name="search_results">};
335 }
336
337
338 $retHTML .= qq{
339 <div>
340 Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
341 </div>
342 <table style="fview" width="100%" border="0" cellpadding="2" cellspacing="0">
343 <tr class="fviewheader">
344 <td align="center">Share</td>
345 <td align="center">Type and Name</td>
346 <td align="center">#</td>
347 <td align="center">Size</td>
348 <td align="center">Date</td>
349 <td align="center">Media</td>
350 </tr>
351 };
352
353 my $file;
354
355 sub hilite_html($$) {
356 my ($html, $search) = @_;
357 $html =~ s#($search)#<b>$1</b>#gis;
358 return $html;
359 }
360
361 sub restore_link($$$$$$) {
362 my $type = shift;
363 my $action = 'RestoreFile';
364 $action = 'browse' if (lc($type) eq 'dir');
365 return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
366 }
367
368 foreach $file (@{ $files }) {
369 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
370 $retHTML .= qq{<tr class="fviewborder">};
371
372 $retHTML .=
373 qq{<td class="fviewborder" align="right">} . $file->{'sharename'} . qq{</td>} .
374 qq{<td class="fviewborder"><img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" alt="$typeStr" align="middle">&nbsp;} . hilite_html( $file->{'fpath'}, $hilite ) . qq{</td>} .
375 qq{<td class="fviewborder" align="center">} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupno'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'fpath'} )}, $file->{'backupno'} ) . qq{</td>} .
376 qq{<td class="fviewborder" align="right">} . $file->{'size'} . qq{</td>} .
377 qq{<td class="fviewborder">} . epoch_to_iso( $file->{'date'} ) . qq{</td>} .
378 qq{<td class="fviewborder">} . $file->{'dvd'} . qq{</td>};
379
380 $retHTML .= "</tr>";
381 }
382 $retHTML .= "</table>";
383
384 # all variables which has to be transfered
385 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/) {
386 $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
387 }
388
389 my $del = '';
390 my $max_page = int( $results / $on_page );
391 my $page = 0;
392
393 sub page_link($$$) {
394 my ($param,$page,$display) = @_;
395
396 $param->{'offset'} = $page;
397
398 my $html = '<a href = "' . $MyURL;
399 my $del = '?';
400 foreach my $k (keys %{ $param }) {
401 if ($param->{$k}) {
402 $html .= $del . $k . '=' . ${EscURI( $param->{$k} )};
403 $del = '&';
404 }
405 }
406 $html .= '">' . $display . '</a>';
407 }
408
409 $retHTML .= '<div style="text-align: center;">';
410
411 if ($offset > 0) {
412 $retHTML .= page_link($param, $offset - 1, '&lt;&lt;') . ' ';
413 }
414
415 while ($page <= $max_page) {
416 if ($page == $offset) {
417 $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
418 } else {
419 $retHTML .= $del . page_link($param, $page, $page + 1);
420 }
421
422 if ($page < $offset - $pager_pages && $page != 0) {
423 $retHTML .= " ... ";
424 $page = $offset - $pager_pages;
425 $del = '';
426 } elsif ($page > $offset + $pager_pages && $page != $max_page) {
427 $retHTML .= " ... ";
428 $page = $max_page;
429 $del = '';
430 } else {
431 $del = ' | ';
432 $page++;
433 }
434 }
435
436 if ($offset < $max_page) {
437 $retHTML .= ' ' . page_link($param, $offset + 1, '&gt;&gt;');
438 }
439
440 $retHTML .= "</div>";
441
442 $retHTML .= "</form>" if ($addForm);
443
444 return $retHTML;
445 }
446
447 1;

  ViewVC Help
Powered by ViewVC 1.1.26