/[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

Annotation of /trunk/lib/BackupPC/SearchLib.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 66 - (hide annotations)
Mon Aug 22 00:09:59 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 11052 byte(s)
calculate size for each backup (this is more accurate than reading meta data
if you aren't staring from clean BackupPC installation).

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

  ViewVC Help
Powered by ViewVC 1.1.26