version 1.37, 2001/03/15 20:59:00
|
version 1.57, 2001/03/21 03:15:46
|
Line 2
|
Line 2
|
# Search Catalog |
# Search Catalog |
# |
# |
# 03/08/2001 Scott Harrison |
# 03/08/2001 Scott Harrison |
|
# Scott Harrison: 03/12/2001, 03/13/2001, 03/14/2001, 03/15/2001, 03/19/2001 |
|
# Scott Harrison: 03/20/2001 |
# |
# |
|
# Functions |
|
# |
|
# handler(server reference) : interacts with the Apache server layer |
|
# (for /adm/searchcat URLs) |
|
# simpletextfield(name,value) : returns HTML formatted string for simple text |
|
# field |
|
# simplecheckbox(name,value) : returns HTML formatted string for simple |
|
# checkbox |
|
# searchphrasefield(title,name,value) : returns HTML formatted string for |
|
# a search expression phrase field |
|
# dateboxes(name, defaultmonth, defaultday, defaultyear) : returns HTML |
|
# formatted string |
|
# for a calendar date |
|
# selectbox(title,name,value,%HASH=options) : returns HTML formatted string for |
|
# a selection box field |
|
# advancedsearch(server reference, environment reference) : perform a complex |
|
# multi-field logical query |
|
# filled(field) : determines whether a given field has been filled |
|
# basicsearch(server reference, environment reference) : perform a simple |
|
# single-field logical query |
|
# output_blank_field_error(server reference) : outputs a message saying that |
|
# more fields need to be filled in |
|
# output_results(output mode, |
|
# server reference, |
|
# environment reference, |
|
# reply list reference) : outputs results from search |
|
# build_SQL_query(field name, logic) : builds a SQL query string from a |
|
# logical expression with AND/OR keywords |
|
# recursive_SQL_query_build(field name, reverse notation expression) : |
|
# builds a SQL query string from a reverse notation expression |
|
# logical expression with AND/OR keywords |
|
|
package Apache::lonsearchcat; |
package Apache::lonsearchcat; |
|
|
use strict; |
use strict; |
Line 10 use Apache::Constants qw(:common);
|
Line 44 use Apache::Constants qw(:common);
|
use Apache::lonnet(); |
use Apache::lonnet(); |
use Apache::File(); |
use Apache::File(); |
use CGI qw(:standard); |
use CGI qw(:standard); |
|
use Text::Query; |
|
|
my %language; |
my %language; |
my $scrout; |
my $scrout; |
my %metadatafields; |
my %metadatafields; |
my %cprtag; |
my %cprtag; |
my %mimetag; |
my %mimetag; |
|
my $closebutton; |
|
my $basicviewselect=<<END; |
|
<select name='basicviewselect'> |
|
<option value='Detailed Citation View'>Detailed Citation View</option> |
|
<option value='Summary View'>Summary View</option> |
|
<option value='Fielded Format'>Fielded Format</option> |
|
<option value='XML/SGML'>XML/SGML</option> |
|
</select> |
|
END |
|
my $advancedviewselect=<<END; |
|
<select name='advancedviewselect'> |
|
<option value='Detailed Citation View'>Detailed Citation View</option> |
|
<option value='Summary View'>Summary View</option> |
|
<option value='Fielded Format'>Fielded Format</option> |
|
<option value='XML/SGML'>XML/SGML</option> |
|
</select> |
|
END |
|
|
sub handler { |
sub handler { |
my $r = shift; |
my $r = shift; |
Line 41 sub handler {
|
Line 93 sub handler {
|
<input type='hidden' name='catalogmode' value='interactive'> |
<input type='hidden' name='catalogmode' value='interactive'> |
END |
END |
|
|
|
$closebutton=<<END if $ENV{'form.catalogmode'} eq 'interactive'; |
|
<input type="button" name="close" value="CLOSE" onClick="self.close()"> |
|
END |
|
|
# ------------------------------------------------ First, check out environment |
# ------------------------------------------------ First, check out environment |
$metadatafields{'owner'}=$ENV{'user.name'}.'@'.$ENV{'user.domain'}; |
$metadatafields{'owner'}=$ENV{'user.name'}.'@'.$ENV{'user.domain'}; |
|
|
Line 51 END
|
Line 107 END
|
{ |
{ |
my $fh=Apache::File->new($r->dir_config('lonTabDir').'/language.tab'); |
my $fh=Apache::File->new($r->dir_config('lonTabDir').'/language.tab'); |
map { |
map { |
$_=~/(\w+)\s+([\w\s\-]+)/; |
$_=~/(\w+)\s+([\w\s\-]+)/; chomp; |
$language{$1}=$2; |
$language{$1}=$2; |
} <$fh>; |
} <$fh>; |
} |
} |
Line 61 END
|
Line 117 END
|
{ |
{ |
my $fh=Apache::File->new($r->dir_config('lonIncludes').'/copyright.tab'); |
my $fh=Apache::File->new($r->dir_config('lonIncludes').'/copyright.tab'); |
map { |
map { |
$_=~/(\w+)\s+([\w\s\-]+)/; |
$_=~/(\w+)\s+([\w\s\-]+)/; chomp; |
$cprtag{$1}=$2; |
$cprtag{$1}=$2; |
} <$fh>; |
} <$fh>; |
} |
} |
Line 71 END
|
Line 127 END
|
{ |
{ |
my $fh=Apache::File->new($r->dir_config('lonTabDir').'/filetypes.tab'); |
my $fh=Apache::File->new($r->dir_config('lonTabDir').'/filetypes.tab'); |
map { |
map { |
$_=~/(\w+)\s+(\w+)\s+([\w\s\-]+)/; |
$_=~/(\w+)\s+(\w+)\s+([\w\s\-]+)/; chomp; |
$mimetag{$1}=".$1 $3"; |
$mimetag{$1}=".$1 $3"; |
} <$fh>; |
} <$fh>; |
} |
} |
Line 213 ENDDOCUMENT
|
Line 269 ENDDOCUMENT
|
<br> |
<br> |
<input type="submit" name="basicsubmit" value="SEARCH"> |
<input type="submit" name="basicsubmit" value="SEARCH"> |
<input type="reset" name="reset" value="RESET"> |
<input type="reset" name="reset" value="RESET"> |
<input type="button" name="close" value="CLOSE" onClick="self.close()"> |
$closebutton |
|
$basicviewselect |
</p> |
</p> |
<hr> |
<hr> |
<h3>Advanced Search</h3> |
<h3>Advanced Search</h3> |
Line 221 $scrout
|
Line 278 $scrout
|
<p> |
<p> |
<input type="submit" name="advancedsubmit" value="SEARCH"> |
<input type="submit" name="advancedsubmit" value="SEARCH"> |
<input type="reset" name="reset" value="RESET"> |
<input type="reset" name="reset" value="RESET"> |
<input type="button" name="close" value="CLOSE" onClick="self.close()"> |
$closebutton |
|
$advancedviewselect |
</p> |
</p> |
</form> |
</form> |
</body> |
</body> |
Line 232 ENDDOCUMENT
|
Line 290 ENDDOCUMENT
|
|
|
# --------------------------------------------------------- Various form fields |
# --------------------------------------------------------- Various form fields |
|
|
sub textfield { |
|
my ($title,$name,$value)=@_; |
|
return "\n<p><b>$title:</b><br>". |
|
'<input type=text name="'.$name.'" size=80 value="'.$value.'">'; |
|
} |
|
|
|
sub simpletextfield { |
sub simpletextfield { |
my ($name,$value)=@_; |
my ($name,$value)=@_; |
return '<input type=text name="'.$name.'" size=20 value="'.$value.'">'; |
return '<input type=text name="'.$name.'" size=20 value="'.$value.'">'; |
Line 419 sub selectbox {
|
Line 471 sub selectbox {
|
return $selout.'</select>'; |
return $selout.'</select>'; |
} |
} |
|
|
# ------------------------------------------------ Performing a advanced search |
# ----------------------------------------------- Performing an advanced search |
sub advancedsearch { |
sub advancedsearch { |
my ($r,$envhash)=@_; |
my ($r,$envhash)=@_; |
my %ENV=%{$envhash}; |
my %ENV=%{$envhash}; |
Line 428 sub advancedsearch {
|
Line 480 sub advancedsearch {
|
for my $field ('title','author','subject','keywords','url','version', |
for my $field ('title','author','subject','keywords','url','version', |
'notes','abstract','mime','language','owner', |
'notes','abstract','mime','language','owner', |
'custommetadata') { |
'custommetadata') { |
if (&filled($ENV{'form.basicexp'})) { |
if (&filled($ENV{"form.$field"})) { |
$fillflag++; |
$fillflag++; |
} |
} |
} |
} |
Line 438 sub advancedsearch {
|
Line 490 sub advancedsearch {
|
return OK; |
return OK; |
} |
} |
|
|
$r->print(<<END); |
my $query=''; |
Advanced searching is not yet implemented. |
|
END |
my @queries; |
|
# Go through logical expression AND/OR/NOT phrase fields. |
|
foreach my $field ('title','author','subject','notes','abstract') { |
|
if ($ENV{'form.'.$field}) { |
|
push @queries,&build_SQL_query($field,$ENV{'form.'.$field}); |
|
} |
|
} |
|
if (@queries) { |
|
$query=join(" and ",@queries); |
|
$query="select * from metadata where $query"; |
|
my $reply=&Apache::lonnet::metadata_query($query); |
|
&output_results('Advanced',$r,$envhash,$query,$reply); |
|
} |
|
else { |
|
&output_results('Advanced',$r,$envhash,$query); |
|
} |
return OK; |
return OK; |
} |
} |
|
|
Line 465 sub basicsearch {
|
Line 532 sub basicsearch {
|
return OK; |
return OK; |
} |
} |
|
|
my $query=$ENV{'form.basicexp'}; |
my $query=''; |
my $concatarg=join('," ",', |
my $concatarg=join('," ",', |
('title', 'author', 'subject', 'notes', 'abstract')); |
('title', 'author', 'subject', 'notes', 'abstract')); |
|
|
$query="select * from metadata where concat($concatarg) like '\%$ENV{'form.basicexp'}\%'"; |
$query="select * from metadata where concat($concatarg) like '\%$ENV{'form.basicexp'}\%'"; |
my $reply=&Apache::lonnet::metadata_query($query); |
my $reply=&Apache::lonnet::metadata_query($query); |
&output_results($r,$envhash,$reply); |
&output_results('Basic',$r,$envhash,$query,$reply); |
return OK; |
return OK; |
} |
} |
|
|
|
# ---------------- Message to output when there are not enough fields filled in |
sub output_blank_field_error { |
sub output_blank_field_error { |
my ($r)=@_; |
my ($r)=@_; |
# make query information persistent to allow for subsequent revision |
# make query information persistent to allow for subsequent revision |
Line 504 BEGINNING
|
Line 572 BEGINNING
|
$persistent |
$persistent |
<input type='button' value='Revise search request' |
<input type='button' value='Revise search request' |
onClick='this.form.submit();'> |
onClick='this.form.submit();'> |
<input type='button' value='CLOSE' |
$closebutton |
onClick='self.close();'> |
|
<hr> |
<hr> |
<h3>Helpful Message</h3> |
<h3>Helpful Message</h3> |
<p> |
<p> |
Line 521 RESULTS
|
Line 588 RESULTS
|
|
|
# ----------------------------- format and output results based on a reply list |
# ----------------------------- format and output results based on a reply list |
sub output_results { |
sub output_results { |
my ($r,$envhash,@replylist)=@_; |
my ($mode,$r,$envhash,$query,@replylist)=@_; |
my %ENV=%{$envhash}; |
my %ENV=%{$envhash}; |
|
my $compiledresult=''; |
|
|
foreach my $reply (@replylist) { |
foreach my $reply (@replylist) { |
|
|
my @results; |
my @results; |
Line 532 sub output_results {
|
Line 601 sub output_results {
|
$replyfile=$r->dir_config('lonDaemons').'/tmp/'.$1; |
$replyfile=$r->dir_config('lonDaemons').'/tmp/'.$1; |
$reply=~/(.*?)\_/; |
$reply=~/(.*?)\_/; |
my $hostname=$1; |
my $hostname=$1; |
|
sleep 3; # temporary fix, need to check for completion and status |
{ |
{ |
while (1) { |
while (1) { |
last if -e $replyfile; |
last if -e $replyfile; |
Line 545 sub output_results {
|
Line 614 sub output_results {
|
@results=<$fh>; |
@results=<$fh>; |
} |
} |
|
|
my $compiledresult=''; |
|
|
|
foreach my $result (@results) { |
foreach my $result (@results) { |
|
my @fields=map |
|
{&Apache::lonnet::unescape($_)} |
|
(split(/\,/,$result)); |
my ($title,$author,$subject,$url,$keywords,$version, |
my ($title,$author,$subject,$url,$keywords,$version, |
$notes,$abstract,$mime,$lang, |
$notes,$abstract,$mime,$lang, |
$creationdate,$lastrevisiondate,$owner,$copyright |
$creationdate,$lastrevisiondate,$owner,$copyright)=@fields; |
)=map {&Apache::lonnet::unescape($_)} (split(/\,/,$result)); |
|
my $shortabstract=$abstract; |
my $shortabstract=$abstract; |
$shortabstract=substr($abstract,0,200) if length($abstract)>200; |
$shortabstract=substr($abstract,0,200) if length($abstract)>200; |
|
$fields[7]=$shortabstract; |
$compiledresult.=<<END; |
$compiledresult.=<<END; |
<p> |
<p> |
END |
END |
Line 563 onClick="javascript:select_data('$title'
|
Line 633 onClick="javascript:select_data('$title'
|
</font> |
</font> |
<br> |
<br> |
END |
END |
$compiledresult.=<<END; |
my $httphost=$ENV{'HTTP_HOST'}; |
<b>URL: </b> <A HREF="http://$ENV{'HTTP_HOST'}$url" TARGET='search_preview'>$url</A> |
|
<br> |
my $viewselect; |
<b>Title:</b> $title<br> |
if ($mode eq 'Basic') { |
<b>Author(s):</b> $author<br> |
$viewselect=$ENV{'form.basicviewselect'}; |
<b>Subject:</b> $subject<br> |
} |
<b>Keyword(s):</b> $keywords<br> |
elsif ($mode eq 'Advanced') { |
<b>Notes:</b> $notes<br> |
$viewselect=$ENV{'form.advancedviewselect'}; |
<b>Abstract:</b> $shortabstract<br> |
} |
<b>MIME Type:</b> $mimetag{$mime}<br> |
|
<b>Language:</b> $language{$lang}<br> |
if ($viewselect eq 'Detailed Citation View') { |
<b>Creation Date:</b> $creationdate<br> |
$compiledresult.=&detailed_citation_view(@fields, |
<b>Last Revision Date:</b> $lastrevisiondate<br> |
$hostname,$httphost); |
<b>Publisher/Owner:</b> $owner<br> |
} |
<b>Copyright/Distribution:</b> $copyright<br> |
elsif ($viewselect eq 'Summary View') { |
<b>Repository Location:</b> $hostname |
$compiledresult.=&summary_view(@fields,$hostname,$httphost); |
</p> |
} |
END |
elsif ($viewselect eq 'Fielded Format') { |
|
$compiledresult.=&fielded_format_view(@fields,$hostname, |
|
$httphost); |
|
} |
|
elsif ($viewselect eq 'XML/SGML') { |
|
$compiledresult.=&xml_sgml_view(@fields,$hostname,$httphost); |
|
} |
|
|
} |
} |
|
|
unless ($compiledresult) { |
unless ($compiledresult) { |
Line 631 SCRIPT
|
Line 708 SCRIPT
|
<form method="post" action="/adm/searchcat"> |
<form method="post" action="/adm/searchcat"> |
<input type='button' value='Revise search request' |
<input type='button' value='Revise search request' |
onClick='this.form.submit();'> |
onClick='this.form.submit();'> |
<input type='button' value='CLOSE' |
$closebutton |
onClick='self.close();'> |
|
$persistent |
$persistent |
<hr> |
<hr> |
<h3>Search Query</h3> |
<h3>Search Query</h3> |
|
RESULTS |
|
if ($mode eq 'Basic') { |
|
$r->print(<<RESULTS); |
<p> |
<p> |
<b>Basic search:</b> $ENV{'form.basicexp'} |
<b>Basic search:</b> $ENV{'form.basicexp'} |
</p> |
</p> |
|
RESULTS |
|
} |
|
elsif ($mode eq 'Advanced') { |
|
$r->print(<<RESULTS); |
|
<p> |
|
<b>Advanced search</b> |
|
$query |
|
</p> |
|
RESULTS |
|
} |
|
$r->print(<<RESULTS); |
<h3>Search Results</h3> |
<h3>Search Results</h3> |
$compiledresult |
$compiledresult |
</body> |
</body> |
Line 647 RESULTS
|
Line 737 RESULTS
|
} |
} |
} |
} |
|
|
|
# ------------------------------------------------------------- build_SQL_query |
|
sub build_SQL_query { |
|
my ($field_name,$logic_statement)=@_; |
|
my $q=new Text::Query('abc', |
|
-parse => 'Text::Query::ParseAdvanced', |
|
-build => 'Text::Query::Build'); |
|
$q->prepare($logic_statement); |
|
my $matchexp=${$q}{'matchexp'}; chomp $matchexp; |
|
my $sql_query=&recursive_SQL_query_build($field_name,$matchexp); |
|
return $sql_query; |
|
} |
|
|
|
# - Recursively parse a reverse notation expression into a SQL query expression |
|
sub recursive_SQL_query_build { |
|
my ($dkey,$pattern)=@_; |
|
my @matches=($pattern=~/(\[[^\]|\[]*\])/g); |
|
return $pattern unless @matches; |
|
foreach my $match (@matches) { |
|
$match=~/\[ (\w+)\s(.*) \]/; |
|
my ($key,$value)=($1,$2); |
|
my $replacement=''; |
|
if ($key eq 'literal') { |
|
$replacement="($dkey like \"\%$value\%\")"; |
|
} |
|
elsif ($key eq 'and') { |
|
$value=~/(.*[\"|\)]) ([|\(|\^].*)/; |
|
$replacement="($1 AND $2)"; |
|
} |
|
elsif ($key eq 'or') { |
|
$value=~/(.*[\"|\)]) ([|\(|\^].*)/; |
|
$replacement="($1 OR $2)"; |
|
} |
|
substr($pattern, |
|
index($pattern,$match), |
|
length($match), |
|
$replacement |
|
); |
|
} |
|
&recursive_SQL_query_build($dkey,$pattern); |
|
} |
|
|
|
# ------------------------------------------------------ Detailed Citation View |
|
sub detailed_citation_view { |
|
my ($title,$author,$subject,$url,$keywords,$version, |
|
$notes,$shortabstract,$mime,$lang, |
|
$creationdate,$lastrevisiondate,$owner,$copyright, |
|
$hostname,$httphost)=@_; |
|
my $result=<<END; |
|
<i>$owner</i>, last revised $lastrevisiondate |
|
<h3><A HREF="http://$httphost$url" TARGET='search_preview'>$title</A></h3> |
|
<h3>$author</h3> |
|
</p> |
|
<p> |
|
<b>Subject:</b> $subject<br> |
|
<b>Keyword(s):</b> $keywords<br> |
|
<b>Notes:</b> $notes<br> |
|
<b>MIME Type:</b> $mimetag{$mime}<br> |
|
<b>Language:</b> $language{$lang}<br> |
|
<b>Copyright/Distribution:</b> $cprtag{$copyright}<br> |
|
$shortabstract |
|
</p> |
|
END |
|
return $result; |
|
} |
|
|
|
# ---------------------------------------------------------------- Summary View |
|
sub summary_view { |
|
my ($title,$author,$subject,$url,$keywords,$version, |
|
$notes,$shortabstract,$mime,$lang, |
|
$creationdate,$lastrevisiondate,$owner,$copyright, |
|
$hostname,$httphost)=@_; |
|
my $result=<<END; |
|
<a href="http://$httphost$url" TARGET='search_preview'>$author</a><br /> |
|
$title<br /> |
|
$owner -- $lastrevisiondate<br /> |
|
$cprtag{$copyright}<br /> |
|
</p> |
|
END |
|
return $result; |
|
} |
|
|
|
# -------------------------------------------------------------- Fielded Format |
|
sub fielded_format_view { |
|
my ($title,$author,$subject,$url,$keywords,$version, |
|
$notes,$shortabstract,$mime,$lang, |
|
$creationdate,$lastrevisiondate,$owner,$copyright, |
|
$hostname,$httphost)=@_; |
|
my $result=<<END; |
|
<b>URL: </b> <A HREF="http://$httphost$url" TARGET='search_preview'>$url</A> |
|
<br /> |
|
<b>Title:</b> $title<br /> |
|
<b>Author(s):</b> $author<br /> |
|
<b>Subject:</b> $subject<br /> |
|
<b>Keyword(s):</b> $keywords<br /> |
|
<b>Notes:</b> $notes<br /> |
|
<b>MIME Type:</b> $mimetag{$mime}<br /> |
|
<b>Language:</b> $language{$lang}<br /> |
|
<b>Creation Date:</b> $creationdate<br /> |
|
<b>Last Revision Date:</b> $lastrevisiondate<br /> |
|
<b>Publisher/Owner:</b> $owner<br /> |
|
<b>Copyright/Distribution:</b> $cprtag{$copyright}<br /> |
|
<b>Repository Location:</b> $hostname<br /> |
|
<b>Abstract:</b> $shortabstract<br /> |
|
</p> |
|
END |
|
return $result; |
|
} |
|
|
|
# -------------------------------------------------------------------- XML/SGML |
|
sub xml_sgml_view { |
|
my ($title,$author,$subject,$url,$keywords,$version, |
|
$notes,$shortabstract,$mime,$lang, |
|
$creationdate,$lastrevisiondate,$owner,$copyright, |
|
$hostname,$httphost)=@_; |
|
my $result=<<END; |
|
<pre> |
|
<LonCapaResource> |
|
<url>$url</url> |
|
<title>$title</title> |
|
<author>$author</author> |
|
<subject>$subject</subject> |
|
<keywords>$keywords</keywords> |
|
<notes>$notes</notes> |
|
<mimeInfo> |
|
<mime>$mime</mime> |
|
<mimetag>$mimetag{$mime}</mimetag> |
|
</mimeInfo> |
|
<languageInfo> |
|
<language>$lang</language> |
|
<languagetag>$language{$lang}</languagetag> |
|
</languageInfo> |
|
<creationdate>$creationdate</creationdate> |
|
<lastrevisiondate>$lastrevisiondate</lastrevisiondate> |
|
<owner>$owner</owner> |
|
<copyrightInfo> |
|
<copyright>$copyright</copyright> |
|
<copyrighttag>$cprtag{$copyright}</copyrighttag> |
|
</copyrightInfo> |
|
<repositoryLocation>$hostname</repositoryLocation> |
|
<shortabstract>$shortabstract</shortabstract> |
|
</LonCapaResource> |
|
</pre> |
|
END |
|
return $result; |
|
} |
|
|
1; |
1; |
__END__ |
__END__ |