--- loncom/interface/lonsearchcat.pm 2001/03/22 13:10:06 1.64 +++ loncom/interface/lonsearchcat.pm 2001/08/16 02:20:01 1.97 @@ -1,9 +1,11 @@ # The LearningOnline Network # Search Catalog # +# YEAR=2001 # 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 +# Scott Harrison: 03/20/2001, 03/21/2001, 03/22/2001, 03/26/2001, 03/27/2001 +# Scott Harrison: 04/02/2001, 08/15/2001 # # Functions # @@ -36,6 +38,21 @@ # 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 +# build_custommetadata_query(field_name, logic_statement) : builds a perl +# regular expression from a logical expression with AND/OR +# keywords +# detailed_citation_view, summary_view, fielded_format_view, xml_sgml_view: +# four different ways to view metadata records. Outputs a HTML-ified string. +# Input arguments are title, author, subject, url, keywords, version, notes, +# short abstract, mime, language, creation date, last revision date, owner, +# copyright, hostname, httphost, and extra custom metadata to show. +# build_date_queries(cmonth1, cday1, cyear1, cmonth2, cday2, cyear2, +# lmonth1, lday1, lyear1, lmonth2, lday2, lyear2) : +# Builds a SQL logic query to check time/date entries. +# output_date_error(server reference, error message) : outputs +# an error message specific to bad date format. +# make_persistent() : makes a set of hidden HTML fields to make +# SQL search interface information to be persistent package Apache::lonsearchcat; @@ -46,12 +63,19 @@ use Apache::File(); use CGI qw(:standard); use Text::Query; +# ---------------------------------------- variables used throughout the module my %language; my $scrout; my %metadatafields; my %cprtag; my %mimetag; my $closebutton; + +# ------ form selection elements that allow for choosing different output views +# Detailed Citation View ---> sub detailed_citationview +# Summary View ---> sub summary_view +# Fielded Format ---> sub fielded_format_view +# XML/SGML ---> sub xml_sgml_view my $basicviewselect=< @@ -69,6 +93,7 @@ my $advancedviewselect=< END +# ----------------------------- Handling routine called via Apache and mod_perl sub handler { my $r = shift; @@ -89,13 +114,14 @@ sub handler { %metadatafields=(); my $hidden=''; - $hidden=< END - - $closebutton=< + $closebutton=< END + } # ------------------------------------------------ First, check out environment $metadatafields{'owner'}=$ENV{'user.name'}.'@'.$ENV{'user.domain'}; @@ -132,6 +158,7 @@ END } <$fh>; } +# ----------------------------------- See if a search invocation should be done if ($ENV{'form.basicsubmit'} eq 'SEARCH') { return &basicsearch($r,\%ENV); } @@ -139,6 +166,7 @@ END return &advancedsearch($r,\%ENV); } +# ----------------------------- Else, begin building search interface to output $scrout=''; # building a part of screen output $scrout.=&searchphrasefield('Limit by title','title', $ENV{'form.title'}); @@ -155,8 +183,8 @@ END $scrout.=&searchphrasefield('Limit by URL','url', $ENV{'form.url'}); - $scrout.=&searchphrasefield('Limit by version','version', - $ENV{'form.version'}); +# $scrout.=&searchphrasefield('Limit by version','version', +# $ENV{'form.version'}); $scrout.=&searchphrasefield('Limit by notes','notes', $ENV{'form.notes'}); @@ -229,9 +257,9 @@ LASTREVISIONDATEEND # ------------------------------------------- Compute customized metadata field $scrout.=< -LIMIT BY OTHER METADATA FIELDS: +LIMIT BY SPECIAL METADATA FIELDS: -For author-specific metadata, enter in an expression in the form of +For resource-specific metadata, enter in an expression in the form of key=value separated by operators such as AND or OR.
Example: grandmother=75 OR grandfather=85
@@ -239,6 +267,17 @@ CUSTOMMETADATA $scrout.=&simpletextfield('custommetadata',$ENV{'form.custommetadata'}); $scrout.=' initial users of this system do not need to worry about this option'; + $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.=' initial users of this system do not need to worry about this option'; + # ---------------------------------------------------------------- Print screen $r->print(< @@ -263,12 +302,12 @@ ENDDOCUMENT $r->print(' '); $r->print(&simplecheckbox('titleonly',$ENV{'form.titleonly'})); $r->print('Title only '); - $r->print(&simplecheckbox('allversions',$ENV{'form.allversions'})); +# $r->print(&simplecheckbox('allversions',$ENV{'form.allversions'})); +# Search historic archives $r->print(<Search historic archives

- - + + $closebutton $basicviewselect

@@ -276,8 +315,8 @@ $basicviewselect

Advanced Search

$scrout

- - + + $closebutton $advancedviewselect

@@ -292,14 +331,15 @@ ENDDOCUMENT sub simpletextfield { my ($name,$value)=@_; - return ''; + return ''; } sub simplecheckbox { my ($name,$value)=@_; my $checked=''; $checked="CHECKED" if $value eq 'on'; - return ''; + return ''; } sub searchphrasefield { @@ -311,7 +351,7 @@ END my $uctitle=uc($title); return "\n

$uctitle:". " $instruction
". - ''; + ''; } sub dateboxes { @@ -464,7 +504,7 @@ sub selectbox { my $selout="\n

$uctitle:". "
".' - -
-END - 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); - } - elsif ($viewselect eq 'Summary View') { - $compiledresult.=&summary_view(@fields,$hostname,$httphost); - } - 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) { - $compiledresult="There were no results that matched your query"; - } - - # make query information persistent to allow for subsequent revision - my $persistent=''; - map { - if (/^form\./ && !/submit/) { - my $name=$_; - my $key=$name; - $name=~s/^form\.//; - $persistent.=< -END - } - } (keys %ENV); + # make query information persistent to allow for subsequent revision + my $persistent=&make_persistent(); + # output beginning of search page $r->print(< @@ -741,6 +731,7 @@ BEGINNING function select_data(title,url) { changeTitle(title); changeURL(url); + self.close(); } function changeTitle(val) { if (opener.inf.document.forms.resinfo.elements.t) { @@ -754,11 +745,13 @@ BEGINNING } SCRIPT - $r->print(<print(<

Search Catalog

+CATALOGBEGIN + $r->print(< @@ -782,13 +775,185 @@ $query

RESULTS } + $r->print('

Search Results

'); + $r->rflush(); + $r->print(< + popwin=open('','popwin','width=400,height=200'); + popwin.document.writeln(''+ + '

Search Results Progress

'+ + '
'+ + '
Server space '+ + '
Status '+ + '
Maximum remaining time '+ + '
'+ + ''); + popwin.document.close(); + +ENDPOP + $r->rflush(); + + my $servernum=(keys %rhash)+0; + $r->print(''); + $r->rflush(); + my $servercount=0; + foreach my $rkey (keys %rhash) { + $servercount++; + $tflag=1; + $compiledresult=''; + my $hostname=$rkey; + $r->print(''); + $r->rflush(); + my $reply=$rhash{$rkey}; + my @results; + + my $replyfile=''; + + if ($reply eq 'con_lost') { + my $percent=sprintf('%3.0f',($servercount/$servernum*100)); + $r->print(''); + } + else { + $reply=~/^([\.\w]+)$/; # must do since 'use strict' checks for tainting + $replyfile=$r->dir_config('lonDaemons').'/tmp/'.$1; + $reply=~/(.*?)\_/; + { + while (1) { + if (-e $replyfile && $tflag) { + $r->print(''); + $r->rflush(); + $tflag=0; + } + last if -e "$replyfile.end"; + last unless $timeremain; + sleep 1; + $timeremain--; + $r->print(''); + $r->rflush(); + } + # QUESTION: how should I handle this error condition.. + # I'm sure there is syntax elsewhere I can use.. + my $fh=Apache::File->new($replyfile) or + ($r->print('ERROR: file cannot be opened') and return OK); + @results=<$fh>; + } + } + my $customshow=''; + my $extrashow=''; + my @customfields; + if ($ENV{'form.customshow'}) { + $customshow=$ENV{'form.customshow'}; + $customshow=~s/[^\w\s]//g; + my @fields=map {"$_:"} + split(/\s+/,$customshow); + @customfields=split(/\s+/,$customshow); + if ($customshow) { + $extrashow="
  • ".join("
  • ",@fields)."
\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; + } + } + 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; + my $shortabstract=$abstract; + $shortabstract=substr($abstract,0,200) if length($abstract)>200; + $fields[7]=$shortabstract; + 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 + $compiledresult.=< +END + $compiledresult.=< + +
+END + 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); + } + + } + + if ($compiledresult) { + $resultflag=1; + } + $r->print(<Search Results $compiledresult +RESULTS + my $percent=sprintf('%3.0f',($servercount/$servernum*100)); + $r->print(''); + } + unless ($resultflag) { + $r->print("\nThere were no results that matched your query\n"); + } + $r->print(''); $r->rflush(); + $r->print(< RESULTS - } } # ------------------------------------------------------------- build_SQL_query @@ -811,6 +976,10 @@ sub build_custommetadata_query { -build => 'Text::Query::BuildAdvancedString'); $q->prepare($logic_statement); my $matchexp=${$q}{'-parse'}{'-build'}{'matchstring'}; + # quick fix to change literal into xml tag-matching + # will eventually have to write a separate builder module + my $oldmatchexp=$matchexp; + $matchexp=~s/(\w+)\\\=([\w\\\+]+)/\\\<$1\\\>\[\^\\\<\]\*$2\[\^\\\<\]\*\\\<\\\/$1\\\>/g; return $matchexp; } @@ -826,6 +995,11 @@ sub recursive_SQL_query_build { if ($key eq 'literal') { $replacement="($dkey like \"\%$value\%\")"; } + elsif ($key eq 'not') { + $value=~s/like/not like/; +# $replacement="($dkey not like $value)"; + $replacement="$value"; + } elsif ($key eq 'and') { $value=~/(.*[\"|\)]) ([|\(|\^].*)/; $replacement="($1 AND $2)"; @@ -848,7 +1022,7 @@ sub detailed_citation_view { my ($title,$author,$subject,$url,$keywords,$version, $notes,$shortabstract,$mime,$lang, $creationdate,$lastrevisiondate,$owner,$copyright, - $hostname,$httphost)=@_; + $hostname,$httphost,$extrashow)=@_; my $result=<$owner, last revised $lastrevisiondate

$title

@@ -861,6 +1035,9 @@ sub detailed_citation_view { MIME Type: $mimetag{$mime}
Language: $language{$lang}
Copyright/Distribution: $cprtag{$copyright}
+

+$extrashow +

$shortabstract

END @@ -872,12 +1049,13 @@ sub summary_view { my ($title,$author,$subject,$url,$keywords,$version, $notes,$shortabstract,$mime,$lang, $creationdate,$lastrevisiondate,$owner,$copyright, - $hostname,$httphost)=@_; + $hostname,$httphost,$extrashow)=@_; my $result=<$author
$title
$owner -- $lastrevisiondate
$cprtag{$copyright}
+$extrashow

END return $result; @@ -888,7 +1066,7 @@ sub fielded_format_view { my ($title,$author,$subject,$url,$keywords,$version, $notes,$shortabstract,$mime,$lang, $creationdate,$lastrevisiondate,$owner,$copyright, - $hostname,$httphost)=@_; + $hostname,$httphost,$extrashow)=@_; my $result=<URL: $url
@@ -905,6 +1083,7 @@ sub fielded_format_view { Copyright/Distribution: $cprtag{$copyright}
Repository Location: $hostname
Abstract: $shortabstract
+$extrashow

END return $result; @@ -915,7 +1094,7 @@ sub xml_sgml_view { my ($title,$author,$subject,$url,$keywords,$version, $notes,$shortabstract,$mime,$lang, $creationdate,$lastrevisiondate,$owner,$copyright, - $hostname,$httphost)=@_; + $hostname,$httphost,$extrashow)=@_; my $result=< <LonCapaResource> @@ -944,6 +1123,7 @@ sub xml_sgml_view { <shortabstract>$shortabstract</shortabstract> </LonCapaResource> +$extrashow END return $result; } @@ -999,17 +1179,7 @@ sub build_date_queries { sub output_date_error { my ($r,$message)=@_; # make query information persistent to allow for subsequent revision - my $persistent=''; - map { - if (/^form\./ && !/submit/) { - my $name=$_; - my $key=$name; - $name=~s/^form\.//; - $persistent.=< -END - } - } (keys %ENV); + my $persistent=&make_persistent(); $r->print(< @@ -1037,7 +1207,20 @@ RESULTS } sub make_persistent { - $ENV{"form.$field"}=~s/\"/\\\"/g; + my $persistent=''; + + map { + if (/^form\./ && !/submit/) { + my $name=$_; + my $key=$name; + $ENV{$key}=~s/\'//g; # do not mess with html field syntax + $name=~s/^form\.//; + $persistent.=< +END + } + } (keys %ENV); + return $persistent; } 1; __END__