/[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 55 - (show annotations)
Sun Aug 21 13:44:20 2005 UTC (18 years, 9 months ago) by dpavlin
File size: 10628 byte(s)
removed dvds from count sql, added duration of search, cosmetic changes in output

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 my $tmp;
21 my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
22 my $st =
23 $dbh->prepare(
24 " SELECT shares.ID AS ID, shares.share AS name FROM shares;");
25 $st->execute();
26 push (@ret, { 'ID' => '', 'name' => '-'});
27 while ( $tmp = $st->fetchrow_hashref() ) {
28 push( @ret, { 'ID' => $tmp->{'ID'}, 'name' => $tmp->{'name'} } );
29 }
30 $dbh->disconnect();
31 return @ret;
32 }
33
34 sub epoch_to_iso {
35 my $t = shift || return;
36 my $dt = DateTime->from_epoch( epoch => $t ) || return;
37 print STDERR "$t == ",$dt->epoch,"\n";
38 return $dt->ymd . ' ' . $dt->hms;
39 }
40
41 sub getWhere($) {
42 my ($param) = @_;
43 my @conditions;
44
45 sub mk_epoch_date($$) {
46 my ($name,$suffix) = @_;
47
48 my $yyyy = $param->{ $name . '_year_' . $suffix} || return;
49 my $mm .= $param->{ $name . '_month_' . $suffix} ||
50 ( $suffix eq 'from' ? 1 : 12);
51 my $dd .= $param->{ $name . '_day_' . $suffix} ||
52 ( $suffix eq 'from' ? 1 : 31);
53 my $dt = new DateTime(
54 year => $yyyy,
55 month => $mm,
56 day => $dd
57 );
58 return $dt->epoch || 'NULL';
59 }
60
61 my $backup_from = mk_epoch_date('search_backup', 'from');
62 push @conditions, qq{ backups.date >= $backup_from } if ($backup_from);
63 my $backup_to = mk_epoch_date('search_backup', 'to');
64 push @conditions, qq{ backups.date <= $backup_to } if ($backup_to);
65
66 my $files_from = mk_epoch_date('search', 'from');
67 push @conditions, qq{ files.date >= $files_from } if ($files_from);
68 my $files_to = mk_epoch_date('search', 'to');
69 push @conditions, qq{ files.date <= $files_to } if ($files_to);
70
71 print STDERR "backup: $backup_from - $backup_to files: $files_from - $files_to cond:",join(" | ",@conditions);
72
73 push( @conditions, ' backups.hostID = ' . $param->{'search_host'} ) if ($param->{'search_host'});
74
75 push (@conditions, " upper(files.name) LIKE upper('%".$param->{'search_filename'}."%')") if ($param->{'search_filename'});
76
77 return (
78 join(" and ", @conditions),
79 $files_from, $files_to,
80 $backup_from, $backup_to
81 );
82 }
83
84
85 sub getFiles($$) {
86 my ($where, $offset) = @_;
87
88 my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
89
90 my $sql_cols = qq{
91 files.id AS fid,
92 hosts.name AS hname,
93 shares.name AS sname,
94 shares.share AS sharename,
95 files.backupNum AS backupNum,
96 files.name AS filename,
97 files.path AS filepath,
98 shares.share||files.fullpath AS networkPath,
99 files.date AS date,
100 files.type AS filetype,
101 files.size AS size,
102 };
103
104 my $sql_dvd_cols = qq{
105 dvds.name 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
113 };
114
115 my $sql_dvd_from = qq{
116 LEFT JOIN dvds ON dvds.ID = files.dvdid
117 };
118
119 my $sql_where;
120 $sql_where = " WHERE ". $where if ($where);
121
122 my $sql_order = qq{
123 ORDER BY files.id
124 LIMIT $on_page
125 OFFSET ?
126 };
127
128 $offset ||= 0;
129 $offset = ($offset * $on_page) + 1;
130
131 my $sth = $dbh->prepare(qq{ select count(files.id) $sql_from $sql_where });
132 $sth->execute();
133
134 my ($results) = $sth->fetchrow_array();
135
136 $sth = $dbh->prepare(qq{ select $sql_cols $sql_dvd_cols $sql_from $sql_dvd_from $sql_where $sql_order });
137 $sth->execute( $offset );
138
139 my @ret;
140
141 while (my $row = $sth->fetchrow_hashref()) {
142 push(@ret, {
143 'hname' => $row->{'hname'},
144 'sname' => $row->{'sname'},
145 'sharename' => $row->{'sharename'},
146 'backupno' => $row->{'backupnum'},
147 'fname' => $row->{'filename'},
148 'fpath' => $row->{'filepath'},
149 'networkpath' => $row->{'networkpath'},
150 'date' => $row->{'date'},
151 'type' => $row->{'filetype'},
152 'size' => $row->{'size'},
153 'id' => $row->{'fid'},
154 'dvd' => $row->{'dvd'}
155 });
156 }
157
158 $sth->finish();
159 $dbh->disconnect();
160 return ($results, \@ret);
161 }
162
163 sub getBackupsNotBurned() {
164
165 my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
166 my $sql = q{
167 SELECT
168 hosts.ID AS hostid,
169 min(hosts.name) AS host,
170 backups.num AS backupno,
171 min(backups.type) AS type,
172 min(backups.date) AS date
173 FROM backups, shares, files, hosts
174 WHERE
175 backups.num = files.backupNum AND
176 shares.ID = files.shareID AND
177 backups.hostID = shares.hostID AND
178 hosts.ID = backups.hostID AND
179 files.dvdid IS NULL
180 GROUP BY
181 backups.hostID, backups.num, hosts.id
182 };
183 my $sth = $dbh->prepare( $sql );
184 my @ret;
185 $sth->execute();
186
187 while ( my $row = $sth->fetchrow_hashref() ) {
188 push(@ret, {
189 'host' => $row->{'host'},
190 'hostid' => $row->{'hostid'},
191 'backupno' => $row->{'backupno'},
192 'type' => $row->{'type'},
193 'date' => $row->{'date'}
194 }
195 );
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{<table style="fview"><tr>};
234
235 if ($addForm) {
236 $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";
237 }
238 $retHTML .= qq{<td class="tableheader">Host</td><td class="tableheader">Backup no</td><td class="tableheader">Type</td><td class="tableheader">date</td></tr>};
239
240 my @backups = getBackupsNotBurned();
241 my $backup;
242
243 if ($addForm) {
244 $retHTML .= qq{<tr><td colspan=7 style="tableheader">
245 <input type="submit" value="Burn selected backups on medium" name="submitBurner">
246 </td></tr>};
247 }
248
249 foreach $backup(@backups) {
250
251 my $ftype = "";
252
253 $retHTML .= "<tr>";
254 if ($addForm) {
255 $retHTML .= qq{<td class="fview"><input type="checkbox" name="fcb} .
256 $backup->{'hostid'}."_".$backup->{'backupno'} .
257 qq{" value="} . $backup->{'hostid'}."_".$backup->{'backupno'} .
258 qq{"></td>};
259 }
260
261 $retHTML .= '<td class="fviewborder">' . $backup->{'host'} . '</td>' .
262 '<td class="fviewborder">' . $backup->{'backupno'} . '</td>' .
263 '<td class="fviewborder">' . $backup->{'type'} . '</td>' .
264 '<td class="fviewborder">' . epoch_to_iso( $backup->{'date'} ) . '<td>' .
265 '</tr>';
266 }
267
268 $retHTML .= "</table>";
269
270 if ($addForm) {
271 $retHTML .= "</form>";
272 }
273
274 return $retHTML;
275 }
276
277 sub displayGrid($$$$) {
278 my ($where, $addForm, $offset, $hilite) = @_;
279 my $retHTML = "";
280
281 if ($addForm) {
282 $retHTML .= qq{<form name="forma" method="GET" action="$MyURL">};
283 $retHTML.= qq{<input type="hidden" value="search" name="action">};
284 $retHTML .= qq{<input type="hidden" value="results" name="search_results">};
285 }
286
287 my $start_t = time();
288
289 my ($results, $files) = getFiles($where, $offset);
290
291 my $dur_t = time() - $start_t;
292 my $dur = sprintf("%0.4fs", $dur_t);
293
294 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
295
296 $retHTML .= qq{
297 <br/>Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
298 <table style="fview" width="100%">
299 <tr>
300 <td class="tableheader">Share</td>
301 <td class="tableheader">Name</td>
302 <td class="tableheader">Type</td>
303 <td class="tableheader">#</td>
304 <td class="tableheader">Size</td>
305 <td class="tableheader">Date</td>
306 <td class="tableheader">Media</td>
307 </tr>
308 };
309
310 my $file;
311
312 sub hilite_html($$) {
313 my ($html, $search) = @_;
314 $html =~ s#($search)#<b>$1</b>#gis;
315 return $html;
316 }
317
318 sub restore_link($$$$$$) {
319 my $type = shift;
320 my $action = 'RestoreFile';
321 $action = 'browse' if (lc($type) eq 'dir');
322 return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
323 }
324
325 foreach $file (@{ $files }) {
326 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
327 $retHTML .= "<tr>";
328
329 foreach my $v ((
330 $file->{'sharename'},
331 qq{<img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" align="center">&nbsp;} . hilite_html( $file->{'fpath'}, $hilite ),
332 $typeStr,
333 restore_link( $typeStr, $file->{'hname'}, $file->{'backupno'}, $file->{'sname'}, $file->{'fpath'}, $file->{'backupno'} ),
334 $file->{'size'},
335 epoch_to_iso( $file->{'date'} ),
336 $file->{'dvd'}
337 )) {
338 $retHTML .= qq{<td class="fviewborder">$v</td>};
339 }
340
341 $retHTML .= "</tr>";
342 }
343 $retHTML .= "</table>";
344
345 # all variables which has to be transfered
346 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/) {
347 $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
348 }
349
350 my $del = '';
351 my $max_page = int( $results / $on_page );
352 my $page = 0;
353
354 my $link_fmt = '<a href = "#" onclick="document.forma.offset.value=%d;document.forma.submit();">%s</a>';
355
356 $retHTML .= '<div style="text-align: center;">';
357
358 if ($offset > 0) {
359 $retHTML .= sprintf($link_fmt, $offset - 1, '&lt;&lt;') . ' ';
360 }
361
362 while ($page <= $max_page) {
363 if ($page == $offset) {
364 $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
365 } else {
366 $retHTML .= $del . sprintf($link_fmt, $page, $page + 1);
367 }
368
369 if ($page < $offset - $pager_pages && $page != 0) {
370 $retHTML .= " ... ";
371 $page = $offset - $pager_pages;
372 $del = '';
373 } elsif ($page > $offset + $pager_pages && $page != $max_page) {
374 $retHTML .= " ... ";
375 $page = $max_page;
376 $del = '';
377 } else {
378 $del = ' | ';
379 $page++;
380 }
381 }
382
383 if ($offset < $max_page) {
384 $retHTML .= ' ' . sprintf($link_fmt, $offset + 1, '&gt;&gt;');
385 }
386
387 $retHTML .= "</div>";
388
389 $retHTML .= "</form>" if ($addForm);
390
391 return $retHTML;
392 }
393
394 1;

  ViewVC Help
Powered by ViewVC 1.1.26