version 1.144, 2002/07/26 16:37:58
|
version 1.147, 2002/07/30 18:30:56
|
Line 103 use Apache::lonmysql();
|
Line 103 use Apache::lonmysql();
|
|
|
=over 4 |
=over 4 |
|
|
=item $closebutton |
|
|
|
button that closes the search window |
|
|
|
=item $importbutton |
=item $importbutton |
|
|
button to take the select results and go to group sorting |
button to take the select results and go to group sorting |
Line 127 that produces it. Adding a new view typ
|
Line 123 that produces it. Adding a new view typ
|
adding a line to the definition of this hash and making sure the function |
adding a line to the definition of this hash and making sure the function |
takes the proper parameters. |
takes the proper parameters. |
|
|
=item $results_db |
|
|
|
The name of the database results from searches are put in. |
|
|
|
=back |
=back |
|
|
=cut |
=cut |
Line 139 The name of the database results from se
|
Line 131 The name of the database results from se
|
###################################################################### |
###################################################################### |
|
|
# -- dynamically rendered interface components |
# -- 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 |
my $importbutton; # button to take the selected results and go to group sorting |
|
|
# -- miscellaneous variables |
# -- miscellaneous variables |
my %groupsearch_db; # database hash |
my %groupsearch_db; # database hash |
my $diropendb = ""; # db file |
my $diropendb = ""; # db file |
|
|
my $results_db = ""; |
|
# View Description Function Pointer |
# View Description Function Pointer |
my %Views = ("Detailed Citation View" => \&detailed_citation_view, |
my %Views = ("Detailed Citation View" => \&detailed_citation_view, |
"Summary View" => \&summary_view, |
"Summary View" => \&summary_view, |
"Fielded Format" => \&fielded_format_view, |
"Fielded Format" => \&fielded_format_view, |
"XML/SGML" => \&xml_sgml_view ); |
"XML/SGML" => \&xml_sgml_view ); |
|
my %persistent_db; |
|
my $hidden_fields; |
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
|
|
Line 180 string that holds portions of the screen
|
Line 170 string that holds portions of the screen
|
###################################################################### |
###################################################################### |
sub handler { |
sub handler { |
my $r = shift; |
my $r = shift; |
untie %groupsearch_db; |
# |
|
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->content_type('text/html'); |
$r->send_http_header; |
$r->send_http_header; |
return OK if $r->header_only; |
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(3); |
|
delete($ENV{'form.pause'}); |
|
} |
## |
## |
## Initialize global variables |
## Initialize global variables |
## |
## |
my $domain = $r->dir_config('lonDefDomain'); |
my $domain = $r->dir_config('lonDefDomain'); |
$diropendb= "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain). |
$diropendb= "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain). |
"\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db"; |
"\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db"; |
$results_db = "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain). |
# |
'_'.&Apache::lonnet::escape($ENV{'user.name'})."_searchresults.db"; |
# set the name of the persistent database |
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, |
# $ENV{'form.persistent_db_id'} can only have digits in it. |
['catalogmode','launch','acts','mode','form','element', |
if (! exists($ENV{'form.persistent_db_id'}) || |
'reqinterface']); |
($ENV{'form.persistent_db_id'} =~ /\D/) || |
|
($ENV{'form.launch'} eq '1')) { |
|
$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'; |
|
## |
|
if (! &get_persistent_form_data($r,$persistent_db_file)) { |
|
&write_status($r,"Unable to get persistent data"); |
|
} |
## |
## |
## Clear out old values from groupsearch database |
## Clear out old values from groupsearch database |
## |
## |
|
untie %groupsearch_db if (tied(%groupsearch_db)); |
if ($ENV{'form.launch'} eq '1') { |
if ($ENV{'form.launch'} eq '1') { |
if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) { |
if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) { |
&start_fresh_session(); |
&start_fresh_session(); |
Line 210 sub handler {
|
Line 231 sub handler {
|
} |
} |
} |
} |
## |
## |
## Produce some output, so people know it is working |
|
## |
|
$r->print("\n"); |
|
$r->rflush; |
|
## |
|
## Configure dynamic components of interface |
## Configure dynamic components of interface |
## |
## |
my $hidden; # Holds 'hidden' html forms |
$hidden_fields = '<input type="hidden" name="persistent_db_id" value="'. |
|
$ENV{'form.persistent_db_id'}.'" />'; |
|
## |
if ($ENV{'form.catalogmode'} eq 'interactive') { |
if ($ENV{'form.catalogmode'} eq 'interactive') { |
$hidden="<input type='hidden' name='catalogmode' value='interactive'>". |
|
"\n"; |
|
$closebutton="<input type='button' name='close' value='CLOSE' ". |
$closebutton="<input type='button' name='close' value='CLOSE' ". |
"onClick='self.close()'>"."\n"; |
"onClick='self.close()'>"."\n"; |
} elsif ($ENV{'form.catalogmode'} eq 'groupsearch') { |
} elsif ($ENV{'form.catalogmode'} eq 'groupsearch') { |
$hidden=<<END; |
|
<input type='hidden' name='catalogmode' value='groupsearch'> |
|
END |
|
$closebutton=<<END; |
$closebutton=<<END; |
<input type='button' name='close' value='CLOSE' onClick='self.close()'> |
<input type='button' name='close' value='CLOSE' onClick='self.close()'> |
END |
END |
Line 234 END
|
Line 247 END
|
<input type='button' name='import' value='IMPORT' |
<input type='button' name='import' value='IMPORT' |
onClick='javascript:select_group()'> |
onClick='javascript:select_group()'> |
END |
END |
|
} else { |
|
$closebutton = ''; |
|
$importbutton = ''; |
} |
} |
$hidden .= &make_persistent({ "form.mode" => $ENV{'form.mode'}, |
## |
"form.form" => $ENV{'form.form'}, |
## Sanity checks on form elements |
"form.element" => $ENV{'form.element'}, |
## |
"form.date" => 2 }); |
if (!defined($ENV{'form.viewselect'})) { |
## |
$ENV{'form.viewselect'} ="Detailed Citation View"; |
## What are we doing? |
} |
## |
$ENV{'form.phase'} = 'displaybasic' if (! exists($ENV{'form.phase'})); |
my $searchtype; |
## |
$searchtype = 'Basic' if ($ENV{'form.basicsubmit'} eq 'SEARCH'); |
## Switch on the phase |
$searchtype = 'Advanced' if ($ENV{'form.advancedsubmit'} eq 'SEARCH'); |
## |
if ($searchtype) { |
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())) { |
|
my $error = &Apache::lonmysql::get_error(); |
|
$r->print(<<END); |
|
<html><head><title>Search Error</title></head> |
|
<body> |
|
Unable to create table in which to store search results. |
|
The search has been aborted. |
|
<pre> |
|
ERROR: |
|
$error |
|
</pre> |
|
</body> |
|
</html> |
|
END |
|
return OK; |
|
} |
|
delete($ENV{'form.launch'}); |
|
if (! &make_form_data_persistent($r,$persistent_db_file)) { |
|
$r->print(<<END); |
|
<html><head><title>Search Error</title></head> |
|
<body> |
|
Unable to properly store search information. The search has been aborted. |
|
</body> |
|
</html> |
|
END |
|
return OK; |
|
} |
|
# |
# We are running a search |
# We are running a search |
my ($query,$customquery,$customshow,$libraries) = |
my ($query,$customquery,$customshow,$libraries) = |
(undef,undef,undef,undef); |
(undef,undef,undef,undef); |
my $pretty_string; |
my $pretty_string; |
if ($searchtype eq 'Basic') { |
if ($ENV{'form.phase'} eq 'basic_search') { |
($query,$pretty_string) = &parse_basic_search($r); |
($query,$pretty_string) = &parse_basic_search($r,$closebutton); |
} elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') { |
} else { # Advanced search |
($query,$customquery,$customshow,$libraries,$pretty_string) |
($query,$customquery,$customshow,$libraries,$pretty_string) |
= &parse_advanced_search($r); |
= &parse_advanced_search($r,$closebutton); |
return OK if (! defined($query)); |
return OK if (! defined($query)); |
} |
} |
# Output some information to the user. |
&make_persistent($r, |
$r->print(&search_results_header($searchtype,$pretty_string)); |
{ query => $query, |
$r->print("Sending search request to LON-CAPA servers.<br />\n"); |
customquery => $customquery, |
$r->rflush(); |
customshow => $customshow, |
&run_search($r,$query,$customquery,$customshow,$libraries); |
libraries => $libraries, |
&display_results($r,$searchtype,$hidden,$importbutton, |
pretty_string => $pretty_string }, |
$closebutton); |
$persistent_db_file); |
|
## |
$r->rflush(); |
## Print out the frames interface |
} else { |
## |
# |
&print_frames_interface($r); |
# We need to get information to search on |
|
# |
|
# Set the default view if it is not already set. |
|
if (!defined($ENV{'form.viewselect'})) { |
|
$ENV{'form.viewselect'} ="Detailed Citation View"; |
|
} |
|
# Output the advanced interface |
|
if ($ENV{'form.reqinterface'} eq 'advanced') { |
|
$r->print(&advanced_search_form($closebutton,$hidden)); |
|
} else { |
|
# Output normal search interface |
|
$r->print(&basic_search_form($closebutton,$hidden)); |
|
} |
|
} |
} |
return OK; |
return OK; |
} |
} |
Line 290 END
|
Line 341 END
|
|
|
=pod |
=pod |
|
|
=item &basic_search_form() |
=item &print_basic_search_form() |
|
|
Returns a scalar which holds html for the basic search form. |
Returns a scalar which holds html for the basic search form. |
|
|
Line 299 Returns a scalar which holds html for th
|
Line 350 Returns a scalar which holds html for th
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
|
|
sub basic_search_form{ |
sub print_basic_search_form{ |
my ($closebutton,$hidden) = @_; |
my ($r,$closebutton) = @_; |
my $scrout=<<"ENDDOCUMENT"; |
my $scrout=<<"ENDDOCUMENT"; |
<html> |
<html> |
<head> |
<head> |
Line 317 sub basic_search_form{
|
Line 368 sub basic_search_form{
|
<img align='right' src='/adm/lonIcons/lonlogos.gif' /> |
<img align='right' src='/adm/lonIcons/lonlogos.gif' /> |
<h1>Search Catalog</h1> |
<h1>Search Catalog</h1> |
<form method="post" action="/adm/searchcat"> |
<form method="post" action="/adm/searchcat"> |
$hidden |
<input type="hidden" name="phase" value="basic_search" /> |
|
$hidden_fields |
<h3>Basic Search</h3> |
<h3>Basic Search</h3> |
<p> |
<p> |
Enter terms or phrases separated by AND, OR, or NOT |
Enter terms or phrases separated by AND, OR, or NOT |
Line 333 ENDDOCUMENT
|
Line 385 ENDDOCUMENT
|
# $scrout.='<font color="#800000">Search historic archives</font>'; |
# $scrout.='<font color="#800000">Search historic archives</font>'; |
my $checkbox = &simplecheckbox('related',$ENV{'form.related'}); |
my $checkbox = &simplecheckbox('related',$ENV{'form.related'}); |
$scrout.=<<END; |
$scrout.=<<END; |
</td><td><a href="/adm/searchcat?reqinterface=advanced">Advanced Search</a></td></tr> |
</td><td><a href="/adm/searchcat?phase=disp_adv">Advanced Search</a></td></tr> |
<tr><td>$checkbox use related words</td><td></td></tr> |
<tr><td>$checkbox use related words</td><td></td></tr> |
</table> |
</table> |
</p> |
</p> |
Line 352 END
|
Line 404 END
|
</body> |
</body> |
</html> |
</html> |
ENDDOCUMENT |
ENDDOCUMENT |
return $scrout; |
$r->print($scrout); |
|
return; |
} |
} |
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
Line 368 Returns a scalar which holds html for th
|
Line 421 Returns a scalar which holds html for th
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
|
|
sub advanced_search_form{ |
sub print_advanced_search_form{ |
my ($closebutton,$hidden) = @_; |
my ($r,$closebutton) = @_; |
my $advanced_buttons = <<"END"; |
my $advanced_buttons = <<"END"; |
<p> |
<p> |
<input type="submit" name="advancedsubmit" value='SEARCH' /> |
<input type="submit" name="advancedsubmit" value='SEARCH' /> |
Line 401 Enter terms or phrases separated by sear
|
Line 454 Enter terms or phrases separated by sear
|
such as AND, OR, or NOT.<br /> |
such as AND, OR, or NOT.<br /> |
<form method="post" action="/adm/searchcat"> |
<form method="post" action="/adm/searchcat"> |
$advanced_buttons |
$advanced_buttons |
$hidden |
$hidden_fields |
|
<input type="hidden" name="phase" value="adv_search" /> |
<table> |
<table> |
<tr><td><font color="#800000" face="helvetica"><b>VIEW:</b></font></td> |
<tr><td><font color="#800000" face="helvetica"><b>VIEW:</b></font></td> |
<td> |
<td> |
Line 453 ENDHEADER
|
Line 507 ENDHEADER
|
# adjust the size of the select box |
# adjust the size of the select box |
my $size = 4; |
my $size = 4; |
my $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size); |
my $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size); |
# standalone machines do not get to choose a domain to search. |
$scrout.="\n".'<font color="#800000" face="helvetica"><b>'. |
if ((scalar @domains) == 1) { |
'DOMAINS</b></font><br />'. |
$scrout .='<input type="hidden" name="domains" value="any" />'."\n"; |
'<select name="domains" size="'.$size.'" multiple>'."\n". |
} else { |
'<option name="any" value="any" '. |
$scrout.="\n".'<font color="#800000" face="helvetica"><b>'. |
($domain_hash{'any'}? 'selected ' :''). |
'DOMAINS</b></font><br />'. |
|
'<select name="domains" size="'.$size.'" multiple>'."\n". |
|
'<option name="any" value="any" '. |
|
($domain_hash{'any'}? 'selected ' :''). |
|
'>all domains</option>'."\n"; |
'>all domains</option>'."\n"; |
foreach my $dom (sort @domains) { |
foreach my $dom (sort @domains) { |
$scrout.="<option name=\"$dom\" ". |
$scrout.="<option name=\"$dom\" ". |
($domain_hash{$dom} ? 'selected ' :'').">$dom</option>\n"; |
($domain_hash{$dom} ? 'selected ' :'').">$dom</option>\n"; |
} |
|
$scrout.="</select>\n"; |
|
} |
} |
|
$scrout.="</select>\n"; |
#---------------------------------------------------------------- |
#---------------------------------------------------------------- |
$scrout.=&selectbox('Limit by language','language', |
$scrout.=&selectbox('Limit by language','language', |
$ENV{'form.language'},'any','Any Language', |
$ENV{'form.language'},'any','Any Language', |
Line 548 $advanced_buttons
|
Line 597 $advanced_buttons
|
</body> |
</body> |
</html> |
</html> |
ENDDOCUMENT |
ENDDOCUMENT |
return $scrout; |
$r->print($scrout); |
|
return; |
} |
} |
|
|
###################################################################### |
###################################################################### |
Line 556 ENDDOCUMENT
|
Line 606 ENDDOCUMENT
|
|
|
=pod |
=pod |
|
|
=item &make_persistent() |
=item &get_persistent_form_data |
|
|
|
Inputs: filename of database |
|
|
|
Outputs: returns undef on database errors. |
|
|
|
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 0 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]); |
|
} |
|
} |
|
} |
|
untie (%persistent_db); |
|
return 1; |
|
} |
|
###################################################################### |
|
###################################################################### |
|
|
|
=pod |
|
|
|
=item &get_persistent_data |
|
|
|
Inputs: filename of database, ref to array of values to recover. |
|
|
Returns a scalar which holds the current ENV{'form.*'} values in |
Outputs: array of values. Returns undef on error. |
a 'hidden' html input tag. This allows search interface information |
|
to be somewhat persistent. |
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 |
=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 { |
sub make_persistent { |
|
my $r = shift; |
my %save = %{shift()}; |
my %save = %{shift()}; |
my $persistent=''; |
my $filename = shift; |
foreach my $name (keys %save) { |
return undef if (! tie(%persistent_db,'GDBM_File', |
if ($name =~ /^form\./ && $name !~ /submit/) { |
$filename,&GDBM_WRCREAT,0640)); |
my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name})); |
foreach my $name (keys(%save)) { |
$name=~s/^form\.//; |
next if (! exists($save{$name})); |
foreach (@values) { |
next if (! defined($save{$name}) || $save{$name} eq ''); |
s/\"/\'/g; # do not mess with html field syntax |
my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name})); |
next if (! $_ ); |
# We handle array references, but not recursively. |
$persistent.=<<END; |
my $store = join(',', map { &Apache::lonnet::escape($_); } @values ); |
<input type="hidden" name="$name" value="$_" /> |
$persistent_db{$name} = $store; |
END |
} |
} |
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 $persistent; |
return &make_persistent($r,\%save,$filename); |
} |
} |
|
|
###################################################################### |
###################################################################### |
Line 893 Parse advanced search form and return th
|
Line 1073 Parse advanced search form and return th
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub parse_advanced_search { |
sub parse_advanced_search { |
my ($r)=@_; |
my ($r,$closebutton)=@_; |
my $fillflag=0; |
my $fillflag=0; |
my $pretty_search_string = "<br />\n"; |
my $pretty_search_string = "<br />\n"; |
# Clean up fields for safety |
# Clean up fields for safety |
Line 929 sub parse_advanced_search {
|
Line 1109 sub parse_advanced_search {
|
} |
} |
} |
} |
unless ($fillflag) { |
unless ($fillflag) { |
&output_blank_field_error($r); |
&output_blank_field_error($r,$closebutton); |
return ; |
return ; |
} |
} |
# Turn the form input into a SQL-based query |
# Turn the form input into a SQL-based query |
Line 992 sub parse_advanced_search {
|
Line 1172 sub parse_advanced_search {
|
); |
); |
# Test to see if date windows are legitimate |
# Test to see if date windows are legitimate |
if ($datequery=~/^Incorrect/) { |
if ($datequery=~/^Incorrect/) { |
&output_date_error($r,$datequery); |
&output_date_error($r,$datequery,$closebutton); |
return ; |
return ; |
} elsif ($datequery) { |
} elsif ($datequery) { |
# Here is where you would set up pretty_search_string to output |
# Here is where you would set up pretty_search_string to output |
Line 1072 Parse the basic search form and return a
|
Line 1252 Parse the basic search form and return a
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub parse_basic_search { |
sub parse_basic_search { |
my ($r)=@_; |
my ($r,$closebutton)=@_; |
# Clean up fields for safety |
# Clean up fields for safety |
for my $field ('basicexp') { |
for my $field ('basicexp') { |
$ENV{"form.$field"}=~s/[^\w\s\(\)\-]//g; |
$ENV{"form.$field"}=~s/[^\w\s\(\)\-]//g; |
Line 1086 sub parse_basic_search {
|
Line 1266 sub parse_basic_search {
|
|
|
# Check to see if enough is filled in |
# Check to see if enough is filled in |
unless (&filled($ENV{'form.basicexp'})) { |
unless (&filled($ENV{'form.basicexp'})) { |
&output_blank_field_error($r); |
&output_blank_field_error($r,$closebutton); |
return OK; |
return OK; |
} |
} |
my $pretty_search_string = '<b>'.$ENV{'form.basicexp'}.'</b>'; |
my $pretty_search_string = '<b>'.$ENV{'form.basicexp'}.'</b>'; |
Line 1362 the following format:
|
Line 1542 the following format:
|
## columns of type 'enum' cannot be used for FULLTEXT. |
## columns of type 'enum' cannot be used for FULLTEXT. |
## |
## |
my @DataOrder = qw/id title author subject url keywords version notes |
my @DataOrder = qw/id title author subject url keywords version notes |
abstract mime lang owner copyright creationdate lastrevisiondate hostname |
abstract mime lang owner copyright creationdate lastrevisiondate hostname/; |
idx_title idx_author idx_subject idx_abstract idx_mime idx_language |
|
idx_owner idx_copyright/; |
|
|
|
my %Datatypes = |
my %Datatypes = |
( id =>{ type => 'INT', |
( id =>{ type => 'INT', |
Line 1390 my %Datatypes =
|
Line 1568 my %Datatypes =
|
creationdate =>{ type=>'DATETIME'}, |
creationdate =>{ type=>'DATETIME'}, |
lastrevisiondate =>{ type=>'DATETIME'}, |
lastrevisiondate =>{ type=>'DATETIME'}, |
#-------------------------------------------------- |
#-------------------------------------------------- |
idx_title =>{ type=>'FULLTEXT', target=>'title'}, |
|
idx_author =>{ type=>'FULLTEXT', target=>'author'}, |
|
idx_subject =>{ type=>'FULLTEXT', target=>'subject'}, |
|
idx_abstract =>{ type=>'FULLTEXT', target=>'abstract'}, |
|
idx_mime =>{ type=>'FULLTEXT', target=>'mime'}, |
|
idx_language =>{ type=>'FULLTEXT', target=>'lang'}, |
|
idx_owner =>{ type=>'FULLTEXT', target=>'owner'}, |
|
idx_copyright =>{ type=>'FULLTEXT', target=>'copyright'}, |
|
); |
); |
|
|
|
my @Fullindicies = |
|
qw/title author subject abstract mime language owner copyright/; |
|
|
|
###################################################################### |
|
###################################################################### |
|
|
|
=pod |
|
|
|
=item &create_results_table() |
|
|
|
Creates the table of search results by calling lonmysql. Stores the |
|
table id in $ENV{'form.table'} |
|
|
|
Inputs: none. |
|
|
|
Returns: the identifier of the table on success, undef on error. |
|
|
|
=cut |
|
|
|
###################################################################### |
|
###################################################################### |
|
sub create_results_table { |
|
my $table = &Apache::lonmysql::create_table |
|
( { columns => \%Datatypes, |
|
column_order => \@DataOrder, |
|
fullindex => \@Fullindicies, |
|
} ); |
|
if (defined($table)) { |
|
$ENV{'form.table'} = $table; |
|
return $table; |
|
} |
|
return undef; # Error... |
|
} |
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
|
|
Line 1413 my %Datatypes =
|
Line 1616 my %Datatypes =
|
###################################################################### |
###################################################################### |
sub write_status { |
sub write_status { |
my ($r,$string) = @_; |
my ($r,$string) = @_; |
$r->print("<pre>".$string."</pre>\n"); |
$string =~ s/(\')/\$1/g; |
$r->rflush(); |
$string =~ s/\n//sg; |
|
# $r->print("<script>alert('$string');</script>\n"); |
|
# $r->rflush(); |
return; |
return; |
} |
} |
|
|
Line 1430 sub write_status {
|
Line 1635 sub write_status {
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub run_search { |
sub run_search { |
my ($r,$query,$customquery,$customshow,$serverlist) = @_; |
my ($r,$query,$customquery,$customshow,$serverlist,$pretty_string) = @_; |
|
# |
|
# Timing variables |
|
# |
|
my $starttime = time; |
|
my $max_time = 120; # seconds for the search to complete |
|
# |
|
# Print run_search header |
|
# |
|
$r->print("<html><head><title>Search Status</title></head><body>"); |
|
$r->print("Search: ".$pretty_string."<br />\n"); |
|
$r->rflush(); |
|
# |
|
# Determine the servers we need to contact. |
# |
# |
my @Servers_to_contact; |
my @Servers_to_contact; |
if (defined($serverlist)) { |
if (defined($serverlist)) { |
Line 1439 sub run_search {
|
Line 1657 sub run_search {
|
@Servers_to_contact = sort(keys(%Apache::lonnet::libserv)); |
@Servers_to_contact = sort(keys(%Apache::lonnet::libserv)); |
} |
} |
my %Server_status; |
my %Server_status; |
# |
my $table =$ENV{'form.table'}; |
# Timing variables |
if (! defined($table) || $table eq '') { |
my $starttime = time; |
$r->print("Unable to determine table id to store search results in.". |
my $max_time = 120; # seconds for the search to complete |
"The search has been aborted."); |
# |
return; |
# Create Table |
} |
##################################### |
my $table_status = &Apache::lonmysql::check_table($table); |
my $table = &Apache::lonmysql::create_table |
if (! defined($table_status)) { |
( { columns => \%Datatypes, |
$r->print("Unable to determine status of table.</body></html>"); |
column_order => \@DataOrder, |
&Apache::lonnet::logthis("Bogus table id of $table for ". |
} ); |
"$ENV{'user.name'} @ $ENV{'user.domain'}"); |
if (! defined($table)) { |
&Apache::lonnet::logthis("lonmysql error = ". |
# 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()); |
&Apache::lonmysql::get_error()); |
$r->print("An internal error occured with the database.<br />". |
|
"The error has been logged, but you should probably alert". |
|
" your system administrator."); |
|
return; |
return; |
} |
} |
$ENV{'form.table'}=$table; |
if (! $table_status) { |
# |
$r->print("The table id,$table, we tried to use is invalid.". |
##################################### |
"The search has been aborted."); |
|
return; |
|
} |
|
## |
|
## Prepare for the big loop. |
|
## |
my $hitcountsum; |
my $hitcountsum; |
my $server; |
my $server; |
my $status; |
my $status; |
|
$r->print("Searching"); |
while ((time - $starttime < $max_time) && |
while ((time - $starttime < $max_time) && |
((@Servers_to_contact) || keys(%Server_status))) { |
((@Servers_to_contact) || keys(%Server_status))) { |
# Send out a search request if it needs to be done. |
# Send out a search request if it needs to be done. |
Line 1474 sub run_search {
|
Line 1692 sub run_search {
|
my $server = shift(@Servers_to_contact); |
my $server = shift(@Servers_to_contact); |
my $reply=&Apache::lonnet::metadata_query($query,$customquery, |
my $reply=&Apache::lonnet::metadata_query($query,$customquery, |
$customshow,[$server]); |
$customshow,[$server]); |
# We should let the user know we have contacted another server |
|
($server) = keys(%$reply); |
($server) = keys(%$reply); |
$Server_status{$server} = $reply->{$server}; |
$Server_status{$server} = $reply->{$server}; |
# &write_status($r,"Contacted:$server:reply:". |
# $r->print("Contacted:$server:reply:$Server_status{$server}"); |
# $Server_status{$server}); |
$r->print(" ."); |
# Hmmm, should we add to $max_time if we contact a server? |
$r->rflush(); |
} else { |
} else { |
sleep(1); # wait a sec. to give time for files to be written |
sleep(1); # wait a sec. to give time for files to be written |
} |
} |
while (my ($server,$status) = each(%Server_status)) { |
while (my ($server,$status) = each(%Server_status)) { |
if ($status eq 'con_lost') { |
if ($status eq 'con_lost') { |
delete ($Server_status{$server}); |
delete ($Server_status{$server}); |
# &write_status($r,"Removing $server"); |
# $r->print("server $server is not responding."); |
next; |
next; |
} |
} |
$status=~/^([\.\w]+)$/; |
$status=~/^([\.\w]+)$/; |
my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1; |
my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1; |
if (-e $datafile && ! -e "$datafile.end") { |
if (-e $datafile && ! -e "$datafile.end") { |
# Let the user know we are receiving data from the server |
# Let the user know we are receiving data from the server |
&write_status($r,"$server:Receiving file"); |
# $r->print("$server:Receiving file"); |
next; |
next; |
} |
} |
if (-e "$datafile.end") { |
if (-e "$datafile.end") { |
Line 1506 sub run_search {
|
Line 1723 sub run_search {
|
# Error opening file... |
# Error opening file... |
# Tell the user and exit...? |
# Tell the user and exit...? |
# Should I give up on opening it? |
# Should I give up on opening it? |
&write_status("Unable to open $datafile"); |
$r->print("Unable to open search results file for ". |
|
"server $server. Omitting from search"); |
next; |
next; |
} |
} |
# Read in the whole file. |
# Read in the whole file. |
Line 1521 sub run_search {
|
Line 1739 sub run_search {
|
# Store the result in the mysql database |
# Store the result in the mysql database |
my $result = &Apache::lonmysql::store_row($table,\%Fields); |
my $result = &Apache::lonmysql::store_row($table,\%Fields); |
if (! defined($result)) { |
if (! defined($result)) { |
&write_status($r,&Apache::lonmysql::get_error()); |
$r->print(&Apache::lonmysql::get_error()); |
} |
} |
# &write_status($r,&Apache::lonmysql::get_debug()); |
# $r->print(&Apache::lonmysql::get_debug()); |
$hitcountsum ++; |
$hitcountsum ++; |
} # End of foreach (@results) |
} # End of foreach (@results) |
$fh->close(); |
$fh->close(); |
# $server is only deleted if the results file has been |
# $server is only deleted if the results file has been |
# found and (successfully) opened. This may be a bad idea. |
# found and (successfully) opened. This may be a bad idea. |
delete($Server_status{$server}); |
delete($Server_status{$server}); |
|
# $r->print("Received $new_count more results from ". |
|
# $server."."); |
} |
} |
} |
} |
# Finished looping through the servers |
# Finished looping through the servers |
} |
} |
&Apache::lonmysql::disconnect_from_db(); |
&Apache::lonmysql::disconnect_from_db(); |
|
# Let the user know |
|
# |
# We have run out of time or run out of servers to talk to and |
# We have run out of time or run out of servers to talk to and |
# results to get. |
# results to get. |
if ($hitcountsum > 0) { |
$r->print("<br /><b>Search Completed</b><br />"); |
$r->print("<h3>Total results = $hitcountsum</h3></body></html>"); |
if ($hitcountsum) { |
|
$r->print($hitcountsum." successful matches were found.<br />"); |
|
} else { |
|
$r->print("There were no successful matches to your query.<br />"); |
} |
} |
|
$r->print("</body></html>"); |
return; |
return; |
} |
} |
|
|
Line 1547 sub run_search {
|
Line 1773 sub run_search {
|
###################################################################### |
###################################################################### |
=pod |
=pod |
|
|
=item &display_buttons |
=item &prev_next_buttons |
|
|
=cut |
=cut |
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub display_buttons { |
sub prev_next_buttons { |
my ($low,$high,$otherparms) = @_; |
my ($current_min,$show,$total,$parms) = @_; |
my $maxshow = 20; |
return '' if ($show eq 'all'); # No links if you get them all at once. |
my $lowest = ($low - $maxshow < 0 ? 0 : $low-$maxshow); |
my $links; |
my $highest = $high + $maxshow; |
## |
my ($previous,$current,$next); |
## Prev |
if ($lowest < $low) { |
my $prev_min = $current_min - $show; |
$previous = qq{<a href="/adm/searchcat?$otherparms&mode=display&low=$lowest&high=$highest">prev</a>}; |
$prev_min = 0 if $prev_min < 0; |
|
if ($prev_min < $current_min) { |
|
$links .= qq{ |
|
<a href="/adm/searchcat?$parms&start=$prev_min&show=$show">prev</a> |
|
}; |
} else { |
} else { |
$previous = "prev"; |
$links .= 'prev'; |
} |
} |
$current = qq{<a href="/adm/searchcat?$otherparms&mode=display&low=$low&high=$high">reload</a>}; |
## |
$next = qq{<a href="/adm/searchcat?$otherparms&mode=display&low=$high&high=$highest">next</a>}; |
## Pages.... Someday. |
my $result = $previous." ".$current." ".$next; |
## |
return $result; |
$links .= qq{ |
|
<a href="/adm/searchcat?$parms&start=$current_min&$show=$show">reload</a> |
|
}; |
|
## |
|
## Next |
|
my $next_min = $current_min + $show; |
|
$next_min = $current_min if ($next_min > $total); |
|
if ($next_min != $current_min) { |
|
$links .= qq{ |
|
<a href="/adm/searchcat?$parms&start=$next_min&show=$show">next</a> |
|
}; |
|
} else { |
|
$links .= ' next'; |
|
} |
|
return $links; |
} |
} |
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
Line 1581 sub display_buttons {
|
Line 1825 sub display_buttons {
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub display_results { |
sub display_results { |
my ($r,$mode,$hidden,$importbutton,$closebutton) = @_; |
my ($r,$mode,$importbutton,$closebutton) = @_; |
|
$r->print(&search_results_header()); |
## |
## |
## Set viewing function |
## Set viewing function |
## |
## |
Line 1592 sub display_results {
|
Line 1837 sub display_results {
|
return; |
return; |
} |
} |
## |
## |
## make query information persistent to allow for subsequent revision |
## Get the catalog controls setup |
## |
## |
my $persistent=&make_persistent(\%ENV); |
my $action = "/adm/searchcat?phase=results"; |
## |
## |
## Get the catalog controls setup |
## Deal with groupsearch |
|
## |
|
if ($ENV{'form.catalogmode'} eq 'groupsearch') { |
|
if (! tie(%groupsearch_db,'GDBM_File',$diropendb, |
|
&GDBM_WRCREAT,0640)) { |
|
$r->print('Unable to tie hash to db file</body></html>'); |
|
$r->rflush(); |
|
return; |
|
} |
|
} |
|
## |
|
## Prepare the table for querying |
## |
## |
my $action = "/adm/searchcat"; |
|
if ($mode eq 'Basic') { |
|
$action .= "?reqinterface=basic"; |
|
} elsif ($mode eq 'Advanced') { |
|
$action .= "?reqinterface=advanced"; |
|
} |
|
$r->print(<<CATALOGCONTROLS); |
|
<form name='results' method="post" action="$action"> |
|
$hidden |
|
<input type='hidden' name='acts' value='' /> |
|
<input type='button' value='Revise search request' |
|
onClick='this.form.submit();' /> |
|
$importbutton |
|
$closebutton |
|
$persistent |
|
<hr /> |
|
CATALOGCONTROLS |
|
if (! tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) { |
|
$r->print('Unable to tie hash to db file</body></html>'); |
|
$r->rflush(); |
|
return; |
|
} |
|
# |
|
my $fnum; |
|
# For now, just query the whole lot and spit them out. |
|
my $table = $ENV{'form.table'}; |
my $table = $ENV{'form.table'}; |
my $connection_result = &Apache::lonmysql::connect_to_db(); |
my $connection_result = &Apache::lonmysql::connect_to_db(); |
if (!defined($connection_result)) { |
if (!defined($connection_result)) { |
&write_status($r,&Apache::lonmysql::get_error()); |
$r->print(&Apache::lonmysql::get_error()); |
|
} |
|
my $table_check = &Apache::lonmysql::check_table($table); |
|
if (! defined($table_check)) { |
|
$r->print("A MySQL error has occurred.</body></html>"); |
|
&Apache::lonnet::logthis("lonmysql was unable to determine the status". |
|
" of table ".$table); |
|
return; |
|
} elsif (! $table_check) { |
|
$r->print("The table of results could not be found."); |
|
&Apache::lonnet::logthis("The user requested a table, ".$table. |
|
", that could not be found."); |
|
return; |
|
} |
|
## |
|
## Get the number of results |
|
## |
|
my $total_results = &Apache::lonmysql::number_of_rows($table); |
|
if (! defined($total_results)) { |
|
$r->print("A MySQL error has occurred.</body></html>"); |
|
&Apache::lonnet::logthis("lonmysql was unable to determine the number". |
|
" of rows in table ".$table); |
|
&Apache::lonnet::logthis(&Apache::lonmysql::get_error()); |
|
&Apache::lonnet::logthis(&Apache::lonmysql::get_debug()); |
|
return; |
|
} |
|
if ($total_results == 0) { |
|
$r->print("There were no results matching your query.\n". |
|
"</form></body></html>"); |
|
return; |
|
} |
|
## |
|
## Determine how many results we need to get |
|
## |
|
$ENV{'form.show'} = 20; |
|
$ENV{'form.start'} = 0 if (! exists($ENV{'form.start'})); |
|
$ENV{'form.show'} = 'all' if (! exists($ENV{'form.show'})); |
|
my $min = $ENV{'form.start'}; |
|
my $max; |
|
if ($ENV{'form.show'} eq 'all') { |
|
$max = $total_results ; |
|
} else { |
|
$max = $min + $ENV{'form.show'}; |
|
$max = $total_results if ($max > $total_results); |
} |
} |
my @Results = &Apache::lonmysql::get_rows($table,'id>=0'); |
## |
#&write_status($r,&Apache::lonmysql::get_debug()); |
## Output links (if necessary) for 'prev' and 'next' pages. |
#&write_status($r,&Apache::lonmysql::get_error()); |
## |
|
$r->print("<center>Results $min to $max out of $total_results</center>\n"); |
|
$r->print |
|
('<br /><center>'. |
|
&prev_next_buttons($min,$ENV{'form.show'},$total_results, |
|
"table=".$ENV{'form.table'}. |
|
"&phase=results". |
|
"&persistent_db_id=".$ENV{'form.persistent_db_id'}) |
|
."</center><br />\n" |
|
); |
|
## |
|
## Get results from MySQL table |
|
## |
|
my @Results = &Apache::lonmysql::get_rows($table, |
|
'id>'.$min.' AND id<='.$max); |
|
## |
|
## Loop through the results and output them. |
|
## |
foreach my $row (@Results) { |
foreach my $row (@Results) { |
my %Fields = %{&parse_row(@$row)}; |
my %Fields = %{&parse_row(@$row)}; |
my $output="\n<p>\n"; |
my $output="<p>\n"; |
if ($ENV{'form.catalogmode'} eq 'interactive') { |
$output.=&catalogmode_output($Fields{'title'},$Fields{'url'}); |
my $titleesc=$Fields{'title'}; |
|
$titleesc=~s/\'/\\'/; # ' |
|
if ($ENV{'form.catalogmode'} eq 'interactive') { |
|
$output.=<<END |
|
<font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT" |
|
onClick="javascript:select_data('$titleesc','$Fields{'url'}')"> |
|
</font> |
|
<br /> |
|
END |
|
} |
|
} |
|
if ($ENV{'form.catalogmode'} eq 'groupsearch') { |
|
$fnum+=0; |
|
$groupsearch_db{"pre_${fnum}_link"}=$Fields{'url'}; |
|
$groupsearch_db{"pre_${fnum}_title"}=$Fields{'title'}; |
|
$output.=<<END; |
|
<font size='-1'> |
|
<input type="checkbox" name="returnvalues" value="SELECT" |
|
onClick="javascript:queue($fnum)" /> |
|
</font> |
|
<br /> |
|
END |
|
# <input type="hidden" name="title$fnum" value="$title" /> |
|
# <input type="hidden" name="url$fnum" value="$url" /> |
|
$fnum++; |
|
} |
|
# Render the result into html |
# Render the result into html |
$output.= &$viewfunction(%Fields); |
$output.= &$viewfunction(%Fields); |
if ($output) { |
$output.="</p>\n<hr align='left' width='200' noshade />"; |
$output.="<hr align='left' width='200' noshade />"; |
# Print them out as they come in. |
} |
|
$r->print($output); |
$r->print($output); |
$r->rflush(); |
$r->rflush(); |
} |
} |
if (@Results < 1) { |
if (@Results < 1) { |
$r->print("There were no results matching your query"); |
$r->print("There were no results matching your query"); |
|
} else { |
|
$r->print |
|
('<br /><center>'. |
|
&prev_next_buttons($min,$ENV{'form.show'},$total_results, |
|
"table=".$ENV{'form.table'}. |
|
"&phase=results". |
|
"&persistent_db_id=". |
|
$ENV{'form.persistent_db_id'}) |
|
."</center><br />\n" |
|
); |
} |
} |
$r->print("</body></html>"); |
$r->print("</body></html>"); |
$r->rflush(); |
$r->rflush(); |
Line 1683 END
|
Line 1957 END
|
|
|
=pod |
=pod |
|
|
|
=item &catalogmode_output($title,$url) |
|
|
|
Returns html needed for the various catalog modes. Gets inputs from |
|
$ENV{'form.catalogmode'}. Stores data in %groupsearch_db and $fnum |
|
(local variable). |
|
|
|
=cut |
|
|
|
###################################################################### |
|
###################################################################### |
|
{ |
|
my $fnum; |
|
|
|
sub catalogmode_output { |
|
my $output = ''; |
|
my ($title,$url) = @_; |
|
if ($ENV{'form.catalogmode'} eq 'interactive') { |
|
$title=~ s/\'/\\'/g; # ' Escape single quotes. |
|
if ($ENV{'form.catalogmode'} eq 'interactive') { |
|
$output.=<<END |
|
<font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT" |
|
onClick="javascript:select_data('$title','$url')"> |
|
</font> |
|
END |
|
} |
|
} |
|
if ($ENV{'form.catalogmode'} eq 'groupsearch') { |
|
$fnum+=0; |
|
$groupsearch_db{"pre_${fnum}_link"}=$url; |
|
$groupsearch_db{"pre_${fnum}_title"}=$title; |
|
$output.=<<END; |
|
<font size='-1'> |
|
<input type="checkbox" name="returnvalues" value="SELECT" |
|
onClick="javascript:queue($fnum)" /> |
|
</font> |
|
END |
|
$fnum++; |
|
} |
|
return $output; |
|
} |
|
|
|
} |
|
###################################################################### |
|
###################################################################### |
|
|
|
=pod |
|
|
=item &parse_row |
=item &parse_row |
|
|
Parse a row returned from the database. |
Parse a row returned from the database. |
Line 1705 sub parse_row {
|
Line 2026 sub parse_row {
|
&Apache::loncommon::filedescription($Fields{'mime'}); |
&Apache::loncommon::filedescription($Fields{'mime'}); |
return \%Fields; |
return \%Fields; |
} |
} |
###################################################################### |
|
###################################################################### |
|
|
|
=pod |
|
|
|
=item &output_results() |
|
|
|
Format and output results based on a reply list. |
|
There are two windows that this function writes to. The main search |
|
window ("srch") has a listing of the results. A secondary window ("popwin") |
|
gives the status of the network search (time elapsed, number of machines |
|
contacted, etc.) |
|
|
|
=cut |
|
|
|
###################################################################### |
|
###################################################################### |
|
sub output_results { |
|
# &Apache::lonnet::logthis("output_results:".time); |
|
my $fnum; # search result counter |
|
my ($mode,$r,$replyref,$hidden)=@_; |
|
my %rhash=%{$replyref}; |
|
my $compiledresult=''; |
|
my $timeremain=300; # (seconds) |
|
my $elapsetime=0; |
|
my $resultflag=0; |
|
my $tflag=1; |
|
## |
|
## Set viewing function |
|
## |
|
my $viewfunction = $Views{$ENV{'form.viewselect'}}; |
|
if (!defined($viewfunction)) { |
|
$r->print("Internal Error - Bad view selected.\n"); |
|
$r->rflush(); |
|
return; |
|
} |
|
# |
|
# make query information persistent to allow for subsequent revision |
|
my $persistent=&make_persistent(\%ENV); |
|
# |
|
# Begin producing output |
|
$r->rflush(); |
|
# |
|
# begin showing the cataloged results |
|
my $action = "/adm/searchcat"; |
|
if ($mode eq 'Basic') { |
|
$action .= "?reqinterface=basic"; |
|
} elsif ($mode eq 'Advanced') { |
|
$action .= "?reqinterface=advanced"; |
|
} |
|
$r->print(<<CATALOGCONTROLS); |
|
<form name='results' method="post" action="$action"> |
|
$hidden |
|
<input type='hidden' name='acts' value='' /> |
|
<input type='button' value='Revise search request' |
|
onClick='this.form.submit();' /> |
|
$importbutton |
|
$closebutton |
|
$persistent |
|
<hr /> |
|
CATALOGCONTROLS |
|
# |
|
# make the pop-up window for status |
|
$r->print(&make_popwin(%rhash)); |
|
$r->rflush(); |
|
## |
|
## Prepare for the main loop below |
|
## |
|
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; |
|
my $hits =@results; |
|
&popwin_js($r,'popwin.hc["'.$rkey.'"]='. |
|
$hits.';'); |
|
$hitcountsum+=$hits; |
|
&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 %groupsearch_db if (tied %groupsearch_db); |
|
# |
|
if (! tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) { |
|
$r->print('<html><head></head><body>Unable to tie hash to db '. |
|
'file</body></html>'); |
|
} 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); |
|
# |
|
# Check copyright tags and skip results the user cannot use |
|
my (undef,undef,$resdom,$resname) = split('/',$Fields{'url'}); |
|
# Check for priv |
|
if (($Fields{'copyright'} eq 'priv') && |
|
(($ENV{'user.name'} ne $resname) && |
|
($ENV{'user.domain'} ne $resdom))) { |
|
next; |
|
} |
|
# Check for domain |
|
if (($Fields{'copyright'} eq 'domain') && |
|
($ENV{'user.domain'} ne $resdom)) { |
|
next; |
|
} |
|
# |
|
$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; |
|
} |
|
} |
|
$compiledresult.="\n<p>\n"; |
|
if ($ENV{'form.catalogmode'} eq 'interactive') { |
|
my $titleesc=$Fields{'title'}; |
|
$titleesc=~s/\'/\\'/; # ' |
|
$compiledresult.=<<END if ($ENV{'form.catalogmode'} eq 'interactive'); |
|
<font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT" |
|
onClick="javascript:select_data('$titleesc','$Fields{'url'}')"> |
|
</font> |
|
<br /> |
|
END |
|
} |
|
if ($ENV{'form.catalogmode'} eq 'groupsearch') { |
|
$fnum+=0; |
|
$groupsearch_db{"pre_${fnum}_link"}=$Fields{'url'}; |
|
$groupsearch_db{"pre_${fnum}_title"}=$Fields{'title'}; |
|
$compiledresult.=<<END; |
|
<font size='-1'> |
|
<input type="checkbox" name="returnvalues" value="SELECT" |
|
onClick="javascript:queue($fnum)" /> |
|
</font> |
|
<br /> |
|
END |
|
# <input type="hidden" name="title$fnum" value="$title" /> |
|
# <input type="hidden" name="url$fnum" value="$url" /> |
|
$fnum++; |
|
} |
|
# Render the result into html |
|
$compiledresult.= &$viewfunction(%Fields, hostname => $rkey ); |
|
if ($compiledresult or $servercount!=$servernum) { |
|
$compiledresult.="<hr align='left' width='200' noshade />"; |
|
} |
|
} |
|
untie %groupsearch_db; |
|
} |
|
if ($compiledresult) { |
|
$resultflag=1; |
|
$r->print($compiledresult); |
|
} |
|
} # End of foreach loop over servers remaining |
|
} # End of big loop - while($serversleft && $timeremain) |
|
unless ($resultflag) { |
|
$r->print("\nThere were no results that matched your query\n"); |
|
} |
|
$r->print('<script type="text/javascript">'.'popwin.close()</script>'. |
|
"\n"); |
|
$r->print("</body>\n</html>\n"); |
|
$r->rflush(); |
|
return; |
|
} |
|
|
|
########################################################### |
########################################################### |
########################################################### |
########################################################### |
Line 2103 Checked for existance & 'edit' mode.
|
Line 2195 Checked for existance & 'edit' mode.
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub search_results_header { |
sub search_results_header { |
my ($mode,$pretty_query) = @_; |
|
$mode = lc($mode); |
|
my $title; |
|
if ($mode eq 'advanced') { |
|
$title = "Advanced Search Results"; |
|
} elsif ($mode eq 'basic') { |
|
$title = "Basic Search Results"; |
|
} |
|
my $result = ''; |
my $result = ''; |
# output beginning of search page |
# output beginning of search page |
$result.=<<BEGINNING; |
|
<html> |
|
<head> |
|
<title>$title</title> |
|
BEGINNING |
|
# conditional output of script functions dependent on the mode in |
# conditional output of script functions dependent on the mode in |
# which the search was invoked |
# which the search was invoked |
if ($ENV{'form.catalogmode'} eq 'interactive'){ |
if ($ENV{'form.catalogmode'} eq 'interactive'){ |
Line 2184 SCRIPT
|
Line 2263 SCRIPT
|
} |
} |
</script> |
</script> |
SCRIPT |
SCRIPT |
$result.=<<SCRIPT; |
|
<script type="text/javascript"> |
|
function displayinfo(val) { |
|
popwin.document.forms.popremain.sdetails.value=val; |
|
} |
|
function openhelp(val) { |
|
openhelpwin=open('/adm/help/searchcat.html','helpscreen', |
|
'scrollbars=1,width=400,height=300'); |
|
openhelpwin.focus(); |
|
} |
|
function abortsearch(val) { |
|
popwin.close(); |
|
} |
|
</script> |
|
SCRIPT |
|
$result.=<<END; |
$result.=<<END; |
</head> |
</head> |
<body bgcolor="#ffffff"> |
|
<img align=right src=/adm/lonIcons/lonlogos.gif> |
|
<h1>$title</h1> |
|
END |
END |
if ($pretty_query) { |
|
$result .= "<p>Search query: $pretty_query</p>"; |
|
} |
|
return $result; |
return $result; |
} |
} |
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
|
sub search_status_header { |
=pod |
return <<ENDSTATUS; |
|
<html><head><title>Search Status</title></head> |
=item &make_popwin() |
<body> |
|
<h3>Search Status</h3> |
Returns html with javascript in it to open up the status window. |
Sending search request to LON-CAPA servers.<br /> |
|
ENDSTATUS |
=cut |
} |
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub make_popwin { |
sub print_frames_interface { |
my %rhash = @_; |
my $r = shift; |
my $servernum=(keys %rhash); |
my $basic_link = "/adm/searchcat?"."&table=".$ENV{'form.table'}. |
my $hcinit; |
"&persistent_db_id=".$ENV{'form.persistent_db_id'}; |
my $grid="'<br />'+\n"; |
my $run_search_link = $basic_link."&phase=run_search"; |
# $sn is the server number, used ONLY to make sure we have |
my $results_link = $basic_link."&phase=results". |
# rows of 10 each. No longer used to index images. |
"&pause=10"."&start=0"."&show=20"; |
my $sn=1; |
my $result = <<"ENDFRAMES"; |
foreach my $sk (sort keys %rhash) { |
<html> |
$grid.="'<a href=\""; |
<head> |
$grid.="javascript:opener.displayinfo('+"; |
<title>LON-CAPA Digital Library Search Results</title> |
$grid.="\"'\"+'"; |
</head> |
$grid.=$sk; |
<frameset rows="150,*"> |
my $hc; |
<frame name="statusframe" src="$run_search_link"> |
if ($rhash{$sk} eq 'con_lost') { |
<frame name="resultsframe" src="$results_link"> |
$hc="BAD CONNECTION "; |
</frameset> |
} |
</html> |
else { |
ENDFRAMES |
$hc="'+\"'\"+\"+hc['$sk']+\"+\"'\"+'"; |
|
$hcinit.="hc[\"$sk\"]=\"not yet connected...\";"; |
$r->print($result); |
} |
return; |
$grid.=" hitcount=".$hc; |
|
$grid.=" domain=".$Apache::lonnet::hostdom{$sk}; |
|
$grid.=" IP=".$Apache::lonnet::hostip{$sk}; |
|
# '+"'"+'">'+ |
|
$grid.="'+\"'\"+')\">'+"; |
|
$grid.="\n"; |
|
$grid.="'<img border=\"0\" name=\"img_".$Apache::lonnet::hostdom{$sk}. |
|
'_'.$sk."\" src=\"/adm/lonIcons/srvnull.gif\" alt=\"".$sk. |
|
"\" /></a>'+\n"; |
|
$grid.="'<br />'+\n" unless $sn%10; |
|
$sn++; |
|
} |
|
my $result.=<<ENDPOP; |
|
<script type="text/javascript"> |
|
popwin=open('','popwin','scrollbars=1,width=400,height=220'); |
|
popwin.focus(); |
|
popwin.document.writeln('<'+'html>'); |
|
popwin.document.writeln('<'+'head>'); |
|
popwin.document.writeln('<'+'script>'); |
|
popwin.document.writeln('hc=new Array();$hcinit'); |
|
popwin.document.writeln('<'+'/script>'); |
|
popwin.document.writeln('<'+'/head>'+ |
|
'<'+'body bgcolor="#FFFFFF">'+ |
|
'<'+'image name="whirly" align="right" src="/adm/lonIcons/'+ |
|
'lonanim.gif" '+ |
|
'alt="animated logo" />'+ |
|
'<'+'h3>Search Results Progress<'+'/h3>'+ |
|
'<'+'form name="popremain">'+ |
|
'<'+'tt>'+ |
|
'<'+'br clear="all"/><i>PLEASE BE PATIENT</i>'+ |
|
'<'+'br />SCANNING $servernum SERVERS'+ |
|
'<'+'br clear="all" />Number of record hits found '+ |
|
'<'+'input type="text" size="10" name="numhits"'+ |
|
' value="0" />'+ |
|
'<'+'br clear="all" />Time elapsed '+ |
|
'<'+'input type="text" size="10" name="elapsetime"'+ |
|
' value="0" />'+ |
|
'<'+'br />'+ |
|
'SERVER GRID (click on any cell for details)'+ |
|
$grid |
|
'<'+'br />'+ |
|
'Server details '+ |
|
'<'+'input type="text" size="35" name="sdetails"'+ |
|
' value="" />'+ |
|
'<'+'br />'+ |
|
' <'+'input type="button" name="button"'+ |
|
' value="close this window" '+ |
|
' onClick="javascript:opener.abortsearch()" />'+ |
|
' <'+'input type="button" name="button"'+ |
|
' value="help" onClick="javascript:opener.openhelp()" />'+ |
|
'<'+'/tt>'+ |
|
'<'+'/form>'+ |
|
'<'+'/body><'+'/html>'); |
|
popwin.document.close(); |
|
</script> |
|
ENDPOP |
|
return $result; |
|
} |
} |
|
|
###################################################################### |
###################################################################### |
Line 2356 END
|
Line 2357 END
|
=item &summary_view() |
=item &summary_view() |
|
|
=cut |
=cut |
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub summary_view { |
sub summary_view { |
Line 2490 sub filled {
|
Line 2490 sub filled {
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub output_blank_field_error { |
sub output_blank_field_error { |
my ($r)=@_; |
my ($r,$closebutton)=@_; |
# make query information persistent to allow for subsequent revision |
# make query information persistent to allow for subsequent revision |
my $persistent=&make_persistent(\%ENV); |
|
|
|
$r->print(<<BEGINNING); |
$r->print(<<BEGINNING); |
<html> |
<html> |
<head> |
<head> |
Line 2505 BEGINNING
|
Line 2503 BEGINNING
|
<img align='right' src='/adm/lonIcons/lonlogos.gif' /> |
<img align='right' src='/adm/lonIcons/lonlogos.gif' /> |
<h1>Search Catalog</h1> |
<h1>Search Catalog</h1> |
<form method="post" action="/adm/searchcat"> |
<form method="post" action="/adm/searchcat"> |
$persistent |
$hidden_fields |
<input type='button' value='Revise search request' |
<a href="/adm/searchcat?persistent_db_id=$ENV{'form.persistent_db_id'}" |
onClick='this.form.submit();' /> |
>Revise search request</a> |
$closebutton |
$closebutton |
<hr /> |
<hr /> |
<h3>Helpful Message</h3> |
<h3>Helpful Message</h3> |
Line 2531 RESULTS
|
Line 2529 RESULTS
|
|
|
Output a full html page with an error message. |
Output a full html page with an error message. |
|
|
|
Inputs: |
|
|
|
$r, the request pointer. |
|
$message, the error message for the user. |
|
$closebutton, the specialized close button needed for groupsearch. |
|
|
=cut |
=cut |
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub output_date_error { |
sub output_date_error { |
my ($r,$message)=@_; |
my ($r,$message,$closebutton)=@_; |
# make query information persistent to allow for subsequent revision |
# make query information persistent to allow for subsequent revision |
my $persistent=&make_persistent(\%ENV); |
|
|
|
$r->print(<<RESULTS); |
$r->print(<<RESULTS); |
<html> |
<html> |
<head> |
<head> |
Line 2549 sub output_date_error {
|
Line 2551 sub output_date_error {
|
<img align='right' src='/adm/lonIcons/lonlogos.gif' /> |
<img align='right' src='/adm/lonIcons/lonlogos.gif' /> |
<h1>Search Catalog</h1> |
<h1>Search Catalog</h1> |
<form method="post" action="/adm/searchcat"> |
<form method="post" action="/adm/searchcat"> |
$persistent |
$hidden_fields |
<input type='button' value='Revise search request' |
<input type='button' value='Revise search request' |
onClick='this.form.submit();' /> |
onClick='this.form.submit();' /> |
$closebutton |
$closebutton |
Line 2589 sub start_fresh_session {
|
Line 2591 sub start_fresh_session {
|
} |
} |
} |
} |
|
|
###################################################################### |
|
###################################################################### |
|
|
|
=pod |
|
|
|
=item &popwin_js() send javascript to popwin |
|
|
|
=cut |
|
|
|
###################################################################### |
|
###################################################################### |
|
sub popwin_js { |
|
# Print javascript out to popwin, but make sure we dont generate |
|
# any javascript errors in doing so. |
|
my ($r,$text) = @_; |
|
$r->print(<<"END"); |
|
<script type="text/javascript"> |
|
if (! popwin.closed) { |
|
$text |
|
} |
|
</script> |
|
END |
|
$r->rflush(); |
|
} |
|
|
|
###################################################################### |
|
###################################################################### |
|
|
|
=pod |
|
|
|
=item &popwin_imgupdate() |
|
|
|
Send a given image (and its location) out to the browser. Takes as |
|
input $r, loncapa server id, and an icon URL. |
|
|
|
=cut |
|
|
|
###################################################################### |
|
###################################################################### |
|
sub popwin_imgupdate { |
|
my ($r,$server,$icon) = @_; |
|
&popwin_js($r,'popwin.document.img_'.$Apache::lonnet::hostdom{$server}. |
|
'_'.$server.'.'.'src="/adm/lonIcons/'.$icon.'";'); |
|
} |
|
|
|
1; |
1; |
|
|
__END__ |
__END__ |