--- loncom/interface/lonsearchcat.pm 2001/03/15 20:11:18 1.34 +++ loncom/interface/lonsearchcat.pm 2002/06/19 20:39:11 1.123 @@ -1,88 +1,283 @@ -# The LearningOnline Network +# The LearningOnline Network with CAPA # Search Catalog # -# 03/08/2001 Scott Harrison +# $Id: lonsearchcat.pm,v 1.123 2002/06/19 20:39:11 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. 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 ## +## ## +############################################################################### + 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 %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 -my %language; -my $scrout; -my %metadatafields; -my %cprtag; -my %mimetag; +=item $importbutton +button to take the selecte results and go to group sorting + +=item $hidden + +holds 'hidden' html forms + +=item $scrout + +string that holds portions of the screen output + +=item $yourself + +allows for quickly limiting to oneself + +=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(). + +=back + +=cut + +###################################################################### +###################################################################### + +# -- 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 +my $hidden; # Holds 'hidden' html forms + +# -- miscellaneous variables +my $scrout; # string that holds portions of the screen output +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{$_}; + } +} + +###################################################################### +###################################################################### + +=pod + +=item &handler() - main handler invoked by httpd child + +=cut + +###################################################################### +###################################################################### +# ----------------------------- Handling routine called via Apache and mod_perl sub handler { my $r = shift; - -# -------------------------------------- see if called from an interactive mode - map { - my ($name, $value) = split(/=/,$_); - $value =~ tr/+/ /; - $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; - if ($name eq 'catalogmode') { - $ENV{'form.'.$name}=$value; - } - } (split(/&/,$ENV{'QUERY_STRING'})); + untie %hash; $r->content_type('text/html'); $r->send_http_header; return OK if $r->header_only; - %metadatafields=(); + 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']); + + 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; + } + } - my $hidden=''; - $hidden=<
LIMIT BY LAST REVISION DATE RANGE:
-
between:
+
between:
LASTREVISIONDATESTART
$scrout.=&dateboxes('lastrevisiondatestart',1,1,1976,
$ENV{'form.lastrevisiondatestart_month'},
@@ -164,64 +364,105 @@ LASTREVISIONDATEEND
$scrout.=&searchphrasefield('Limit by publisher/owner','owner',
$ENV{'form.owner'});
-# $metadatafields{'owner'});
$ENV{'form.copyright'}='any' unless length($ENV{'form.copyright'});
$scrout.=&selectbox('Limit by copyright/distribution','copyright',
- $ENV{'form.copyright'},%cprtag);
+ $ENV{'form.copyright'},
+ 'any','Any copyright/distribution',
+ \&{Apache::loncommon::copyrightdescription},
+ (&Apache::loncommon::copyrightids),
+ );
# ------------------------------------------- Compute customized metadata field
$scrout.=<
+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.=' initial users of this system do not need to worry about this option';
+ $scrout.=<
+CUSTOMSHOW
+$scrout.=&simpletextfield('customshow',$ENV{'form.customshow'});
+$scrout.=' initial users of this system do not need to worry about this option';
+
# ---------------------------------------------------------------- Print screen
$r->print(<Search Catalog
-
-
-
+
+
+
+$closebutton
+
+
+
+
- - - + + +$closebutton + + + +
@@ -230,386 +471,552 @@ ENDDOCUMENT return OK; } -# --------------------------------------------------------- Various form fields +###################################################################### +###################################################################### -sub textfield { - my ($title,$name,$value)=@_; - return "\n$title: '.$uctitle.':'.
+ " $instruction $uctitle:".
- "
".
- '';
+=pod
+
+=item &make_persistent()
+
+Returns a scalar which holds the current ENV{'form.*'} values in
+a 'hidden' html input tag.
+
+=cut
+
+######################################################################
+######################################################################
+
+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.=<
".
- '';
+ return "\n".
+ '
".&simpletextfield($name,$value,80);
}
sub dateboxes {
my ($name,$defaultmonth,$defaultday,$defaultyear,
$currentmonth,$currentday,$currentyear)=@_;
($defaultmonth,$defaultday,$defaultyear)=('','','');
- my $month=<
".'Search Results
+RESULTS
+ }
+ elsif ($mode eq 'Advanced') {
+ $r->print(<Search Results
');
+ $r->rflush();
+ my $servernum=(keys %rhash)+0;
+
+ # define server grid (shows status of multiple machines)
+ my $hcinit;
+ my $grid="'
'+";
+ $grid.="\n";
+ my $sn=1;
+ for my $sk (sort keys %rhash) {
+ # ''+
+ $grid.="'+\"'\"+')\">'+";
+ $grid.="\n";
+ $grid.="''+\n";
+ $grid.="'
'+\n" unless $sn%10;
+ $sn++;
+ }
+ $r->print(<
\n";
+ }
+ }
+ my $customdata='';
+ my %customhash;
+ foreach my $result (@results) {
+ if ($result=~/^(custom\=.*)$/) { # grab all custom metadata
+ my $tmp=$result;
+ $tmp=~s/^custom\=//;
+ my ($k,$v)=map {&Apache::lonnet::unescape($_);
+ } split(/\,/,$tmp);
+ $customhash{$k}=$v;
+ }
+ }
+ if (keys %hash) {
+ untie %hash;
+ }
+ if (tie(%hash,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) {
+ if ($ENV{'form.launch'} eq '1') {
+ &start_fresh_session();
+ }
+ foreach my $result (@results) {
+ next if $result=~/^custom\=/;
+ chomp $result;
+ next unless $result;
+ my @fields=map
+ {&Apache::lonnet::unescape($_)}
+ (split(/\,/,$result));
+ my ($title,$author,$subject,$url,$keywords,$version,
+ $notes,$abstract,$mime,$lang,
+ $creationdate,$lastrevisiondate,$owner,$copyright)=@fields;
+
+ unless ($title) { $title='Untitled'; }
+ unless ($ENV{'user.adv'}) {
+ $keywords='- not displayed -';
+ $fields[4]=$keywords;
+ $notes='- not displayed -';
+ $fields[6]=$notes;
+ $abstract='- not displayed -';
+ $fields[7]=$abstract;
+ $subject='- not displayed -';
+ $fields[2]=$subject;
+ }
+
+ my $shortabstract=$abstract;
+ $shortabstract=substr($abstract,0,200).'...' if length($abstract)>200;
+ $fields[7]=$shortabstract;
+ my $shortkeywords=$keywords;
+ $shortkeywords=substr($keywords,0,200).'...' if length($keywords)>200;
+ $fields[4]=$shortkeywords;
+
+ my $extrashow2=$extrashow;
+ if ($extrashow) {
+ foreach my $field (@customfields) {
+ my $value='';
+ if ($customhash{$url}=~/\<${field}[^\>]*\>(.*?)\<\/${field}[^\>]*\>/s) {
+ $value=$1;
+ }
+ $extrashow2=~s/\<\!\-\- $field \-\-\>/ $value/g;
+ }
+ }
+
+ $compiledresult.=<
+END
+ }
+ if ($ENV{'form.catalogmode'} eq 'groupsearch') {
+ $fnum+=0;
+ $hash{"pre_${fnum}_link"}=$url;
+ $hash{"pre_${fnum}_title"}=$title;
+ $compiledresult.=<
+END
+#
+#
+ $fnum++;
+ }
+ my $httphost=$ENV{'HTTP_HOST'};
+
+ my $viewselect;
+ if ($mode eq 'Basic') {
+ $viewselect=$ENV{'form.basicviewselect'};
+ }
+ elsif ($mode eq 'Advanced') {
+ $viewselect=$ENV{'form.advancedviewselect'};
+ }
+
+ if ($viewselect eq 'Detailed Citation View') {
+ $compiledresult.=&detailed_citation_view(@fields,
+ $hostname,$httphost,
+ $extrashow2);
+ }
+ elsif ($viewselect eq 'Summary View') {
+ $compiledresult.=&summary_view(@fields,$hostname,$httphost,
+ $extrashow2);
+ }
+ elsif ($viewselect eq 'Fielded Format') {
+ $compiledresult.=&fielded_format_view(@fields,$hostname,
+ $httphost,$extrashow2);
+ }
+ elsif ($viewselect eq 'XML/SGML') {
+ $compiledresult.=&xml_sgml_view(@fields,$hostname,$httphost,
+ $extrashow2);
+ }
+
+ }
+
+ untie %hash;
+ }
+ else {
+ $r->print('Unable to tie hash to db '.
+ 'file');
+ }
+ if ($compiledresult) {
+ $resultflag=1;
+ }
+
+ $r->print(<$title
+$author
+
+Subject: $subject
+Keyword(s): $keywords
+Notes: $notes
+MIME Type:
+END
+ $result.=&Apache::loncommon::filedescription($mime);
+ $result.=<
+$shortabstract +
+END + return $result; +} + +###################################################################### +###################################################################### + +=pod + +=item &summary_view() + +=cut + +###################################################################### +###################################################################### +sub summary_view { + my ($title,$author,$subject,$url,$keywords,$version, + $notes,$shortabstract,$mime,$lang, + $creationdate,$lastrevisiondate,$owner,$copyright, + $hostname,$httphost,$extrashow)=@_; + my $cprtag=&Apache::loncommon::copyrightdescription($copyright); + my $result=<