/[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 83 - (show annotations)
Sun Aug 28 10:14:48 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 11604 byte(s)
refactor displaySearchGrid and related function to remove multiple calls
from BackupPC::CGI::SearchArchives to BackupPC::SearchLib.

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

  ViewVC Help
Powered by ViewVC 1.1.26