--- loncom/interface/lonsearchcat.pm 2002/06/24 15:09:52 1.126
+++ loncom/interface/lonsearchcat.pm 2002/07/29 21:53:57 1.146
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Search Catalog
#
-# $Id: lonsearchcat.pm,v 1.126 2002/06/24 15:09:52 matthew Exp $
+# $Id: lonsearchcat.pm,v 1.146 2002/07/29 21:53:57 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -40,7 +40,7 @@
=head1 NAME
-lonsearchcat
+lonsearchcat - LONCAPA Search Interface
=head1 SYNOPSIS
@@ -67,14 +67,14 @@ search (on a server basis) is displayed
###############################################################################
###############################################################################
+###############################################################################
## ##
## ORGANIZATION OF THIS PERL MODULE ##
## ##
## 1. Modules used by this module ##
-## 2. Choices for different output views (detailed, summary, xml, etc) ##
-## 3. BEGIN block (to be run once after compilation) ##
-## 4. Handling routine called via Apache and mod_perl ##
-## 5. Other subroutines ##
+## 2. Variables used throughout the module ##
+## 3. handler subroutine called via Apache and mod_perl ##
+## 4. Other subroutines ##
## ##
###############################################################################
@@ -87,8 +87,10 @@ use Apache::lonnet();
use Apache::File();
use CGI qw(:standard);
use Text::Query;
+use DBI;
use GDBM_File;
use Apache::loncommon();
+use Apache::lonmysql();
# ---------------------------------------- variables used throughout the module
@@ -101,35 +103,26 @@ use Apache::loncommon();
=over 4
-=item %hostdomains
-
-matches host name to host domain
-
-=item %hostips
-
-matches host name to host ip
-
-=item %hitcount
-
-stores number of hits per host
-
-=item $closebutton
-
-button that closes the search window
-
=item $importbutton
-button to take the selecte results and go to group sorting
+button to take the select results and go to group sorting
-=item %hash
+=item %groupsearch_db
-The ubiquitous database hash
+Database hash used to save values for the groupsearch RAT interface.
=item $diropendb
The full path to the (temporary) search database file. This is set and
used in &handler() and is also used in &output_results().
+=item %Views
+
+Hash which associates an output view description with the function
+that produces it. Adding a new view type should be as easy as
+adding a line to the definition of this hash and making sure the function
+takes the proper parameters.
+
=back
=cut
@@ -137,47 +130,19 @@ used in &handler() and is also used in &
######################################################################
######################################################################
-# -- information holders
-my %hostdomains; # matches host name to host domain
-my %hostips; # matches host name to host ip
-my %hitcount; # stores number of hits per host
-
# -- dynamically rendered interface components
-my $closebutton; # button that closes the search window
my $importbutton; # button to take the selected results and go to group sorting
# -- miscellaneous variables
-my $yourself; # allows for quickly limiting to oneself
-my %hash; # database hash
-
-# ------------------------------------------ choices for different output views
-# Detailed Citation View ---> sub detailed_citation_view
-# Summary View ---> sub summary_view
-# Fielded Format ---> sub fielded_format_view
-# XML/SGML ---> sub xml_sgml_view
-
-#------------------------------------------------------------- global variables
-my $diropendb = "";
-my $domain = "";
-
-# ----------------------------------------------------------------------- BEGIN
-
-=pod
-
-=item BEGIN block
-
-Load %hostdomains and %hostips with data from lonnet.pm. Only library
-servers are considered.
-
-=cut
-
-BEGIN {
- foreach (keys (%Apache::lonnet::libserv)) {
- $hostdomains{$_}=$Apache::lonnet::hostdom{$_};
- $hostips{$_}=$Apache::lonnet::hostip{$_};
- }
-}
-
+my %groupsearch_db; # database hash
+my $diropendb = ""; # db file
+# View Description Function Pointer
+my %Views = ("Detailed Citation View" => \&detailed_citation_view,
+ "Summary View" => \&summary_view,
+ "Fielded Format" => \&fielded_format_view,
+ "XML/SGML" => \&xml_sgml_view );
+my %persistent_db;
+my $hidden_fields;
######################################################################
######################################################################
@@ -205,26 +170,57 @@ string that holds portions of the screen
######################################################################
sub handler {
my $r = shift;
- untie %hash;
-
+ #
+ my $closebutton; # button that closes the search window
+ # This button is different for the RAT compared to
+ # normal invocation.
+ #
$r->content_type('text/html');
$r->send_http_header;
return OK if $r->header_only;
-
+ ##
+ ## Pick up form fields passed in the links.
+ ##
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+ ['catalogmode','launch','acts','mode','form','element','pause',
+ 'phase','persistent_db_id','table','start','show']);
+ ##
+ ## The following is a trick - we wait a few seconds if asked to so
+ ## the daemon running the search can get ahead of the daemon
+ ## printing the results. We only need (theoretically) to do
+ ## this once, so the pause indicator is deleted
+ ##
+ if (exists($ENV{'form.pause'})) {
+ sleep(5);
+ delete($ENV{'form.pause'});
+ }
+ ##
+ ## Initialize global variables
+ ##
my $domain = $r->dir_config('lonDefDomain');
$diropendb= "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain).
"\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db";
-
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['catalogmode','launch','acts','mode','form','element',
- 'reqinterface']);
+ #
+ # set the name of the persistent database
+ # $ENV{'form.persistent_db_id'} can only have digits in it.
+ if (! exists($ENV{'form.persistent_db_id'}) ||
+ $ENV{'form.persistent_db_id'} =~ /\D/ ) {
+ $ENV{'form.persistent_db_id'} = time;
+ }
+ my $persistent_db_file = "/home/httpd/perl/tmp/".
+ &Apache::lonnet::escape($domain).
+ '_'.&Apache::lonnet::escape($ENV{'user.name'}).
+ '_'.$ENV{'form.persistent_db_id'}.'_persistent_search.db';
+ ##
+ &get_persistent_form_data($r,$persistent_db_file);
##
- ## Clear out old values from database
+ ## Clear out old values from groupsearch database
##
+ untie %groupsearch_db if (tied(%groupsearch_db));
if ($ENV{'form.launch'} eq '1') {
- if (tie(%hash,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) {
+ if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) {
&start_fresh_session();
- untie %hash;
+ untie %groupsearch_db;
} else {
$r->print('
Unable to tie hash to db '.
'file');
@@ -232,23 +228,15 @@ sub handler {
}
}
##
- ## Produce some output, so people know it is working
- ##
- $r->print("\n");
- $r->rflush;
- ##
## Configure dynamic components of interface
##
- my $hidden; # Holds 'hidden' html forms
+ $hidden_fields = '';
+ ##
if ($ENV{'form.catalogmode'} eq 'interactive') {
- $hidden="".
- "\n";
$closebutton=""."\n";
} elsif ($ENV{'form.catalogmode'} eq 'groupsearch') {
- $hidden=<
-END
$closebutton=<
END
@@ -256,29 +244,77 @@ END
END
+ } else {
+ $closebutton = '';
+ $importbutton = '';
}
- $hidden .= <
-
-
-
-END
##
- ## What are we doing?
+ ## Sanity checks on form elements
##
- if ($ENV{'form.basicsubmit'} eq 'SEARCH') {
- # Perform basic search and give results
- return &basicsearch($r,\%ENV,$hidden);
- } elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') {
- # Perform advanced search and give results
- return &advancedsearch($r,\%ENV,$hidden);
- } elsif ($ENV{'form.reqinterface'} eq 'advanced') {
- # Output the advanced interface
- $r->print(&advanced_search_form($closebutton,$hidden));
- return OK;
- } else {
- # Output normal search interface
- $r->print(&basic_search_form($closebutton,$hidden));
+ if (!defined($ENV{'form.viewselect'})) {
+ $ENV{'form.viewselect'} ="Detailed Citation View";
+ }
+ $ENV{'form.phase'} = 'displaybasic' if (! exists($ENV{'form.phase'}));
+ ##
+ ## Switch on the phase
+ ##
+ if ($ENV{'form.phase'} eq 'disp_basic') {
+ &print_basic_search_form($r,$closebutton);
+ } elsif ($ENV{'form.phase'} eq 'disp_adv') {
+ &print_advanced_search_form($r,$closebutton);
+ } elsif ($ENV{'form.phase'} eq 'results') {
+ &display_results($r,$importbutton,$closebutton);
+ } elsif($ENV{'form.phase'} eq 'run_search') {
+ my ($query,$customquery,$customshow,$libraries,$pretty_string) =
+ &get_persistent_data($persistent_db_file,
+ ['query','customquery','customshow',
+ 'libraries','pretty_string']);
+ &write_status($r,"query = $query");
+ &write_status($r,"customquery = $customquery");
+ &write_status($r,"customshow = $customshow");
+ &write_status($r,"libraries = $libraries");
+ &write_status($r,"pretty_string = $pretty_string");
+ &run_search($r,$query,$customquery,$customshow,
+ $libraries,$pretty_string);
+ } elsif(($ENV{'form.phase'} eq 'basic_search') ||
+ ($ENV{'form.phase'} eq 'adv_search')) {
+ # Set up table
+ if (! defined(&create_results_table())) {
+ # Unable to make table to store results in.
+ # Definately abort search.
+ }
+ if (! &make_form_data_persistent($r,$persistent_db_file)) {
+ # Unable to store persistent data.
+ # Probably should bail out.
+ }
+ #
+ # We are running a search
+ my ($query,$customquery,$customshow,$libraries) =
+ (undef,undef,undef,undef);
+ my $pretty_string;
+ if ($ENV{'form.phase'} eq 'basic_search') {
+ ($query,$pretty_string) = &parse_basic_search($r,$closebutton);
+ } else { # Advanced search
+ ($query,$customquery,$customshow,$libraries,$pretty_string)
+ = &parse_advanced_search($r,$closebutton);
+ return OK if (! defined($query));
+ }
+ &write_status($r,"query = $query");
+ &write_status($r,"customquery = $customquery");
+ &write_status($r,"customshow = $customshow");
+ &write_status($r,"libraries = $libraries");
+ &write_status($r,"pretty_string = $pretty_string");
+ &make_persistent($r,
+ { query => $query,
+ customquery => $customquery,
+ customshow => $customshow,
+ libraries => $libraries,
+ pretty_string => $pretty_string },
+ $persistent_db_file);
+ ##
+ ## Print out the frames interface
+ ##
+ &print_frames_interface($r);
}
return OK;
}
@@ -288,7 +324,7 @@ END
=pod
-=item &basic_search_form()
+=item &print_basic_search_form()
Returns a scalar which holds html for the basic search form.
@@ -297,8 +333,8 @@ Returns a scalar which holds html for th
######################################################################
######################################################################
-sub basic_search_form{
- my ($closebutton,$hidden) = @_;
+sub print_basic_search_form{
+ my ($r,$closebutton) = @_;
my $scrout=<<"ENDDOCUMENT";
@@ -315,10 +351,12 @@ sub basic_search_form{
Search Catalog
ENDDOCUMENT
- return $scrout;
+ $r->print($scrout);
+ return;
}
######################################################################
######################################################################
@@ -365,8 +404,19 @@ Returns a scalar which holds html for th
######################################################################
######################################################################
-sub advanced_search_form{
- my ($closebutton,$hidden) = @_;
+sub print_advanced_search_form{
+ my ($r,$closebutton) = @_;
+ my $advanced_buttons = <<"END";
+
+
+
+$closebutton
+
+
+END
+ if (!defined($ENV{'form.viewselect'})) {
+ $ENV{'form.viewselect'} ="Detailed Citation View";
+ }
my $scrout=<<"ENDHEADER";
@@ -381,35 +431,77 @@ sub advanced_search_form{
-
Search Catalog
-
ENDDOCUMENT
- return $scrout;
+ $r->print($scrout);
+ return;
}
######################################################################
@@ -512,35 +589,170 @@ ENDDOCUMENT
=pod
-=item &make_persistent()
+=item &get_persistent_form_data
+
+Inputs: filename of database
+
+Outputs: returns undef on database errors.
-Returns a scalar which holds the current ENV{'form.*'} values in
-a 'hidden' html input tag. This allows search interface information
-to be somewhat persistent.
+This function is the reverse of &make_persistent() for form data.
+Retrieve persistent data from %persistent_db. Retrieved items will have their
+values unescaped. If a form value already exists in $ENV, it will not be
+overwritten. Form values that are array references may have values appended
+to them.
=cut
######################################################################
######################################################################
+sub get_persistent_form_data {
+ my $r = shift;
+ my $filename = shift;
+ return undef if (! -e $filename);
+ return undef if (! tie(%persistent_db,'GDBM_File',$filename,
+ &GDBM_READER,0640));
+ #
+ # These make sure we do not get array references printed out as 'values'.
+ my %arrays_allowed = ('form.category'=>1,'form.domains'=>1);
+ #
+ # Loop through the keys, looking for 'form.'
+ foreach my $name (keys(%persistent_db)) {
+ next if ($name !~ /^form./);
+ my @values = map {
+ &Apache::lonnet::unescape($_);
+ } split(',',$persistent_db{$name});
+ next if (@values <1);
+ if (exists($ENV{$name})) {
+ if (ref($ENV{$name}) eq 'ARRAY') {
+ # If it is an array, tack @values on the end of it.
+ $ENV{$name} = [@$ENV{$name},@values];
+ } elsif (! ref($ENV{$name}) && $arrays_allowed{$name}) {
+ # if arrays are allowed, turn it into one and add @values
+ $ENV{$name} = [$ENV{$name},@values];
+ } # otherwise, assume the value in $ENV{$name} is better than ours.
+ } else {
+ if ($arrays_allowed{$name}) {
+ $ENV{$name} = [@values];
+ } else {
+ $ENV{$name} = $values[0] if ($values[0]);
+ }
+ }
+ &write_status($r,"Reconstructed $name = $ENV{$name}");
+ }
+ untie (%persistent_db);
+ return 1;
+}
+######################################################################
+######################################################################
-sub make_persistent {
- my $persistent='';
- foreach (keys %ENV) {
- if (/^form\./ && !/submit/) {
- my $name=$_;
- my $key=$name;
- $ENV{$key}=~s/\'//g; # do not mess with html field syntax
- $name=~s/^form\.//;
- $persistent.=<
-END
+=pod
+
+=item &get_persistent_data
+
+Inputs: filename of database, ref to array of values to recover.
+
+Outputs: array of values. Returns undef on error.
+
+This function is the reverse of &make_persistent();
+Retrieve persistent data from %persistent_db. Retrieved items will have their
+values unescaped. If the item contains commas (before unescaping), the
+returned value will be an array pointer.
+
+=cut
+
+######################################################################
+######################################################################
+sub get_persistent_data {
+ my $filename = shift;
+ my @Vars = @{shift()};
+ my @Values; # Return array
+ return undef if (! -e $filename);
+ return undef if (! tie(%persistent_db,'GDBM_File',$filename,
+ &GDBM_READER,0640));
+ foreach my $name (@Vars) {
+ if (! exists($persistent_db{$name})) {
+ push @Values, undef;
+ next;
}
+ my @values = map {
+ &Apache::lonnet::unescape($_);
+ } split(',',$persistent_db{$name});
+ if (@values == 1) {
+ push @Values,$values[0];
+ } else {
+ push @Values,\@values;
+ }
+ }
+ untie (%persistent_db);
+ return @Values;
+}
+
+######################################################################
+######################################################################
+
+=pod
+
+=item &make_persistent()
+
+Inputs: Hash of values to save, filename of persistent database.
+
+Store variables away to the %persistent_db.
+Values will be escaped. Values that are array pointers will have their
+elements escaped and concatenated in a comma seperated string.
+
+=cut
+
+######################################################################
+######################################################################
+sub make_persistent {
+ my $r = shift;
+ my %save = %{shift()};
+ my $filename = shift;
+ return undef if (! tie(%persistent_db,'GDBM_File',
+ $filename,&GDBM_WRCREAT,0640));
+ foreach my $name (keys(%save)) {
+ next if (! exists($save{$name}));
+ next if (! defined($save{$name}) || $save{$name} eq '');
+ my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name}));
+ # We handle array references, but not recursively.
+ my $store = join(',', map { &Apache::lonnet::escape($_); } @values );
+ $persistent_db{$name} = $store;
+ &write_status($r,"Stored $name = $store");
}
- return $persistent;
+ untie(%persistent_db);
+ return 1;
}
+######################################################################
+######################################################################
+
+=pod
+
+=item &make_form_data_persistent()
+
+Inputs: filename of persistent database.
+
+Store most form variables away to the %persistent_db.
+Values will be escaped. Values that are array pointers will have their
+elements escaped and concatenated in a comma seperated string.
+
+=cut
+
+######################################################################
+######################################################################
+sub make_form_data_persistent {
+ my $r = shift;
+ my $filename = shift;
+ my %save;
+ foreach (keys(%ENV)) {
+ next if (! /^form/ || /submit/);
+ $save{$_} = $ENV{$_};
+ }
+ return &make_persistent($r,\%save,$filename);
+}
######################################################################
+# HTML form building functions #
######################################################################
=pod
@@ -549,6 +761,13 @@ END
=over 4
+=cut
+
+###############################################
+###############################################
+
+=pod
+
=item &simpletextfield()
Inputs: $name,$value,$size
@@ -556,6 +775,23 @@ Inputs: $name,$value,$size
Returns a text input field with the given name, value, and size.
If size is not specified, a value of 20 is used.
+=cut
+
+###############################################
+###############################################
+
+sub simpletextfield {
+ my ($name,$value,$size)=@_;
+ $size = 20 if (! defined($size));
+ return '';
+}
+
+###############################################
+###############################################
+
+=pod
+
=item &simplecheckbox()
Inputs: $name,$value
@@ -563,56 +799,107 @@ Inputs: $name,$value
Returns a simple check box with the given $name.
If $value eq 'on' the box is checked.
-=item &searchphrasefield()
+=cut
-Inputs: $title,$name,$value
+###############################################
+###############################################
-Returns html for a title line and an input field for entering search terms.
-the instructions "Enter terms or phrases separated by search operators such
-as AND, OR, or NOT." are given following the title. The entry field (which
-is where the $name and $value are used) is an 80 column simpletextfield.
+sub simplecheckbox {
+ my ($name,$value)=@_;
+ my $checked='';
+ $checked="checked" if $value eq 'on';
+ return '';
+}
-=item &dateboxes()
+###############################################
+###############################################
-Returns html selection form elements for the specification of
-the day, month, and year.
+=pod
-=item &selectbox()
+=item &fieldtitle()
-Returns html selection form.
+Input: $title
-=back
+Returns a scalar with html which will display $title as a search
+field heading.
=cut
-######################################################################
-######################################################################
+###############################################
+###############################################
-sub simpletextfield {
- my ($name,$value,$size)=@_;
- $size = 20 if (! defined($size));
- return '';
+sub fieldtitle {
+ my $title = uc(shift());
+ return ''.$title.
+ ': ';
}
-sub simplecheckbox {
- my ($name,$value)=@_;
- my $checked='';
- $checked="CHECKED" if $value eq 'on';
- return '';
-}
+###############################################
+###############################################
+
+=pod
+
+=item &searchphrasefield()
+
+Inputs: $title,$name,$value
+Returns html for a title line and an input field for entering search terms.
+The entry field (which is where the $name and $value are used) is a 50 column
+simpletextfield. The html returned is for a row in a three column table.
+
+=cut
+
+###############################################
+###############################################
+
sub searchphrasefield {
my ($title,$name,$value)=@_;
- my $instruction=<'.$uctitle.':'.
- " $instruction ".&simpletextfield($name,$value,80);
+ return '
'.&fieldtitle($title).'
'.
+ &simpletextfield($name,$value,50)."
\n";
}
+###############################################
+###############################################
+
+=pod
+
+=item &searchphrasefield_with_related()
+
+Inputs: $title,$name,$value
+
+Returns html for a title line and an input field for entering search terms
+and a check box for 'related words'. The entry field (which is where the
+$name and $value are used) is a 50 column simpletextfield. The name of
+the related words checkbox is "$name_related".
+
+=cut
+
+###############################################
+###############################################
+
+sub searchphrasefield_with_related {
+ my ($title,$name,$value)=@_;
+ return '
-CATALOGCONTROLS
+ # Timing variables
#
- # Remind them what they searched for
+ my $starttime = time;
+ my $max_time = 120; # seconds for the search to complete
#
- if ($mode eq 'Basic') {
- $r->print('
');
+ # Print run_search header
+ #
+ $r->print("Search Status");
+ $r->print("Search: ".$pretty_string." \n");
$r->rflush();
#
- # make the pop-up window for status
+ # Determine the servers we need to contact.
#
- $r->print(&make_popwin(%rhash));
- $r->rflush();
+ my @Servers_to_contact;
+ if (defined($serverlist)) {
+ @Servers_to_contact = @$serverlist;
+ } else {
+ @Servers_to_contact = sort(keys(%Apache::lonnet::libserv));
+ }
+ my %Server_status;
+ my $table =$ENV{'form.table'};
+ if (! defined($table)) {
+ # What do I do now? Print out an error page.
+ &Apache::lonnet::logthis("lonmysql attempted to create a table ".
+ "and this was the result:".
+ &Apache::lonmysql::get_error());
+ $r->print("An internal error occured with the database. ".
+ "The error has been logged, but you should probably alert".
+ " your system administrator.");
+ return;
+ }
##
- ## Prepare for the main loop below
+ ## Prepare for the big loop.
##
- my $servercount=0;
- my $hitcountsum=0;
- my $servernum=(keys %rhash);
- my $serversleft=$servernum;
- ##
- ## Run until we run out of time or we run out of servers
- ##
- while($serversleft && $timeremain) {
- ##
- ## %rhash has servers deleted from it as results come in
- ## (within the foreach loop below).
- ##
- foreach my $rkey (sort keys %rhash) {
-# &Apache::lonnet::logthis("Server $rkey:".time);
- $servercount++;
- $compiledresult='';
- my $reply=$rhash{$rkey};
- my @results;
- if ($reply eq 'con_lost') {
- &popwin_imgupdate($r,$rkey,"srvbad.gif");
- $serversleft--;
- delete $rhash{$rkey};
- } else {
- # must do since 'use strict' checks for tainting
- $reply=~/^([\.\w]+)$/;
- my $replyfile=$r->dir_config('lonDaemons').'/tmp/'.$1;
- $reply=~/(.*?)\_/;
- for (my $counter=0;$counter<2;$counter++) {
- if (-e $replyfile && ! -e "$replyfile.end") {
- &popwin_imgupdate($r,$rkey,"srvhalf.gif");
- &popwin_js($r,'popwin.hc["'.$rkey.'"]='.
- '"still transferring..."'.';');
- }
- # Are we finished transferring data?
- if (-e "$replyfile.end") {
- $serversleft--;
- delete $rhash{$rkey};
- if (-s $replyfile) {
- &popwin_imgupdate($r,$rkey,"srvgood.gif");
- my $fh;
- unless ($fh=Apache::File->new($replyfile)){
- # Is it really appropriate to die on this error?
- $r->print('ERROR: file '.
- $replyfile.' cannot be opened');
- return OK;
- }
- @results=<$fh> if $fh;
- $hitcount{$rkey}=@results+0;
- &popwin_js($r,'popwin.hc["'.$rkey.'"]='.
- $hitcount{$rkey}.';');
- $hitcountsum+=$hitcount{$rkey};
- &popwin_js($r,'popwin.document.forms.popremain.'.
- 'numhits.value='.$hitcountsum.';');
- } else {
- &popwin_imgupdate($r,$rkey,"srvempty.gif");
- &popwin_js($r,'popwin.hc["'.$rkey.'"]=0;');
- }
- last;
- } # end of if ( -e "$replyfile.end")
- last unless $timeremain;
- sleep 1; # wait for daemons to write files?
- $timeremain--;
- $elapsetime++;
- &popwin_js($r,"popwin.document.popremain.".
- "elapsetime.value=$elapsetime;");
- }
- &popwin_js($r,'popwin.document.whirly.'.
- 'src="/adm/lonIcons/lonanimend.gif";');
- } # end of if ($reply eq 'con_lost') else statement
- my %Fields = undef; # Holds the data to be sent to the various
- # *_view routines.
- my ($extrashow,$customfields,$customhash) = &handle_custom_fields(\@results);
- my @customfields = @$customfields;
- my %customhash = %$customhash;
- untie %hash if (keys %hash);
- #
- if (! tie(%hash,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) {
- $r->print('Unable to tie hash to db '.
- 'file');
+ my $hitcountsum;
+ my $server;
+ my $status;
+ while ((time - $starttime < $max_time) &&
+ ((@Servers_to_contact) || keys(%Server_status))) {
+ # Send out a search request if it needs to be done.
+ if (@Servers_to_contact) {
+ # Contact one server
+ my $server = shift(@Servers_to_contact);
+ my $reply=&Apache::lonnet::metadata_query($query,$customquery,
+ $customshow,[$server]);
+ ($server) = keys(%$reply);
+ $Server_status{$server} = $reply->{$server};
+ # $r->print("Contacted:$server:reply:$Server_status{$server}");
+ if ($max_time - (time - $starttime) < 20) {
+ # If there are less than 20 seconds to go in the search,
+ # give the newly contacted servers 20 more seconds to
+ # respond....
+ $max_time += 20;
+ }
} else {
- if ($ENV{'form.launch'} eq '1') {
- &start_fresh_session();
- }
- foreach my $result (@results) {
- next if $result=~/^custom\=/;
- chomp $result;
- next unless $result;
- %Fields = &parse_raw_result($result,$rkey);
- $Fields{'extrashow'}=$extrashow;
- if ($extrashow) {
- foreach my $field (@customfields) {
- my $value='';
- $value = $1 if ($customhash{$Fields{'url'}}=~/\<{$field}[^\>]*\>(.*?)\<\/{$field}[^\>]*\>/s);
- $Fields{'extrashow'}=~s/\<\!\-\- $field \-\-\>/ $value/g;
- }
+ sleep(1); # wait a sec. to give time for files to be written
+ }
+ while (my ($server,$status) = each(%Server_status)) {
+ if ($status eq 'con_lost') {
+ delete ($Server_status{$server});
+ # $r->print("server $server is not responding.");
+ next;
+ }
+ $status=~/^([\.\w]+)$/;
+ my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1;
+ if (-e $datafile && ! -e "$datafile.end") {
+ # Let the user know we are receiving data from the server
+ # $r->print("$server:Receiving file");
+ next;
+ }
+ if (-e "$datafile.end") {
+ if (-z "$datafile") {
+ delete($Server_status{$server});
+ next;
}
- if ($compiledresult or $servercount!=$servernum) {
- $compiledresult.="";
+ my $fh;
+ if (!($fh=Apache::File->new($datafile))) {
+ # Error opening file...
+ # Tell the user and exit...?
+ # Should I give up on opening it?
+ $r->print("Unable to open search results file for ".
+ "server $server. Omitting from search");
+ next;
}
- $compiledresult.="\n