--- loncom/interface/lonsearchcat.pm 2023/12/30 03:56:48 1.331.4.16.2.2 +++ loncom/interface/lonsearchcat.pm 2012/12/07 18:16:33 1.332 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Search Catalog # -# $Id: lonsearchcat.pm,v 1.331.4.16.2.2 2023/12/30 03:56:48 raeburn Exp $ +# $Id: lonsearchcat.pm,v 1.332 2012/12/07 18:16:33 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -52,6 +52,8 @@ search (on a server basis) is displayed =head1 Internals +=over 4 + =cut ############################################################################### @@ -78,7 +80,6 @@ use Apache::lonnavmaps; use Apache::lonindexer(); use Apache::lonwishlist(); use LONCAPA; -use Time::HiRes qw(sleep); ###################################################################### ###################################################################### @@ -144,7 +145,7 @@ sub handler { ## this once, so the pause indicator is deleted ## if (exists($env{'form.pause'})) { - sleep(0.1); + sleep(1); delete($env{'form.pause'}); } ## @@ -171,21 +172,12 @@ sub handler { &Apache::lonhtmlcommon::clear_breadcrumbs(); my @allowed_searches = ('portfolio'); - if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') { + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) { push(@allowed_searches,'res'); } my $crumb_text = 'Portfolio Search'; if (@allowed_searches ==2) { - $crumb_text = 'Portfolio and Content Library Search'; - } - my $target = '_top'; - if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) || - (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) { - if ($env{'form.phase'} =~ /^(sort|run_search)$/) { - $target = '_parent'; - } else { - $target = '_self'; - } + $crumb_text = 'Portfolio and Catalog Search'; } &Apache::lonhtmlcommon::add_breadcrumb ({href=>'/adm/searchcat?'. @@ -194,7 +186,7 @@ sub handler { '&launch='.$env{'form.launch'}. '&mode='.$env{'form.mode'}, text=>"$crumb_text", - target=>$target, + target=>'_top', bug=>'Searching',}); # if ($env{'form.phase'} !~ m/(basic|adv|course)_search/) { @@ -203,15 +195,12 @@ sub handler { &Apache::lonnet::logthis('lonsearchcat:'. 'Unable to recover data from '. $persistent_db_file); - my $msg = - &mt('We were unable to retrieve data describing your search.'). - ' '.&mt('This is a serious error and has been logged.'). - '
'. - &mt('Please alert your LON-CAPA administrator.'); - &Apache::loncommon::simple_error_page( - $r,'Search Error', - $msg, - {'no_auto_mt_msg' => 1}); + my $msg = + 'We were unable to retrieve data describing your search. '. + 'This is a serious error and has been logged. '. + 'Please alert your LON-CAPA administrator.'; + &Apache::loncommon::simple_error_page($r,'Search Error', + $msg); return OK; } } @@ -308,7 +297,7 @@ END } # if ($env{'form.searchmode'} eq 'advanced') { - my $srchtype = 'Content Library'; + my $srchtype = 'Catalog'; if ($env{'form.area'} eq 'portfolio') { $srchtype = 'Portfolio'; } @@ -332,31 +321,31 @@ END &display_results($r,$importbutton,$closebutton,$diropendb, $env{'form.area'}); } elsif ($env{'form.phase'} =~ /^(sort|run_search)$/) { - my ($query,$customquery,$customshow,$libraries,$pretty_string,$domainsref) = + my ($query,$customquery,$customshow,$libraries,$pretty_string) = &get_persistent_data($persistent_db_file, ['query','customquery','customshow', - 'libraries','pretty_string','domains']); + 'libraries','pretty_string']); if ($env{'form.phase'} eq 'sort') { - &print_sort_form($r,$pretty_string,$target); + &print_sort_form($r,$pretty_string); } elsif ($env{'form.phase'} eq 'run_search') { &run_search($r,$query,$customquery,$customshow, - $libraries,$pretty_string,$env{'form.area'},$domainsref,$target); + $libraries,$pretty_string,$env{'form.area'}); } } elsif(($env{'form.phase'} eq 'basic_search') || ($env{'form.phase'} eq 'adv_search')) { # # We are running a search, try to parse it - my ($query,$customquery,$customshow,$libraries,$domains) = - (undef,undef,undef,undef,undef); + my ($query,$customquery,$customshow,$libraries) = + (undef,undef,undef,undef); my $pretty_string; if ($env{'form.phase'} eq 'basic_search') { - ($query,$pretty_string,$libraries,$domains) = + ($query,$pretty_string,$libraries) = &parse_basic_search($r,$closebutton,$hidden_fields); return OK if (! defined($query)); &make_persistent({ basicexp => $env{'form.basicexp'}}, $persistent_db_file); } else { # Advanced search - ($query,$customquery,$customshow,$libraries,$pretty_string,$domains) + ($query,$customquery,$customshow,$libraries,$pretty_string) = &parse_advanced_search($r,$closebutton,$hidden_fields); return OK if (! defined($query)); } @@ -364,8 +353,7 @@ END customquery => $customquery, customshow => $customshow, libraries => $libraries, - pretty_string => $pretty_string, - domains => $domains }, + pretty_string => $pretty_string }, $persistent_db_file); # # Set up table @@ -439,9 +427,7 @@ sub hidden_field { ###################################################################### -=pod - -=over 4 +=pod =item &print_basic_search_form() @@ -459,7 +445,7 @@ sub print_basic_search_form { $env{'form.catalogmode'} ne 'import'); my $scrout = &Apache::loncommon::start_page('Content Library').$bread_crumb; # Search form for resource space - if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') { + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) { $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton); $scrout .= '

'; } @@ -474,7 +460,7 @@ sub setup_basic_search { my ($r,$area,$hidden_fields,$closebutton) = @_; # Define interface components my %lt = &Apache::lonlocal::texthash ( - res => 'Content Library Search', + res => 'LON-CAPA Catalog Search', portfolio => 'Portfolio Search', ); my ($userelatedwords,$onlysearchdomain,$inclext,$adv_search_link,$scrout); @@ -488,31 +474,14 @@ sub setup_basic_search { .&mt('use related words') .''; - my $anydom = 1; - if ($area eq 'res') { - unless (&Apache::lonnet::allowed('bre','/res/') eq 'F') { - $anydom = 0; - } - } - my $singledom; - my ($disabled,$checked); - if ($anydom) { - $singledom = $r->dir_config('lonDefDomain'); - if ($env{'form.domains'} eq $singledom) { - $checked = 1; - } - } else { - $singledom = $env{'user.domain'}; - $disabled = ' disabled="disabled"'; - $checked = 1; - } $onlysearchdomain = ''; $adv_search_link = '\n"; } @@ -1469,12 +1401,11 @@ sub parse_advanced_search { } #&Apache::lonnet::logthis('advanced query = '.$/.$query); return ($query,$customquery,$customshow,$libraries_to_query, - $pretty_search_string,$domains_to_query); + $pretty_search_string); } sub parse_domain_restrictions { my $libraries_to_query = undef; - my $domains_to_query = undef; # $env{'form.domains'} can be either a scalar or an array reference. # We need an array. if (! exists($env{'form.domains'}) || $env{'form.domains'} eq '') { @@ -1498,32 +1429,12 @@ sub parse_domain_restrictions { foreach (sort @allowed_domains) { $pretty_domains_string .= "".$_." "; } - my %library_servers = &Apache::lonnet::get_unique_servers(\@allowed_domains, - 'library'); - my (%older_library_servers,%okdoms,%domains_for_id); - map { $okdoms{$_} = 1; } @allowed_domains; - foreach my $key (keys(%library_servers)) { - if (&Apache::lonnet::get_server_loncaparev('',$key) =~ /^\'?(\d+)\.(\d+)/) { - my $major = $1; - my $minor = $2; - if (($major < 2) || (($major == 2) && ($minor < 11))) { - map { $older_library_servers{$_} = 1; } - &Apache::lonnet::machine_ids($library_servers{$key}); - } else { - my %possdoms; - map { $possdoms{$_}=1 if ($okdoms{$_}); } - &Apache::lonnet::machine_domains($library_servers{$key}); - $domains_for_id{$key} = join(',',sort(keys(%possdoms))); - } - } - } - my %servers = (%library_servers,%older_library_servers); + my %servers = &Apache::lonnet::get_unique_servers(\@allowed_domains, + 'library'); $libraries_to_query = [keys(%servers)]; - $domains_to_query = \%domains_for_id; } return ($libraries_to_query, - $pretty_domains_string, - $domains_to_query); + $pretty_domains_string); } ###################################################################### @@ -1552,8 +1463,7 @@ sub parse_basic_search { $env{"form.$_"}=&unescape($env{"form.$_"}); $env{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g; } - my ($libraries_to_query,$pretty_domains_string,$domains_to_query) = - &parse_domain_restrictions(); + my ($libraries_to_query,$pretty_domains_string) = &parse_domain_restrictions(); # # Check to see if enough of a query is filled in my $search_string = $env{'form.basicexp'}; @@ -1599,7 +1509,7 @@ sub parse_basic_search { $pretty_search_string =~ s:^
and ::; &Apache::lonnet::logthis('simple search final query = '.$/.$final_query); return ($final_query,$pretty_search_string, - $libraries_to_query,$domains_to_query); + $libraries_to_query); } @@ -1871,14 +1781,14 @@ sub build_date_queries { if ((defined($cafter) && ! defined($cbefore)) || (defined($cbefore) && ! defined($cafter))) { # This is bad, so let them know - $error = &mt('Incorrect entry for the creation date. '. + $error = &mt('Incorrect entry for the creation date. '. 'You must specify both the beginning and ending dates.'); } if (! defined($error) && ((defined($mafter) && ! defined($mbefore)) || (defined($mbefore) && ! defined($mafter)))) { # This is also bad, so let them know - $error = &mt('Incorrect entry for the last revision date. '. + $error = &mt('Incorrect entry for the last revision date. '. 'You must specify both the beginning and ending dates.'); } if (! defined($error)) { @@ -1890,8 +1800,6 @@ sub build_date_queries { my (undef,undef,undef,$cbday,$cbmon,$cbyear) = localtime($cbefore); # Correct for year being relative to 1900 $cayear+=1900; $cbyear+=1900; - # Correct month; localtime gives month 0..11 but MySQL expects 1..12 - $camon++; $cbmon++; my $cquery= '(creationdate BETWEEN '. "'".$cayear.'-'.$camon.'-'.$caday."'". @@ -1910,8 +1818,6 @@ sub build_date_queries { my (undef,undef,undef,$mbday,$mbmon,$mbyear) = localtime($mbefore); # Correct for year being relative to 1900 $mayear+=1900; $mbyear+=1900; - # Correct month; localtime gives month 0..11 but MySQL expects 1..12 - $mamon++; $mbmon++; my $mquery= '(lastrevisiondate BETWEEN '. "'".$mayear.'-'.$mamon.'-'.$maday."'". @@ -1954,11 +1860,10 @@ sub copyright_check { my (undef,undef,$resdom,$resname) = split('/', $Metadata->{'url'}); # Check for priv - if ($Metadata->{'copyright'} eq 'priv') { - unless (($env{'user.name'} eq $resname) && - ($env{'user.domain'} eq $resdom)) { - return 0; - } + if (($Metadata->{'copyright'} eq 'priv') && + (($env{'user.name'} ne $resname) && + ($env{'user.domain'} ne $resdom))) { + return 0; } # Check for domain if (($Metadata->{'copyright'} eq 'domain') && @@ -1996,13 +1901,11 @@ sub ensure_db_and_table { ## Sanity check the table id. ## if (! defined($table) || $table eq '' || $table =~ /\D/ ) { - $r->print(&Apache::loncommon::start_page('Error') + $r->print(&Apache::loncommon::start_page(&mt('Error')) +. '

table: |'.$table.'|

' # SB .'

' .&mt('Unable to retrieve search results. ' .'Unable to determine the table results were saved in.') - .'

' - . '

'.&mt('Internal info:').'

' - .'
'.$table.'
' .&Apache::loncommon::end_page() ); return undef; @@ -2061,7 +1964,7 @@ a link to change the search query. ###################################################################### ###################################################################### sub print_sort_form { - my ($r,$pretty_query_string,$target) = @_; + my ($r,$pretty_query_string) = @_; ## my %SortableFields=&Apache::lonlocal::texthash( @@ -2108,20 +2011,15 @@ sub print_sort_form { END - my $args; - if ($target eq '_parent') { - $args = {'links_target' => $target}; - } - my $start_page = &Apache::loncommon::start_page('Results',undef,$args); + my $start_page = &Apache::loncommon::start_page('Results',$js); my $breadcrumbs= &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching', - $env{'form.catalogmode'} ne 'import', - '','','','','','',$target); + $env{'form.catalogmode'} ne 'import'); my $result = < +
END @@ -2139,7 +2037,7 @@ END # $result.="\n"; my $revise = &revise_button(); $result.='

' - .&mt('Total of [quant,_1,match,matches] to your query.',$total_results) + .&mt('There are [_1] matches to your query.',$total_results) .' '.$revise.'

' .'

'.&mt('Search: ').$pretty_query_string .'

'; @@ -2277,21 +2175,8 @@ SCRIPT $r->rflush(); } -sub reload_result_frame { - my ($r) = @_; - my $newloc = '/adm/searchcat?phase=results&persistent_db_id='. - $env{'form.persistent_db_id'}; - $r->print(< - parent.update_results("$newloc"); - -SCRIPT - - $r->rflush(); -} - { - my $max_time = 60; # seconds for the search to complete + my $max_time = 300; # seconds for the search to complete my $start_time = 0; my $last_time = 0; @@ -2372,7 +2257,7 @@ results into MySQL. ###################################################################### sub run_search { my ($r,$query,$customquery,$customshow,$serverlist, - $pretty_string,$area,$domainsref,$target) = @_; + $pretty_string,$area) = @_; my $tabletype = 'metadata'; if ($area eq 'portfolio') { $tabletype = 'portfolio_search'; @@ -2381,15 +2266,10 @@ sub run_search { # # Print run_search header # - my $args; - if ($target eq '_parent') { - $args = {'links_target' => $target}; - } - my $start_page = &Apache::loncommon::start_page('Search Status',undef,$args); + my $start_page = &Apache::loncommon::start_page('Search Status',undef); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching', - $env{'form.catalogmode'} ne 'import', - '','','','','','',$target); + $env{'form.catalogmode'} ne 'import'); $r->print(<rflush(); # # Determine the servers we need to contact. - my (@Servers_to_contact,%domains_by_server); + my @Servers_to_contact; if (defined($serverlist)) { if (ref($serverlist) eq 'ARRAY') { @Servers_to_contact = @$serverlist; } else { @Servers_to_contact = ($serverlist); } - if (ref($domainsref) eq 'HASH') { - foreach my $server (@Servers_to_contact) { - $domains_by_server{$server} = $domainsref->{$server}; - } - } } else { - my %library_servers = &Apache::lonnet::unique_library(); - my (%all_library_servers, %older_library_servers); - foreach my $key (keys(%library_servers)) { - if (&Apache::lonnet::get_server_loncaparev('',$key) =~ /^\'?(\d+)\.(\d+)/) { - my $major = $1; - my $minor = $2; - if (($major < 2) || (($major == 2) && ($minor < 11))) { - map { $older_library_servers{$_} = 1; } - &Apache::lonnet::machine_ids($library_servers{$key}); - } - } - } - %all_library_servers = (%library_servers,%older_library_servers); + my %all_library_servers = &Apache::lonnet::unique_library(); @Servers_to_contact = sort(keys(%all_library_servers)); - foreach my $server (@Servers_to_contact) { - my %possdoms; - map { $possdoms{$_}=1; } &Apache::lonnet::machine_domains($all_library_servers{$server}); - $domains_by_server{$server} = - join(',',sort(&Apache::lonnet::machine_domains($all_library_servers{$server}))); - } } my %Server_status; # @@ -2477,8 +2334,6 @@ END ## ## Prepare for the big loop. my $hitcountsum; - my $oldhitcountsum; - my $displaycount; my %matches; my $server; my $status; @@ -2513,7 +2368,7 @@ END my $server = shift(@Servers_to_contact); &update_status($r,&mt('contacting [_1]',$server)); my $reply=&Apache::lonnet::metadata_query($query,$customquery, - $customshow,[$server],\%domains_by_server); + $customshow,[$server]); ($server) = keys(%$reply); $Server_status{$server} = $reply->{$server}; } else { @@ -2525,7 +2380,7 @@ END &update_status($r, &mt('waiting on [_1]',join(' ',keys(%Server_status)))); } - sleep(0.1); + sleep(1); } # # Loop through the servers we have contacted but do not @@ -2578,8 +2433,8 @@ END if ($area eq 'portfolio') { next if (defined($matches{$Fields{'url'}})); - # Skip unless access control set to public or passphrase-protected - next unless (($Fields{'scope'} eq 'public') || ($Fields{'scope'} eq 'guest')); + # Skip if inaccessible + next if (!&Apache::lonnet::portfolio_access($Fields{'url'})); $matches{$Fields{'url'}} = 1; } # @@ -2601,15 +2456,7 @@ END delete($Server_status{$server}); } last if ($connection->aborted()); - if ($oldhitcountsum < $hitcountsum) { - &update_count_status($r,$hitcountsum); - if (($hitcountsum <= $env{'form.show'}) || - (!$displaycount && $hitcountsum)) { - reload_result_frame($r); - $displaycount = $hitcountsum; - } - $oldhitcountsum = $hitcountsum; - } + &update_count_status($r,$hitcountsum); } last if ($connection->aborted()); &update_seconds($r); @@ -2703,8 +2550,6 @@ sub display_results { if ($env{'form.catalogmode'} eq 'import') { if (! tie(%groupsearch_db,'GDBM_File',$diropendb, &GDBM_WRCREAT(),0640)) { - # NOTE: this can happen when a previous request to searchcat?phase=results gets interrupted - # (%groupsearch_db is not untied) $r->print('

'. &mt('Unable to save import results.'). '

'. @@ -2712,11 +2557,7 @@ sub display_results { &Apache::loncommon::end_page()); $r->rflush(); return; - } - # untie %groupsearch_db if the connection gets aborted before the end - $r->register_cleanup(sub { - untie %groupsearch_db if (tied(%groupsearch_db)); - }); + } } ## ## Prepare the table for querying @@ -2858,7 +2699,8 @@ sub display_results { ); if ($total_results == 0) { - $r->print('

'.&mt('There are currently no results.').'

'. + $r->print(''. + '

'.&mt('There are currently no results.').'

'. "". &Apache::loncommon::end_page()); return; @@ -3231,18 +3073,9 @@ SCRIPT SCRIPT - $js.=< - \$(document).ready(function() { - parent.done_loading_results(); - }); - -SCRIPT - my $start_page = &Apache::loncommon::start_page(undef,$js, {'only_body' =>1, - 'add_wishlist' =>1, - 'add_modal' =>1}); + 'add_wishlist' =>1}); my $result=< @@ -3272,26 +3105,6 @@ sub print_frames_interface { // JS @@ -3404,7 +3217,7 @@ sub detailed_citation_view { ''.$prefix. ''.' '. '
'.$values{'title'}."\n". + 'target="preview">'.$values{'title'}."\n". &display_tools($values{'title'}, $jumpurl). "

\n". ''.$values{'author'}.','. @@ -3537,7 +3350,7 @@ sub summary_view { my $link = '
'.&display_url($jumpurl,1).'
'; $result .= ''.$values{'title'}.''. + ' target="preview">'.$values{'title'}.''. &display_tools($values{'title'}, $jumpurl).< $link
@@ -3583,7 +3396,7 @@ sub compact_view { } $jumpurl = &HTML::Entities::encode($jumpurl,'<>&"'); $result.=' '. - ''. + ''. &HTML::Entities::encode($values{'title'},'<>&"').' '. &display_tools($values{'title'}, $jumpurl). $link.' '.$values{'author'}.' ('.$values{'domain'}.')'; @@ -3599,17 +3412,12 @@ sub display_url { } elsif ($url=~m{^(http://|/uploaded/)}) { $link=''.$url.''; } else { - # replace the links to open in a new window - # (because the search opens in a new window, it gets - # confusing when the links open a tab in the - # parent window; ideally we should not force windows) - my $onclick = " onclick=\"window.open(this.href, '_blank', 'toolbar=1,location=1,menubar=0');return false;\""; $link=&Apache::lonhtmlcommon::crumbs( $url, 'preview', '', - '', - $skiplast,$onclick).' '; + (($env{'form.catalogmode'} eq 'import')?'parent.statusframe.document.forms.statusform':''), + $skiplast).' '; } return $link; } @@ -3915,7 +3723,7 @@ Cleans the global %groupsearch_db by rem ###################################################################### sub start_fresh_session { delete $groupsearch_db{'mode_catalog'}; - foreach (keys(%groupsearch_db)) { + foreach (keys %groupsearch_db) { if ($_ =~ /^pre_/) { delete $groupsearch_db{$_}; } @@ -3933,6 +3741,7 @@ sub cleanup { &Apache::lonnet::logthis('Failed cleanup searchcat: groupsearch_db'); } } + &untiehash(); &Apache::lonmysql::disconnect_from_db(); return OK; }