/[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 79 - (show annotations)
Fri Aug 26 23:37:10 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 11463 byte(s)
use BackupPC::Lib::timeStamp in epoch_to_iso,
removed dvds from SQL (in preparation for new storage of archival media),
fix archial SQL,
use correct (I hope) CSS classes in search html

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

  ViewVC Help
Powered by ViewVC 1.1.26