/[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 58 - (show annotations)
Sun Aug 21 14:26:23 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 10838 byte(s)
burn media now sorts by start date and display age (in days)

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 ORDER BY min(backups.date)
183 };
184 my $sth = $dbh->prepare( $sql );
185 my @ret;
186 $sth->execute();
187
188 while ( my $row = $sth->fetchrow_hashref() ) {
189 push(@ret, {
190 'host' => $row->{'host'},
191 'hostid' => $row->{'hostid'},
192 'backupno' => $row->{'backupno'},
193 'type' => $row->{'type'},
194 'date' => $row->{'date'},
195 'age' => sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) ),
196 }
197 );
198 }
199
200 return @ret;
201 }
202
203 sub displayBackupsGrid()
204 {
205 my $retHTML = "";
206 my $addForm = 1;
207
208 if ($addForm) {
209
210 $retHTML .= <<EOF3;
211 <script language="javascript" type="text/javascript">
212 <!--
213
214 function checkAll(location)
215 {
216 for (var i=0;i<document.forma.elements.length;i++)
217 {
218 var e = document.forma.elements[i];
219 if ((e.checked || !e.checked) && e.name != \'all\') {
220 if (eval("document.forma."+location+".checked")) {
221 e.checked = true;
222 } else {
223 e.checked = false;
224 }
225 }
226 }
227 }
228 //-->
229 </script>
230 EOF3
231 $retHTML .= q{<form name="forma" method="GET" action="}."$MyURL"."?action=burn\"";
232 $retHTML.= q{<input type="hidden" value="burn" name="action">};
233 $retHTML .= q{<input type="hidden" value="results" name="search_results">};
234 }
235 $retHTML .= qq{<table style="fview"><tr>};
236
237 if ($addForm) {
238 $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";
239 }
240 $retHTML .= qq{
241 <td class="tableheader">Host</td>
242 <td class="tableheader">Backup no</td>
243 <td class="tableheader">Type</td>
244 <td class="tableheader">date</td>
245 <td class="tableheader">age/days</td>
246 </tr>
247 };
248
249 my @backups = getBackupsNotBurned();
250 my $backup;
251
252 if ($addForm) {
253 $retHTML .= qq{
254 <tr><td colspan=7 style="tableheader">
255 <input type="submit" value="Burn selected backups on medium" name="submitBurner">
256 </td></tr>
257 };
258 }
259
260 foreach $backup(@backups) {
261
262 my $ftype = "";
263
264 $retHTML .= "<tr>";
265 if ($addForm) {
266 $retHTML .= '<td class="fview"><input type="checkbox" name="fcb' .
267 $backup->{'hostid'}.'_'.$backup->{'backupno'} .
268 '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupno'} .
269 '"></td>';
270 }
271
272 $retHTML .= '<td class="fviewborder">' . $backup->{'host'} . '</td>' .
273 '<td class="fviewborder">' . $backup->{'backupno'} . '</td>' .
274 '<td class="fviewborder">' . $backup->{'type'} . '</td>' .
275 '<td class="fviewborder">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
276 '<td class="fviewborder">' . $backup->{'age'} . '</td>' .
277 '</tr>';
278 }
279
280 $retHTML .= "</table>";
281
282 if ($addForm) {
283 $retHTML .= "</form>";
284 }
285
286 return $retHTML;
287 }
288
289 sub displayGrid($$$$) {
290 my ($where, $addForm, $offset, $hilite) = @_;
291 my $retHTML = "";
292
293 if ($addForm) {
294 $retHTML .= qq{<form name="forma" method="GET" action="$MyURL">};
295 $retHTML.= qq{<input type="hidden" value="search" name="action">};
296 $retHTML .= qq{<input type="hidden" value="results" name="search_results">};
297 }
298
299 my $start_t = time();
300
301 my ($results, $files) = getFiles($where, $offset);
302
303 my $dur_t = time() - $start_t;
304 my $dur = sprintf("%0.4fs", $dur_t);
305
306 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
307
308 $retHTML .= qq{
309 <br/>Found <b>$results files</b> showing <b>$from - $to</b> (took $dur)
310 <table style="fview" width="100%">
311 <tr>
312 <td class="tableheader">Share</td>
313 <td class="tableheader">Name</td>
314 <td class="tableheader">Type</td>
315 <td class="tableheader">#</td>
316 <td class="tableheader">Size</td>
317 <td class="tableheader">Date</td>
318 <td class="tableheader">Media</td>
319 </tr>
320 };
321
322 my $file;
323
324 sub hilite_html($$) {
325 my ($html, $search) = @_;
326 $html =~ s#($search)#<b>$1</b>#gis;
327 return $html;
328 }
329
330 sub restore_link($$$$$$) {
331 my $type = shift;
332 my $action = 'RestoreFile';
333 $action = 'browse' if (lc($type) eq 'dir');
334 return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
335 }
336
337 foreach $file (@{ $files }) {
338 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
339 $retHTML .= "<tr>";
340
341 foreach my $v ((
342 $file->{'sharename'},
343 qq{<img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" align="center">&nbsp;} . hilite_html( $file->{'fpath'}, $hilite ),
344 $typeStr,
345 restore_link( $typeStr, $file->{'hname'}, $file->{'backupno'}, $file->{'sname'}, $file->{'fpath'}, $file->{'backupno'} ),
346 $file->{'size'},
347 epoch_to_iso( $file->{'date'} ),
348 $file->{'dvd'}
349 )) {
350 $retHTML .= qq{<td class="fviewborder">$v</td>};
351 }
352
353 $retHTML .= "</tr>";
354 }
355 $retHTML .= "</table>";
356
357 # all variables which has to be transfered
358 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/) {
359 $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
360 }
361
362 my $del = '';
363 my $max_page = int( $results / $on_page );
364 my $page = 0;
365
366 my $link_fmt = '<a href = "#" onclick="document.forma.offset.value=%d;document.forma.submit();">%s</a>';
367
368 $retHTML .= '<div style="text-align: center;">';
369
370 if ($offset > 0) {
371 $retHTML .= sprintf($link_fmt, $offset - 1, '&lt;&lt;') . ' ';
372 }
373
374 while ($page <= $max_page) {
375 if ($page == $offset) {
376 $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
377 } else {
378 $retHTML .= $del . sprintf($link_fmt, $page, $page + 1);
379 }
380
381 if ($page < $offset - $pager_pages && $page != 0) {
382 $retHTML .= " ... ";
383 $page = $offset - $pager_pages;
384 $del = '';
385 } elsif ($page > $offset + $pager_pages && $page != $max_page) {
386 $retHTML .= " ... ";
387 $page = $max_page;
388 $del = '';
389 } else {
390 $del = ' | ';
391 $page++;
392 }
393 }
394
395 if ($offset < $max_page) {
396 $retHTML .= ' ' . sprintf($link_fmt, $offset + 1, '&gt;&gt;');
397 }
398
399 $retHTML .= "</div>";
400
401 $retHTML .= "</form>" if ($addForm);
402
403 return $retHTML;
404 }
405
406 1;

  ViewVC Help
Powered by ViewVC 1.1.26