# The LearningOnline Network with CAPA # Search Catalog # # $Id: lonsearchcat.pm,v 1.139 2002/07/08 20:35:36 matthew Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # YEAR=2001 # 3/8, 3/12, 3/13, 3/14, 3/15, 3/19 Scott Harrison # 3/20, 3/21, 3/22, 3/26, 3/27, 4/2, 8/15, 8/24, 8/25 Scott Harrison # 10/12,10/14,10/15,10/16,11/28,11/29,12/10,12/12,12/16 Scott Harrison # YEAR=2002 # 1/17 Scott Harrison # 6/17 Matthew Hall # ############################################################################### ############################################################################### =pod =head1 NAME lonsearchcat =head1 SYNOPSIS Search interface to LON-CAPAs digital library =head1 DESCRIPTION This module enables searching for a distributed browseable catalog. This is part of the LearningOnline Network with CAPA project described at http://www.lon-capa.org. lonsearchcat presents the user with an interface to search the LON-CAPA digital library. lonsearchcat also initiates the execution of a search by sending the search parameters to LON-CAPA servers. The progress of search (on a server basis) is displayed to the user in a seperate window. =head1 Internals =over 4 =cut ############################################################################### ############################################################################### ############################################################################### ## ## ## ORGANIZATION OF THIS PERL MODULE ## ## ## ## 1. Modules used by this module ## ## 2. Variables used throughout the module ## ## 3. handler subroutine called via Apache and mod_perl ## ## 4. Other subroutines ## ## ## ############################################################################### package Apache::lonsearchcat; # ------------------------------------------------- modules used by this module use strict; use Apache::Constants qw(:common); use Apache::lonnet(); use Apache::File(); use CGI qw(:standard); use Text::Query; use GDBM_File; use Apache::loncommon(); # ---------------------------------------- variables used throughout the module ###################################################################### ###################################################################### =pod =item Global variables =over 4 =item $closebutton button that closes the search window =item $importbutton button to take the select results and go to group sorting =item %hash The ubiquitous database hash =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 ###################################################################### ###################################################################### # -- 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 %hash; # 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 ); ###################################################################### ###################################################################### =pod =item &handler() - main handler invoked by httpd child =item Variables =over 4 =item $hidden holds 'hidden' html forms =item $scrout string that holds portions of the screen output =back =cut ###################################################################### ###################################################################### sub handler { my $r = shift; untie %hash; $r->content_type('text/html'); $r->send_http_header; return OK if $r->header_only; 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']); ## ## Clear out old values from database ## if ($ENV{'form.launch'} eq '1') { if (tie(%hash,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) { &start_fresh_session(); untie %hash; } else { $r->print('Unable to tie hash to db '. 'file'); return OK; } } ## ## 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 if ($ENV{'form.catalogmode'} eq 'interactive') { $hidden="". "\n"; $closebutton=""."\n"; } elsif ($ENV{'form.catalogmode'} eq 'groupsearch') { $hidden=< END $closebutton=< END $importbutton=< END } $hidden .= &make_persistent({ "form.mode" => $ENV{'form.mode'}, "form.form" => $ENV{'form.form'}, "form.element" => $ENV{'form.element'}, "form.date" => 2 }); ## ## What are we doing? ## my $searchtype; $searchtype = 'Basic' if ($ENV{'form.basicsubmit'} eq 'SEARCH'); $searchtype = 'Advanced' if ($ENV{'form.advancedsubmit'} eq 'SEARCH'); if ($searchtype) { # We are running a search my ($query,$customquery,$customshow,$libraries) = (undef,undef,undef,undef); if ($searchtype eq 'Basic') { $query = &parse_basic_search($r); } elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') { ($query,$customquery,$customshow,$libraries) = &parse_advanced_search($r); return OK if (! defined($query)); } # Send query statements over the network to be processed by # either the SQL database or a recursive scheme of 'grep'-like # actions (for custom metadata). $r->rflush(); my $reply=&Apache::lonnet::metadata_query($query,$customquery, $customshow,$libraries); &output_results($searchtype,$r,$reply,$hidden); } else { # # 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; } ###################################################################### ###################################################################### =pod =item &basic_search_form() Returns a scalar which holds html for the basic search form. =cut ###################################################################### ###################################################################### sub basic_search_form{ my ($closebutton,$hidden) = @_; my $scrout=<<"ENDDOCUMENT"; The LearningOnline Network with CAPA

Search Catalog

$hidden

Basic Search

Enter terms or phrases separated by AND, OR, or NOT then press SEARCH below.

ENDDOCUMENT $scrout.=' '.&simpletextfield('basicexp',$ENV{'form.basicexp'},40). ' '; # $scrout.=&simplecheckbox('allversions',$ENV{'form.allversions'}); # $scrout.='Search historic archives'; $scrout.=<Advanced Search

   $closebutton END $scrout.=&selectbox(undef,'viewselect', $ENV{'form.viewselect'}, undef,undef,undef, sort(keys(%Views))); $scrout.=<

ENDDOCUMENT return $scrout; } ###################################################################### ###################################################################### =pod =item &advanced_search_form() Returns a scalar which holds html for the advanced search form. =cut ###################################################################### ###################################################################### sub advanced_search_form{ my ($closebutton,$hidden) = @_; my $advanced_buttons = <<"END";

$closebutton

END if (!defined($ENV{'form.viewselect'})) { $ENV{'form.viewselect'} ="Detailed Citation View"; } my $scrout=<<"ENDHEADER"; The LearningOnline Network with CAPA

Advanced Catalog Search


Enter terms or phrases separated by search operators such as AND, OR, or NOT.
$advanced_buttons $hidden \n"; $scrout.=&searchphrasefield('title', 'title' ,$ENV{'form.title'}); $scrout.=&searchphrasefield('author', 'author' ,$ENV{'form.author'}); $scrout.=&searchphrasefield('subject', 'subject' ,$ENV{'form.subject'}); $scrout.=&searchphrasefield('keywords','keywords',$ENV{'form.keywords'}); $scrout.=&searchphrasefield('URL', 'url' ,$ENV{'form.url'}); $scrout.=&searchphrasefield('notes', 'notes' ,$ENV{'form.notes'}); $scrout.=&searchphrasefield('abstract','abstract',$ENV{'form.abstract'}); # Hack - an empty table row. $scrout.="\n"; $scrout.=&searchphrasefield('file
extension','mime', $ENV{'form.mime'}); $scrout.="\n"; $scrout.=&searchphrasefield('publisher
owner','owner', $ENV{'form.owner'}); $scrout.="
VIEW: ENDHEADER $scrout.=&selectbox(undef,'viewselect', $ENV{'form.viewselect'}, undef,undef,undef, sort(keys(%Views))); $scrout.="
  
  
\n"; $ENV{'form.category'}='any' unless length($ENV{'form.category'}); $scrout.=&selectbox('File Category','category', $ENV{'form.category'}, 'any','Any category', undef, (&Apache::loncommon::filecategories())); $ENV{'form.language'}='any' unless length($ENV{'form.language'}); #---------------------------------------------------------------- # Allow restriction to multiple domains. # I make the crazy assumption that there will never be a domain 'any'. # $ENV{'form.domains'} = 'any' if (! exists($ENV{'form.domains'})); my @allowed_domains = (ref($ENV{'form.domains'}) ? @{$ENV{'form.domains'}} : ($ENV{'form.domains'}) ); my %domain_hash = (); foreach (@allowed_domains) { $domain_hash{$_}++; } my @domains =&Apache::loncommon::get_domains(); # adjust the size of the select box my $size = 4; my $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size); # standalone machines do not get to choose a domain to search. if ((scalar @domains) == 1) { $scrout .=''."\n"; } else { $scrout.="\n".''. 'DOMAINS
'. '\n"; } #---------------------------------------------------------------- $scrout.=&selectbox('Limit by language','language', $ENV{'form.language'},'any','Any Language', \&{Apache::loncommon::languagedescription}, (&Apache::loncommon::languageids), ); # ------------------------------------------------ Compute date selection boxes $scrout.=< LIMIT BY CREATION DATE RANGE:
between: CREATIONDATESTART $scrout.=&dateboxes('creationdatestart',1,1,1976, $ENV{'form.creationdatestart_month'}, $ENV{'form.creationdatestart_day'}, $ENV{'form.creationdatestart_year'}, ); $scrout.="and:\n"; $scrout.=&dateboxes('creationdateend',12,31,2051, $ENV{'form.creationdateend_month'}, $ENV{'form.creationdateend_day'}, $ENV{'form.creationdateend_year'}, ); $scrout.="

"; $scrout.=< LIMIT BY LAST REVISION DATE RANGE:
between: LASTREVISIONDATESTART $scrout.=&dateboxes('lastrevisiondatestart',1,1,1976, $ENV{'form.lastrevisiondatestart_month'}, $ENV{'form.lastrevisiondatestart_day'}, $ENV{'form.lastrevisiondatestart_year'}, ); $scrout.=< LIMIT BY SPECIAL METADATA FIELDS: For resource-specific metadata, enter in an expression in the form of key=value separated by operators such as AND, OR or NOT.
Example: grandmother=75 OR grandfather=85
CUSTOMMETADATA $scrout.=&simpletextfield('custommetadata',$ENV{'form.custommetadata'}); $scrout.=< SHOW SPECIAL METADATA FIELDS: Enter in a space-separated list of special metadata fields to show in a fielded listing for each record result.
CUSTOMSHOW $scrout.=&simpletextfield('customshow',$ENV{'form.customshow'}); $scrout.=< ENDDOCUMENT return $scrout; } ###################################################################### ###################################################################### =pod =item &make_persistent() 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. =cut ###################################################################### ###################################################################### sub make_persistent { my %save = %{shift()}; my $persistent=''; foreach (keys %save) { if (/^form\./ && !/submit/) { my $name=$_; my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name})); $name=~s/^form\.//; foreach (@values) { s/\"/\'/g; # do not mess with html field syntax $persistent.=< END } } } return $persistent; } ###################################################################### ###################################################################### =pod =item HTML form building functions =over 4 =item &simpletextfield() 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. =item &simplecheckbox() Inputs: $name,$value Returns a simple check box with the given $name. If $value eq 'on' the box is checked. =item &searchphrasefield() 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. =item &dateboxes() Returns html selection form elements for the specification of the day, month, and year. =item &selectbox() Returns a scalar containing an html tag. =item $default The default value of the form. Can be $anyvalue, or in @idlist. =item $anyvalue The