/[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 51 - (show annotations)
Sat Aug 20 16:40:11 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 10512 byte(s)
added SearchDSN and SearchUser configuration directives. Defaults are
probably useful only to me :-)
Added total duration display to BackupPC_updatedb

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
11 my $on_page = 100;
12 my $pager_pages = 10;
13
14 my $dsn = $Conf{SearchDSN};
15 my $db_user = $Conf{SearchUser} || '';
16
17 sub getUnits() {
18 my @ret = ();
19 my $tmp;
20 my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
21 my $st =
22 $dbh->prepare(
23 " SELECT shares.ID AS ID, shares.share AS name FROM shares;");
24 $st->execute();
25 push (@ret, { 'ID' => '', 'name' => '-'});
26 while ( $tmp = $st->fetchrow_hashref() ) {
27 push( @ret, { 'ID' => $tmp->{'ID'}, 'name' => $tmp->{'name'} } );
28 }
29 $dbh->disconnect();
30 return @ret;
31 }
32
33 sub epoch_to_iso {
34 my $t = shift || return;
35 my $dt = DateTime->from_epoch( epoch => $t ) || return;
36 print STDERR "$t == ",$dt->epoch,"\n";
37 return $dt->ymd . ' ' . $dt->hms;
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, ' backups.hostID = ' . $param->{'search_host'} ) if ($param->{'search_host'});
73
74 push (@conditions, " upper(files.name) 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 shares.share||files.fullpath AS networkPath,
98 files.date AS date,
99 files.type AS filetype,
100 files.size AS size,
101 dvds.name 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
109 LEFT JOIN dvds ON dvds.ID = files.dvdid
110 };
111
112 my $sql_where;
113 $sql_where = " WHERE ". $where if ($where);
114
115 my $sql_order = qq{
116 ORDER BY files.id
117 LIMIT $on_page
118 OFFSET ?
119 };
120
121 $offset ||= 0;
122 $offset = ($offset * $on_page) + 1;
123
124 my $sth = $dbh->prepare(qq{ select count(files.id) $sql_from $sql_where });
125 $sth->execute();
126
127 my ($results) = $sth->fetchrow_array();
128
129 $sth = $dbh->prepare(qq{ select $sql_cols $sql_from $sql_where $sql_order });
130 $sth->execute( $offset );
131
132 my @ret;
133
134 while (my $row = $sth->fetchrow_hashref()) {
135 push(@ret, {
136 'hname' => $row->{'hname'},
137 'sname' => $row->{'sname'},
138 'sharename' => $row->{'sharename'},
139 'backupno' => $row->{'backupnum'},
140 'fname' => $row->{'filename'},
141 'fpath' => $row->{'filepath'},
142 'networkpath' => $row->{'networkpath'},
143 'date' => $row->{'date'},
144 'type' => $row->{'filetype'},
145 'size' => $row->{'size'},
146 'id' => $row->{'fid'},
147 'dvd' => $row->{'dvd'}
148 });
149 }
150
151 $sth->finish();
152 $dbh->disconnect();
153 return ($results, \@ret);
154 }
155
156 sub getBackupsNotBurned() {
157
158 my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1 } );
159 my $sql = q{
160 SELECT
161 hosts.ID AS hostID,
162 hosts.name AS host,
163 backups.num AS backupno,
164 backups.type AS type,
165 backups.date AS date
166 FROM backups, shares, files, hosts
167 WHERE
168 backups.num = files.backupNum AND
169 shares.ID = files.shareID AND
170 backups.hostID = shares.hostID AND
171 hosts.ID = backups.hostID AND
172 files.dvdid IS NULL
173 GROUP BY
174 backups.hostID, backups.num
175 };
176 my $st = $dbh -> prepare( $sql );
177 my @ret = ();
178 $st -> execute();
179
180 while ( my $row = $st -> fetchrow_hashref() )
181 {
182 push(@ret, {
183 'host' => $row->{'host'},
184 'hostid' => $row->{'hostID'},
185 'backupno' => $row->{'backupno'},
186 'type' => $row->{'type'},
187 'date' => $row->{'date'}
188 }
189 );
190 }
191
192 return @ret;
193 }
194
195 sub displayBackupsGrid()
196 {
197 my $retHTML = "";
198 my $addForm = 1;
199
200 if ($addForm) {
201
202 $retHTML .= <<EOF3;
203 <script language="javascript" type="text/javascript">
204 <!--
205
206 function checkAll(location)
207 {
208 for (var i=0;i<document.forma.elements.length;i++)
209 {
210 var e = document.forma.elements[i];
211 if ((e.checked || !e.checked) && e.name != \'all\') {
212 if (eval("document.forma."+location+".checked")) {
213 e.checked = true;
214 } else {
215 e.checked = false;
216 }
217 }
218 }
219 }
220 //-->
221 </script>
222 EOF3
223 $retHTML .= q{<form name="forma" method="GET" action="}."$MyURL"."?action=burn\"";
224 $retHTML.= q{<input type="hidden" value="burn" name="action">};
225 $retHTML .= q{<input type="hidden" value="results" name="search_results">};
226 }
227 $retHTML .= qq{<table style="fview"><tr>};
228
229 if ($addForm) {
230 $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";
231 }
232 $retHTML .= qq{<td class="tableheader">Host</td><td class="tableheader">Backup no</td><td class="tableheader">Type</td><td class="tableheader">date</td></tr>};
233
234 my @backups = getBackupsNotBurned();
235 my $backup;
236
237 if ($addForm) {
238 $retHTML .= qq{<tr><td colspan=7 style="tableheader">
239 <input type="submit" value="Burn selected backups on medium" name="submitBurner">
240 </td></tr>};
241 }
242
243 foreach $backup(@backups) {
244
245 my $ftype = "";
246
247 $retHTML .= "<tr>";
248 if ($addForm) {
249 $retHTML .= qq{<td class="fview"><input type="checkbox" name="fcb} .
250 $backup->{'hostid'}."_".$backup->{'backupno'} .
251 qq{" value="} . $backup->{'hostid'}."_".$backup->{'backupno'} .
252 qq{"></td>};
253 }
254
255 $retHTML .= '<td class="fviewborder">' . $backup->{'host'} . '</td>' .
256 '<td class="fviewborder">' . $backup->{'backupno'} . '</td>' .
257 '<td class="fviewborder">' . $backup->{'type'} . '</td>' .
258 '<td class="fviewborder">' . epoch_to_iso( $backup->{'date'} ) . '<td>' .
259 '</tr>';
260 }
261
262 $retHTML .= "</table>";
263
264 if ($addForm) {
265 $retHTML .= "</form>";
266 }
267
268 return $retHTML;
269 }
270
271 sub displayGrid($$$$) {
272 my ($where, $addForm, $offset, $hilite) = @_;
273 my $retHTML = "";
274
275 if ($addForm) {
276 $retHTML .= qq{<form name="forma" method="GET" action="$MyURL">};
277 $retHTML.= qq{<input type="hidden" value="search" name="action">};
278 $retHTML .= qq{<input type="hidden" value="results" name="search_results">};
279 }
280
281 my ($results, $files) = getFiles($where, $offset);
282
283 my ($from, $to) = (($offset * $on_page) + 1, ($offset * $on_page) + $on_page);
284
285 $retHTML .= qq{
286 <br/>Found $results files, showing $from - $to
287 <table style="fview" width="100%">
288 <tr>
289 <td class="tableheader">Share</td>
290 <td class="tableheader">Name</td>
291 <td class="tableheader">Type</td>
292 <td class="tableheader">#</td>
293 <td class="tableheader">Size</td>
294 <td class="tableheader">Date</td>
295 <td class="tableheader">Media</td>
296 </tr>
297 };
298
299 my $file;
300
301 sub hilite_html($$) {
302 my ($html, $search) = @_;
303 $html =~ s#($search)#<b>$1</b>#gis;
304 return $html;
305 }
306
307 sub restore_link($$$$$$) {
308 my $type = shift;
309 my $action = 'RestoreFile';
310 $action = 'browse' if (lc($type) eq 'dir');
311 return sprintf(qq{<a href="?action=%s&host=%s&num=%d&share=%s&dir=%s">%s</a>}, $action, @_);
312 }
313
314 foreach $file (@{ $files }) {
315 my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
316 $retHTML .= "<tr>";
317
318 foreach my $v ((
319 $file->{'sharename'},
320 qq{<img src="$Conf{CgiImageDirURL}/icon-$typeStr.gif" align="center">&nbsp;} . hilite_html( $file->{'fpath'}, $hilite ),
321 $typeStr,
322 restore_link( $typeStr, $file->{'hname'}, $file->{'backupno'}, $file->{'sname'}, $file->{'fpath'}, $file->{'backupno'} ),
323 $file->{'size'},
324 epoch_to_iso( $file->{'date'} ),
325 $file->{'dvd'}
326 )) {
327 $retHTML .= qq{<td class="fviewborder">$v</td>};
328 }
329
330 $retHTML .= "</tr>";
331 }
332 $retHTML .= "</table>";
333
334 # all variables which has to be transfered
335 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/) {
336 $retHTML .= qq{<INPUT TYPE="hidden" NAME="$n" VALUE="$In{$n}">\n};
337 }
338
339 my $del = '';
340 my $max_page = int( $results / $on_page );
341 my $page = 0;
342
343 my $link_fmt = '<a href = "#" onclick="document.forma.offset.value=%d;document.forma.submit();">%s</a>';
344
345 $retHTML .= '<div style="text-align: center;">';
346
347 if ($offset > 0) {
348 $retHTML .= sprintf($link_fmt, $offset - 1, '&lt;&lt;') . ' ';
349 }
350
351 while ($page <= $max_page) {
352 if ($page == $offset) {
353 $retHTML .= $del . '<b>' . ($page + 1) . '</b>';
354 } else {
355 $retHTML .= $del . sprintf($link_fmt, $page, $page + 1);
356 }
357
358 if ($page < $offset - $pager_pages && $page != 0) {
359 $retHTML .= " ... ";
360 $page = $offset - $pager_pages;
361 $del = '';
362 } elsif ($page > $offset + $pager_pages && $page != $max_page) {
363 $retHTML .= " ... ";
364 $page = $max_page;
365 $del = '';
366 } else {
367 $del = ' | ';
368 $page++;
369 }
370 }
371
372 if ($offset < $max_page) {
373 $retHTML .= ' ' . sprintf($link_fmt, $offset + 1, '&gt;&gt;');
374 }
375
376 $retHTML .= "</div>";
377
378 $retHTML .= "</form>" if ($addForm);
379
380 return $retHTML;
381 }
382
383 1;

  ViewVC Help
Powered by ViewVC 1.1.26