--- trunk/lib/BackupPC/SearchLib.pm 2005/08/28 12:35:59 86 +++ trunk/lib/BackupPC/SearchLib.pm 2005/09/22 14:25:51 129 @@ -15,11 +15,7 @@ my $dsn = $Conf{SearchDSN}; my $db_user = $Conf{SearchUser} || ''; -my $index_path = $Conf{HyperEstraierIndex}; -if ($index_path) { - $index_path = $TopDir . '/' . $index_path; - $index_path =~ s#//#/#g; -} +my $hest_index_path = $Conf{HyperEstraierIndex}; my $dbh; @@ -62,25 +58,34 @@ sub mk_epoch_date($$) { my ($name,$suffix) = @_; - my $yyyy = $param->{ $name . '_year_' . $suffix} || return; + my $yyyy = $param->{ $name . '_year_' . $suffix} || return undef; my $mm .= $param->{ $name . '_month_' . $suffix} || ( $suffix eq 'from' ? 1 : 12); my $dd .= $param->{ $name . '_day_' . $suffix} || ( $suffix eq 'from' ? 1 : 31); + + $yyyy =~ s/\D//g; + $mm =~ s/\D//g; + $dd =~ s/\D//g; + my $dt = new DateTime( year => $yyyy, month => $mm, day => $dd ); + print STDERR "mk_epoch_date($name,$suffix) [$yyyy-$mm-$dd] = " . $dt->ymd . " " . $dt->hms . "\n"; return $dt->epoch || 'NULL'; } - return ( + my @ret = ( mk_epoch_date('search_backup', 'from'), mk_epoch_date('search_backup', 'to'), mk_epoch_date('search', 'from'), mk_epoch_date('search', 'to'), ); + + return @ret; + } @@ -104,8 +109,11 @@ } -sub getFiles($$) { - my ($param, $offset) = @_; +sub getFiles($) { + my ($param) = @_; + + my $offset = $param->{'offset'} || 0; + $offset *= $on_page; my $dbh = get_dbh(); @@ -113,26 +121,18 @@ files.id AS fid, hosts.name AS hname, shares.name AS sname, - -- shares.share AS sharename, files.backupnum AS backupnum, - -- files.name AS filename, files.path AS filepath, files.date AS date, files.type AS type, - files.size AS size, - -- dvds.name AS dvd - null AS dvd + files.size AS size }; my $sql_from = qq{ FROM files INNER JOIN shares ON files.shareID=shares.ID INNER JOIN hosts ON hosts.ID = shares.hostID - INNER JOIN backups ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = shares.ID - }; - - my $sql_dvd_from = qq{ - -- LEFT JOIN dvds ON dvds.ID = files.dvdid + INNER JOIN backups ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = files.shareID }; my $sql_where; @@ -146,10 +146,7 @@ }; my $sql_count = qq{ select count(files.id) $sql_from $sql_where }; - my $sql_results = qq{ select $sql_cols $sql_from $sql_dvd_from $sql_where $sql_order }; - - $offset ||= 0; - $offset = ($offset * $on_page); + my $sql_results = qq{ select $sql_cols $sql_from $sql_where $sql_order }; my $sth = $dbh->prepare($sql_count); $sth->execute(); @@ -174,16 +171,46 @@ return ($results, \@ret); } -sub getFilesHyperEstraier($$) { - my ($param, $offset) = @_; +sub getHyperEstraier_url($) { + my ($use_hest) = @_; + + return unless $use_hest; + + use HyperEstraier; + my ($index_path, $index_node_url); + + if ($use_hest =~ m#^http://#) { + $index_node_url = $use_hest; + } else { + $index_path = $TopDir . '/' . $index_path; + $index_path =~ s#//#/#g; + } + return ($index_path, $index_node_url); +} + +sub getFilesHyperEstraier($) { + my ($param) = @_; + + my $offset = $param->{'offset'} || 0; + $offset *= $on_page; - die "no index_path?" unless ($index_path); + die "no index_path?" unless ($hest_index_path); use HyperEstraier; + my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path); + # open the database - my $db = HyperEstraier::Database->new(); - $db->open($index_path, $HyperEstraier::ESTDBREADER); + my $db; + if ($index_path) { + $db = HyperEstraier::Database->new(); + $db->open($index_path, $HyperEstraier::ESTDBREADER); + } elsif ($index_node_url) { + $db ||= HyperEstraier::Node->new($index_node_url); + $db->set_auth('admin', 'admin'); + } else { + die "BUG: unimplemented"; + } # create a search condition object my $cond = HyperEstraier::Condition->new(); @@ -191,41 +218,56 @@ my $q = $param->{'search_filename'}; my $shareid = $param->{'search_share'}; - if ($q) { - $q =~ s/(.)/$1 /g; + if (length($q) > 0) { + # exact match + $cond->add_attr("filepath ISTRINC $q"); + $q =~ s/(.)/$1 /g; # set the search phrase to the search condition object $cond->set_phrase($q); + } - my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param); - - $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from); - $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to); + my ($backup_from, $backup_to, $files_from, $files_to) = dates_from_form($param); - $cond->add_attr("date NUMGE $files_from") if ($files_from); - $cond->add_attr("date NUMLE $files_to") if ($files_to); + $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from); + $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to); - $cond->add_attr("shareid NUMEQ $shareid") if ($shareid); - } + $cond->add_attr("date NUMGE $files_from") if ($files_from); + $cond->add_attr("date NUMLE $files_to") if ($files_to); - $offset ||= 0; - $offset = ($offset * $on_page); + $cond->add_attr("shareid NUMEQ $shareid") if ($shareid); # $cond->set_max( $offset + $on_page ); $cond->set_options( $HyperEstraier::Condition::SURE ); $cond->set_order( 'date NUMA' ); # get the result of search - my $result = $db->search($cond, 0); - $result->get(0); - my @res; - my $hits = $result->size; + my ($result, $hits); + + if ($index_path) { + $result = $db->search($cond, 0); + $hits = $result->size; + } elsif ($index_node_url) { + $result = $db->search($cond, 0); + $hits = $result->doc_num; + } else { + die "BUG: unimplemented"; + } # for each document in result - for my $i ($offset .. $result->size-1) { - my $id = $result->get($i); - my $doc = $db->get_doc($id, 0); + for my $i ($offset .. ($offset + $on_page - 1)) { + last if ($i >= $hits); + + my $doc; + if ($index_path) { + my $id = $result->get($i); + $doc = $db->get_doc($id, 0); + } elsif ($index_node_url) { + $doc = $result->get_doc($i); + } else { + die "BUG: unimplemented"; + } my $row; foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) { @@ -237,26 +279,49 @@ return ($hits, \@res); } +sub getGzipName($$$) +{ + my ($host, $share, $backupnum) = @_; + my $ret = $Conf{GzipSchema}; + + $share =~ s/\//_/g; + $ret =~ s/\\h/$host/ge; + $ret =~ s/\\s/$share/ge; + $ret =~ s/\\n/$backupnum/ge; + + return $ret; + +} + sub getBackupsNotBurned() { my $dbh = get_dbh(); - my $sql = q{ - SELECT - backups.hostID AS hostid, - min(hosts.name) AS host, - backups.num AS backupnum, - min(backups.type) AS type, - min(backups.date) AS date, - min(backups.size) AS size - FROM files - INNER JOIN shares ON files.shareID=shares.ID - INNER JOIN hosts ON hosts.ID = shares.hostID - INNER JOIN backups ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = shares.ID - WHERE - files.dvdid IS NULL - GROUP BY - backups.hostID, backups.num - ORDER BY min(backups.date) + + my $sql = q{ + SELECT + backups.hostID AS hostID, + hosts.name AS host, + shares.name AS share, + backups.id AS backupnum, + backups.type AS type, + backups.date AS date, + backups.size AS size + FROM backups + INNER JOIN shares ON backups.shareID=shares.ID + INNER JOIN hosts ON backups.hostID = hosts.ID + LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id AND archive_backup.backup_id IS NULL + WHERE backups.size > 0 + GROUP BY + backups.hostID, + hosts.name, + shares.name, + backups.num, + backups.shareid, + backups.id, + backups.type, + backups.date, + backups.size + ORDER BY backups.date }; my $sth = $dbh->prepare( $sql ); my @ret; @@ -265,99 +330,360 @@ while ( my $row = $sth->fetchrow_hashref() ) { $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) ); $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024); + my (undef,undef,undef,undef,undef,undef,undef,$fs_size,undef,undef,undef,undef,undef) = + stat( $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'. + getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'})); + $row->{'fs_size'} = $fs_size; push @ret, $row; } return @ret; } -sub displayBackupsGrid() - { - my $retHTML = ""; - my $addForm = 1; - - if ($addForm) { +sub displayBackupsGrid() { + + my $retHTML .= q{ +
+ }; + + $retHTML .= <<'EOF3'; + -EOF3 - $retHTML .= q{}; - $retHTML .= q{}; +var debug_div = null; +var media_size = 4400 * 1024; + +function debug(msg) { +// return; // Disable debugging + + if (! debug_div) debug_div = document.getElementById('debug'); + + // this will create debug div if it doesn't exist. + if (! debug_div) { + debug_div = document.createElement('div'); + if (document.body) document.body.appendChild(debug_div); + else debug_div = null; + } + if (debug_div) { + debug_div.appendChild(document.createTextNode(msg)); + debug_div.appendChild(document.createElement("br")); } - $retHTML .= qq{ - - - }; +} + - if ($addForm) { - $retHTML .= ""; +var element_id_cache = Array(); + +function element_id(name,element) { + if (! element_id_cache[name]) { + element_id_cache[name] = self.document.getElementById(name); } - $retHTML .= qq{ - - - - - - - - }; + return element_id_cache[name]; +} + +function checkAll(location) { + var len = element_id('forma').elements.length; + var check_all = element_id('allFiles'); + var suma = 0; + + for (var i = 0; i < len; i++) { + + var e = element_id('forma').elements[i]; + if (e.name != 'all' && e.name.substr(0,3) == 'fcb') { + if (check_all.checked) { + var el = element_id("fss" + e.name.substr(3)); + var size = parseInt(el.value) || 0; + debug('suma: '+suma+' size: '+size); + if ((suma + size) < media_size) { + suma += size; + e.checked = true; + } else { + break; + } + } else { + e.checked = false; + } + } + } + update_sum(suma); +} - my @backups = getBackupsNotBurned(); - my $backup; +function update_sum(suma) { + element_id('forma').totalsize.value = suma; + pbar_set(suma, media_size); + debug('total size: '+suma); +} - if ($addForm) { - $retHTML .= qq{ - - }; +function sumiraj(e) { + var suma = parseInt(element_id('forma').totalsize.value) || 0; + var len = element_id('forma').elements.length; + if (e) { + var size = parseInt( element_id("fss" + e.name.substr(3)).value ); + if (e.checked) { + suma += size; + } else { + suma -= size; + } + } else { + suma = 0; + for (var i = 0; i < len; i++) { + var e = element_id('forma').elements[i]; + if (e.name != 'all' && e.checked && e.name.substr(0,3) == 'fcb') { + var el = element_id("fss" + e.name.substr(3)); + if (el && el.value) suma += parseInt(el.value) || 0; + } + } } + update_sum(suma); + return suma; +} - foreach $backup(@backups) { +/* progress bar */ - my $ftype = ""; - - $retHTML .= ""; - if ($addForm) { - $retHTML .= ''; - } - - $retHTML .= '' . - '' . - '' . - '' . - '' . - '' . - ''; +var _pbar_width = 0; +var _pbar_warn = 10; // change color in last 10% + +function pbar_reset() { + element_id("mask").style.left = "0px"; + _pbar_width = element_id("mContainer").offsetWidth - 2; + element_id("mask").style.width = _pbar_width + "px"; + element_id("progressIndicator").style.zIndex = 10; + element_id("mask").style.display = "block"; + element_id("progressIndicator").innerHTML = "0"; +} + +function dec2hex(d) { + var hch="0123456789ABCDEF"; + var a=d%16; + var q=(d-a)/16; + return hch.charAt(q)+hch.charAt(a); +} + + +function pbar_set(amount, max) { + + debug('pbar_set( '+amount+' , '+max+' )'); + + curWidth = parseInt(element_id("mask").offsetWidth); + curLeft = parseInt(element_id("mask").offsetLeft); + + + var pcnt = Math.floor( amount * 100 / max ); + var p90 = 100 - _pbar_warn; + var pcol = pcnt - p90; + if (pcol < _pbar_warn) { + if (pcol < 0) pcol = 0; + var e = element_id("submitBurner"); + if (e && e.disabled) { + debug('enable_button'); + var a = e.getAttributeNode('disabled') || null; + if (a) e.removeAttributeNode(a); + } + } else if (pcol > _pbar_warn) { + debug('disable button'); + pcol = _pbar_warn; + var e = element_id("submitBurner"); + if (! e.disabled) e.disabled = true; } + var col_g = Math.floor( ( _pbar_warn - pcol ) * 255 / _pbar_warn ); + var col = '#ff' + dec2hex( col_g ) + '00'; - $retHTML .= "
HostBackup noTypedateage/dayssize/MB
- -
' . $backup->{'host'} . '' . $backup->{'backupnum'} . '' . $backup->{'type'} . '' . epoch_to_iso( $backup->{'date'} ) . '' . $backup->{'age'} . '' . $backup->{'size'} . '
"; + //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col); + element_id("gradient").style.backgroundColor = col; + + var size = parseInt( _pbar_width * amount / max ); + + curWidth = _pbar_width - size; + curLeft = size ; - if ($addForm) { - $retHTML .= "
"; + //debug('size: '+size+' curWidth '+curWidth+' curLeft: '+curLeft); + + element_id("progressIndicator").innerHTML = pcnt + '%'; + //element_id("progressIndicator").innerHTML = amount; + + if (curLeft > _pbar_width) { + element_id("mask").style.display = "none"; + return; + } else { + element_id("mask").style.display = ""; + } + + //if(parseInt(element_id("mask").offsetWidth)>10) + element_id("mask").style.width = curWidth + "px"; + element_id("mask").style.left = curLeft + "px"; + +} + +if (!self.body) self.body = new Object(); +self.onload = self.document.onload = self.body.onload = function() { + pbar_reset(); + sumiraj(); +} + +//--> + +
+ +Size: + + +
+
+
+
 
+
+ +
+Note: +
+ +
+ + +
+
+no debug output yet +
+EOF3 + $retHTML .= q{ + + + + + + + + + + + + + + + }; + + my @color = (' bgcolor="#e0e0e0"', ''); + + my $i = 0; + my $host = ''; + + foreach my $backup ( getBackupsNotBurned() ) { + + if ($host ne $backup->{'host'}) { + $i++; + $host = $backup->{'host'}; + } + my $ftype = ""; + + $retHTML .= + ' + ' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + + "\n"; } + + $retHTML .= "
+ + ShareBackup noTypedateage/dayssize/MBgzip size
'; + # FIXME + $backup->{'fs_size'} = int($backup->{'size'} * 1024); + if (($backup->{'fs_size'} || 0) > 0) { + $retHTML .= ' + '; + } + $retHTML .= + '' . $backup->{'host'} . ':' . $backup->{'share'} . '' . $backup->{'backupnum'} . '' . $backup->{'type'} . '' . epoch_to_iso( $backup->{'date'} ) . '' . $backup->{'age'} . '' . $backup->{'size'} . '' . $backup->{'fs_size'} . + '
"; + $retHTML .= ""; return $retHTML; } @@ -373,10 +699,10 @@ my $start_t = time(); my ($results, $files); - if ($param->{'use_hest'}) { - ($results, $files) = getFilesHyperEstraier($param, $offset); + if ($param->{'use_hest'} && length($hilite) > 0) { + ($results, $files) = getFilesHyperEstraier($param); } else { - ($results, $files) = getFiles($param, $offset); + ($results, $files) = getFiles($param); } my $dur_t = time() - $start_t; @@ -402,6 +728,7 @@ + @@ -426,17 +753,23 @@ return sprintf(qq{%s}, $action, @_); } + my $i = $offset * $on_page; + foreach $file (@{ $files }) { + $i++; + my $typeStr = BackupPC::Attrib::fileType2Text(undef, $file->{'type'}); $retHTML .= qq{}; + $retHTML .= qq{}; + $retHTML .= qq{} . qq{} . qq{} . qq{} . qq{} . - qq{}; + qq{}; $retHTML .= ""; }
Share Type and Name #
$i} . $file->{'hname'} . ':' . $file->{'sname'} . qq{$typeStr } . hilite_html( $file->{'filepath'}, $hilite ) . qq{} . restore_link( $typeStr, ${EscURI( $file->{'hname'} )}, $file->{'backupnum'}, ${EscURI( $file->{'sname'})}, ${EscURI( $file->{'filepath'} )}, $file->{'backupnum'} ) . qq{} . $file->{'size'} . qq{} . epoch_to_iso( $file->{'date'} ) . qq{} . $file->{'dvd'} . qq{} . '?' . qq{