Diff for /loncom/interface/lonsearchcat.pm between versions 1.60 and 1.97

version 1.60, 2001/03/21 12:19:53 version 1.97, 2001/08/16 02:20:01
Line 1 Line 1
 # The LearningOnline Network  # The LearningOnline Network
 # Search Catalog  # Search Catalog
 #  #
   # YEAR=2001
 # 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/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  # Functions
 #  #
Line 36 Line 38
 # recursive_SQL_query_build(field name, reverse notation expression) :   # recursive_SQL_query_build(field name, reverse notation expression) : 
 #                 builds a SQL query string from a reverse notation expression  #                 builds a SQL query string from a reverse notation expression
 #                 logical expression with AND/OR keywords  #                 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;  package Apache::lonsearchcat;
   
Line 46  use Apache::File(); Line 63  use Apache::File();
 use CGI qw(:standard);  use CGI qw(:standard);
 use Text::Query;  use Text::Query;
   
   # ---------------------------------------- variables used throughout the module
 my %language;  my %language;
 my $scrout;  my $scrout;
 my %metadatafields;  my %metadatafields;
 my %cprtag;  my %cprtag;
 my %mimetag;  my %mimetag;
 my $closebutton;  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=<<END;  my $basicviewselect=<<END;
 <select name='basicviewselect'>  <select name='basicviewselect'>
 <option value='Detailed Citation View'>Detailed Citation View</option>  <option value='Detailed Citation View'>Detailed Citation View</option>
Line 69  my $advancedviewselect=<<END; Line 93  my $advancedviewselect=<<END;
 </select>  </select>
 END  END
   
   # ----------------------------- Handling routine called via Apache and mod_perl
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
   
Line 89  sub handler { Line 114  sub handler {
     %metadatafields=();      %metadatafields=();
   
     my $hidden='';      my $hidden='';
     $hidden=<<END if $ENV{'form.catalogmode'} eq 'interactive';      if ($ENV{'form.catalogmode'} eq 'interactive') {
    $hidden=<<END;
 <input type='hidden' name='catalogmode' value='interactive'>  <input type='hidden' name='catalogmode' value='interactive'>
 END  END
           $closebutton=<<END;
     $closebutton=<<END if $ENV{'form.catalogmode'} eq 'interactive';  <input type="button" name="close" value='CLOSE' onClick="self.close()">
 <input type="button" name="close" value="CLOSE" onClick="self.close()">  
 END  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 132  END Line 158  END
  } <$fh>;   } <$fh>;
     }      }
   
   # ----------------------------------- See if a search invocation should be done
     if ($ENV{'form.basicsubmit'} eq 'SEARCH') {      if ($ENV{'form.basicsubmit'} eq 'SEARCH') {
  return &basicsearch($r,\%ENV);   return &basicsearch($r,\%ENV);
     }      }
Line 139  END Line 166  END
  return &advancedsearch($r,\%ENV);   return &advancedsearch($r,\%ENV);
     }      }
   
   # ----------------------------- Else, begin building search interface to output
     $scrout=''; # building a part of screen output      $scrout=''; # building a part of screen output
     $scrout.=&searchphrasefield('Limit by title','title',      $scrout.=&searchphrasefield('Limit by title','title',
  $ENV{'form.title'});   $ENV{'form.title'});
Line 155  END Line 183  END
     $scrout.=&searchphrasefield('Limit by URL','url',      $scrout.=&searchphrasefield('Limit by URL','url',
  $ENV{'form.url'});   $ENV{'form.url'});
   
     $scrout.=&searchphrasefield('Limit by version','version',  #    $scrout.=&searchphrasefield('Limit by version','version',
  $ENV{'form.version'});  # $ENV{'form.version'});
   
     $scrout.=&searchphrasefield('Limit by notes','notes',      $scrout.=&searchphrasefield('Limit by notes','notes',
  $ENV{'form.notes'});   $ENV{'form.notes'});
Line 229  LASTREVISIONDATEEND Line 257  LASTREVISIONDATEEND
 # ------------------------------------------- Compute customized metadata field  # ------------------------------------------- Compute customized metadata field
     $scrout.=<<CUSTOMMETADATA;      $scrout.=<<CUSTOMMETADATA;
 <p>  <p>
 <font color="#800000" face="helvetica"><b>LIMIT BY OTHER METADATA FIELDS:</b>  <font color="#800000" face="helvetica"><b>LIMIT BY SPECIAL METADATA FIELDS:</b>
 </font>  </font>
 For author-specific metadata, enter in an expression in the form of   For resource-specific metadata, enter in an expression in the form of 
 <i>key</i>=<i>value</i> separated by operators such as AND or OR.<br>  <i>key</i>=<i>value</i> separated by operators such as AND or OR.<br>
 <b>Example:</b> grandmother=75 OR grandfather=85  <b>Example:</b> grandmother=75 OR grandfather=85
 <br>  <br>
Line 239  CUSTOMMETADATA Line 267  CUSTOMMETADATA
 $scrout.=&simpletextfield('custommetadata',$ENV{'form.custommetadata'});  $scrout.=&simpletextfield('custommetadata',$ENV{'form.custommetadata'});
 $scrout.=' <i>initial users of this system do not need to worry about this option</i>';  $scrout.=' <i>initial users of this system do not need to worry about this option</i>';
   
       $scrout.=<<CUSTOMSHOW;
   <p>
   <font color="#800000" face="helvetica"><b>SHOW SPECIAL METADATA FIELDS:</b>
   </font>
   Enter in a space-separated list of special metadata fields to show
   in a fielded listing for each record result.
   <br>
   CUSTOMSHOW
   $scrout.=&simpletextfield('customshow',$ENV{'form.customshow'});
   $scrout.=' <i>initial users of this system do not need to worry about this option</i>';
   
 # ---------------------------------------------------------------- Print screen  # ---------------------------------------------------------------- Print screen
     $r->print(<<ENDDOCUMENT);      $r->print(<<ENDDOCUMENT);
 <html>  <html>
Line 263  ENDDOCUMENT Line 302  ENDDOCUMENT
     $r->print(' ');      $r->print(' ');
     $r->print(&simplecheckbox('titleonly',$ENV{'form.titleonly'}));      $r->print(&simplecheckbox('titleonly',$ENV{'form.titleonly'}));
     $r->print('<font color="#800000">Title only</font> ');      $r->print('<font color="#800000">Title only</font> ');
     $r->print(&simplecheckbox('allversions',$ENV{'form.allversions'}));  #    $r->print(&simplecheckbox('allversions',$ENV{'form.allversions'}));
   # <font color="#800000">Search historic archives</font>
     $r->print(<<ENDDOCUMENT);      $r->print(<<ENDDOCUMENT);
 <font color="#800000">Search historic archives</font>  
 <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' />
 $closebutton  $closebutton
 $basicviewselect  $basicviewselect
 </p>  </p>
Line 276  $basicviewselect Line 315  $basicviewselect
 <h3>Advanced Search</h3>  <h3>Advanced Search</h3>
 $scrout  $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' />
 $closebutton  $closebutton
 $advancedviewselect  $advancedviewselect
 </p>  </p>
Line 292  ENDDOCUMENT Line 331  ENDDOCUMENT
   
 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.'\' />';
 }  }
   
 sub simplecheckbox {  sub simplecheckbox {
     my ($name,$value)=@_;      my ($name,$value)=@_;
     my $checked='';      my $checked='';
     $checked="CHECKED" if $value eq 'on';      $checked="CHECKED" if $value eq 'on';
     return '<input type=checkbox name="'.$name.'" '. $checked . '>';      return '<input type=checkbox name=\''.$name.'\' '. $checked . '>';
 }  }
   
 sub searchphrasefield {  sub searchphrasefield {
Line 311  END Line 351  END
     my $uctitle=uc($title);      my $uctitle=uc($title);
     return "\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:</b>".      return "\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:</b>".
    "</FONT> $instruction<br>".     "</FONT> $instruction<br>".
            '<input type=text name="'.$name.'" size=80 value="'.$value.'">';             '<input type=text name="'.$name.'" size=80 value=\''.$value.'\'>';
 }  }
   
 sub dateboxes {  sub dateboxes {
Line 464  sub selectbox { Line 504  sub selectbox {
     my $selout="\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".      my $selout="\n<p><font color=\"#800000\" face=\"helvetica\"><b>$uctitle:".
  "</b></font><br>".'<select name="'.$name.'">';   "</b></font><br>".'<select name="'.$name.'">';
     map {      map {
         $selout.='<option value="'.$_.'"';          $selout.='<option value=\''.$_.'\'';
         if ($_ eq $value) { $selout.=' selected'; }          if ($_ eq $value) { $selout.=' selected'; }
         $selout.='>'.$options{$_}.'</option>';          $selout.='>'.$options{$_}.'</option>';
     } sort keys %options;      } sort keys %options;
Line 477  sub advancedsearch { Line 517  sub advancedsearch {
     my %ENV=%{$envhash};      my %ENV=%{$envhash};
   
     my $fillflag=0;      my $fillflag=0;
       # Clean up fields for safety
       for my $field ('title','author','subject','keywords','url','version',
      'creationdatestart_month','creationdatestart_day',
      'creationdatestart_year','creationdateend_month',
      'creationdateend_day','creationdateend_year',
      'lastrevisiondatestart_month','lastrevisiondatestart_day',
      'lastrevisiondatestart_year','lastrevisiondateend_month',
      'lastrevisiondateend_day','lastrevisiondateend_year',
      'notes','abstract','mime','language','owner',
      'custommetadata','customshow') {
    $ENV{"form.$field"}=~s/[^\w\s\(\)\=\-\"\']//g;
       }
   
       # Check to see if enough information was filled in
     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') {
Line 484  sub advancedsearch { Line 538  sub advancedsearch {
     $fillflag++;      $fillflag++;
  }   }
     }      }
   
     unless ($fillflag) {      unless ($fillflag) {
  &output_blank_field_error($r);   &output_blank_field_error($r);
  return OK;   return OK;
     }      }
   
   
       # Turn the form input into a SQL-based query
     my $query='';      my $query='';
   
     my @queries;      my @queries;
     # Go through logical expression AND/OR/NOT phrase fields.      # Evaluate logical expression AND/OR/NOT phrase fields.
   
     foreach my $field ('title','author','subject','notes','abstract','url',      foreach my $field ('title','author','subject','notes','abstract','url',
        'keywords','version','owner') {         'keywords','version','owner') {
  if ($ENV{'form.'.$field}) {   if ($ENV{'form.'.$field}) {
     push @queries,&build_SQL_query($field,$ENV{'form.'.$field});      push @queries,&build_SQL_query($field,$ENV{'form.'.$field});
  }   }
     }      }
       # Evaluate option lists
     if ($ENV{'form.language'} and $ENV{'form.language'} ne 'any') {      if ($ENV{'form.language'} and $ENV{'form.language'} ne 'any') {
  push @queries,"(language like \"\%$ENV{'form.language'}\%\")";   push @queries,"(language like \"$ENV{'form.language'}\")";
     }      }
     if ($ENV{'form.mime'} and $ENV{'form.mime'} ne 'any') {      if ($ENV{'form.mime'} and $ENV{'form.mime'} ne 'any') {
  push @queries,"(mime like \"\%$ENV{'form.mime'}\%\")";   push @queries,"(mime like \"$ENV{'form.mime'}\")";
     }      }
     if ($ENV{'form.copyright'} and $ENV{'form.copyright'} ne 'any') {      if ($ENV{'form.copyright'} and $ENV{'form.copyright'} ne 'any') {
  push @queries,"(copyright like \"\%$ENV{'form.copyright'}\%\")";   push @queries,"(copyright like \"$ENV{'form.copyright'}\")";
     }      }
       # Evaluate date windows
     my $datequery=&build_date_queries(      my $datequery=&build_date_queries(
  $ENV{'form.creationdatestart_month'},   $ENV{'form.creationdatestart_month'},
  $ENV{'form.creationdatestart_day'},   $ENV{'form.creationdatestart_day'},
Line 524  sub advancedsearch { Line 580  sub advancedsearch {
  $ENV{'form.lastrevisiondateend_day'},   $ENV{'form.lastrevisiondateend_day'},
  $ENV{'form.lastrevisiondateend_year'},   $ENV{'form.lastrevisiondateend_year'},
  );   );
     if ($datequery!~/^Incorrect/) {      # Test to see if date windows are legitimate
  push @queries,$datequery;      if ($datequery=~/^Incorrect/) {
     }  
     else {  
  &output_date_error($r,$datequery);   &output_date_error($r,$datequery);
    return OK;
       }
       elsif ($datequery) {
    push @queries,$datequery;
     }      }
   
       # Process form information for custom metadata querying
       my $customquery='';
       if ($ENV{'form.custommetadata'}) {
    $customquery=&build_custommetadata_query('custommetadata',
         $ENV{'form.custommetadata'});
       }
       my $customshow='';
       if ($ENV{'form.customshow'}) {
    $customshow=$ENV{'form.customshow'};
    $customshow=~s/[^\w\s]//g;
    my @fields=split(/\s+/,$customshow);
    $customshow=join(" ",@fields);
       }
       # 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).
     if (@queries) {      if (@queries) {
  $query=join(" AND ",@queries);   $query=join(" AND ",@queries);
  $query="select * from metadata where $query";   $query="select * from metadata where $query";
  my $reply=&Apache::lonnet::metadata_query($query);   my $reply; # reply hash reference
  &output_results('Advanced',$r,$envhash,$query,$reply);   unless ($customquery or $customshow) {
       $reply=&Apache::lonnet::metadata_query($query);
    }
    else {
       $reply=&Apache::lonnet::metadata_query($query,
      $customquery,$customshow);
    }
    &output_results('Advanced',$r,$envhash,$customquery,$reply);
     }      }
     else {      elsif ($customquery) {
  &output_results('Advanced',$r,$envhash,$query);   my $reply; # reply hash reference
    $reply=&Apache::lonnet::metadata_query('',
          $customquery,$customshow);
    &output_results('Advanced',$r,$envhash,$customquery,$reply);
     }      }
     return OK;      # should not get to this point
       return 'Error.  Should not have gone to this point.';
 }  }
   
 # ---------------------------------------------------- see if a field is filled  # ---------------------------------------------------- see if a field is filled
 sub filled {  sub filled {
     my ($field)=@_;      my ($field)=@_;
     if ($field=~/\S/) {      if ($field=~/\S/ && $field ne 'any') {
  return 1;   return 1;
     }      }
     else {      else {
Line 558  sub basicsearch { Line 644  sub basicsearch {
     my ($r,$envhash)=@_;      my ($r,$envhash)=@_;
     my %ENV=%{$envhash};      my %ENV=%{$envhash};
   
       # Clean up fields for safety
       for my $field ('basicexp') {
    $ENV{"form.$field"}=~s/[^\w\s\(\)\-]//g;
       }
   
       # 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);
  return OK;   return OK;
     }      }
   
       # Build SQL query string based on form page
     my $query='';      my $query='';
     my $concatarg=join(',"    ",',      my $concatarg=join(',"    ",',
        ('title', 'author', 'subject', 'notes', 'abstract'));         ('title', 'author', 'subject', 'notes', 'abstract'));
       $concatarg='title' if $ENV{'form.titleonly'};
   
       $query=&build_SQL_query('concat('.$concatarg.')',$ENV{'form.'.'basicexp'});
   
   
     $query="select * from metadata where concat($concatarg) like '\%$ENV{'form.basicexp'}\%'";      # Get reply (either a hash reference to filehandles or bad connection)
     my $reply=&Apache::lonnet::metadata_query($query);      my $reply=&Apache::lonnet::metadata_query('select * from metadata where '.$query);
   
       # Output search results
     &output_results('Basic',$r,$envhash,$query,$reply);      &output_results('Basic',$r,$envhash,$query,$reply);
   
     return OK;      return OK;
 }  }
   
Line 577  sub basicsearch { Line 677  sub basicsearch {
 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
     my $persistent='';      my $persistent=&make_persistent();
     map {  
  if (/^form\./ && !/submit/) {  
     my $name=$_;  
     my $key=$name;  
     $name=~s/^form\.//;  
     $persistent.=<<END;  
 <INPUT TYPE='hidden' NAME='$name' VALUE='$ENV{$key}'>  
 END  
         }  
     } (keys %ENV);  
   
     $r->print(<<BEGINNING);      $r->print(<<BEGINNING);
 <html>  <html>
Line 619  RESULTS Line 709  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 ($mode,$r,$envhash,$query,@replylist)=@_;      my ($mode,$r,$envhash,$query,$replyref)=@_;
     my %ENV=%{$envhash};      my %ENV=%{$envhash};
       my %rhash=%{$replyref};
     my $compiledresult='';      my $compiledresult='';
       my $timeremain=30;
       my $resultflag=0;
       my $tflag=1;
   
     foreach my $reply (@replylist) {      # make query information persistent to allow for subsequent revision
       my $persistent=&make_persistent();
  my @results;  
   
  my $replyfile='';  
  $reply=~/^([\.\w]+)$/; # must do since 'use strict' checks for tainting  
  $replyfile=$r->dir_config('lonDaemons').'/tmp/'.$1;  
  $reply=~/(.*?)\_/;  
  my $hostname=$1;  
  sleep 3; # temporary fix, need to check for completion and status  
  {  
     while (1) {  
  last if -e $replyfile;  
  sleep 1;  
     }  
     # 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('file cannot be opened') and return OK);  
     @results=<$fh>;  
  }  
   
  foreach my $result (@results) {  
     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;  
     $compiledresult.=<<END;  
 <p>  
 END  
             $compiledresult.=<<END if $ENV{'form.catalogmode'} eq 'interactive';  
 <font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT"  
 onClick="javascript:select_data('$title','$url')">  
 </font>  
 <br>  
 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;  
 <INPUT TYPE='hidden' NAME='$name' VALUE='$ENV{$key}'>  
 END  
             }  
  } (keys %ENV);  
   
       # output beginning of search page
  $r->print(<<BEGINNING);   $r->print(<<BEGINNING);
 <html>  <html>
 <head>  <head>
Line 718  BEGINNING Line 731  BEGINNING
     function select_data(title,url) {      function select_data(title,url) {
  changeTitle(title);   changeTitle(title);
  changeURL(url);   changeURL(url);
    self.close();
     }      }
     function changeTitle(val) {      function changeTitle(val) {
  if (opener.inf.document.forms.resinfo.elements.t) {   if (opener.inf.document.forms.resinfo.elements.t) {
Line 731  BEGINNING Line 745  BEGINNING
     }      }
 </script>  </script>
 SCRIPT  SCRIPT
         $r->print(<<RESULTS);      $r->print(<<CATALOGBEGIN);
 </head>  </head>
 <body bgcolor="#ffffff">  <body bgcolor="#ffffff">
 <img align=right src=/adm/lonIcons/lonlogos.gif>  <img align=right src=/adm/lonIcons/lonlogos.gif>
 <h1>Search Catalog</h1>  <h1>Search Catalog</h1>
   CATALOGBEGIN
           $r->print(<<RESULTS);
 <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();'>
Line 759  $query Line 775  $query
 </p>  </p>
 RESULTS  RESULTS
     }      }
       $r->print('<h3>Search Results</h3>');
       $r->rflush();
       $r->print(<<ENDPOP);
   <script>
       popwin=open('','popwin','width=400,height=200');
       popwin.document.writeln('<html><body bgcolor="#FFFFFF">'+
         '<h3>Search Results Progress</h3>'+
         '<form name=popremain>'+
         '<br />Server space <input type=text size=25 name=space value="">'+
         '<br />Status <input type=text size=25 name=status value="">'+
         '<br />Maximum remaining time <input type=text size=25 name=timeout value="30">'+
         '</form>'+
         '</body></html>');
       popwin.document.close();
   </script>
   ENDPOP
       $r->rflush();
   
       my $servernum=(keys %rhash)+0;
       $r->print('<script>popwin.document.popremain.space.value="'.
         $servernum.', 0%, count=0/'.$servernum.'";</script>');
       $r->rflush(); 
       my $servercount=0;
       foreach my $rkey (keys %rhash) {
    $servercount++;
    $tflag=1;
    $compiledresult='';
    my $hostname=$rkey;
    $r->print('<script>popwin.document.popremain.status.value="'.
     $rkey.', trying contact";</script>');
    $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('<script>popwin.document.popremain.space.value="'.
         $servernum.', '.$percent.'%, count='.$servercount.
         '/'.$servernum.'";</script>');
    }
    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('<script>popwin.document.popremain.status.'.
     'value="'.$rkey.', transmitting";</script>');
    $r->rflush();
    $tflag=0;
        }
       last if -e "$replyfile.end";
       last unless $timeremain;
       sleep 1;
       $timeremain--;
       $r->print('<script>popwin.document.popremain.timeout.value="'.
         $timeremain.'";</script>');
       $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 {"<font color=\"#008000\">$_:</font><!-- $_ -->"} 
       split(/\s+/,$customshow);
       @customfields=split(/\s+/,$customshow);
       if ($customshow) {
    $extrashow="<ul><li>".join("</li><li>",@fields)."</li></ul>\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 if $compiledresult;
   <hr align='left' width='200' noshade />
   END
               $compiledresult.=<<END;
   <p>
   END
               $compiledresult.=<<END if $ENV{'form.catalogmode'} eq 'interactive';
   <font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT"
   onClick="javascript:select_data('$title','$url')">
   </font>
   <br>
   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(<<RESULTS);   $r->print(<<RESULTS);
 <h3>Search Results</h3>  
 $compiledresult  $compiledresult
   RESULTS
           my $percent=sprintf('%3.0f',($servercount/$servernum*100));
    $r->print('<script>popwin.document.popremain.space.value="'.
             $servernum.', '.$percent.'%, count='.$servercount.
     '/'.$servernum.'";</script>');
       }
       unless ($resultflag) {
           $r->print("\nThere were no results that matched your query\n");
       }
       $r->print('<script>popwin.close()</script>'); $r->rflush(); 
       $r->print(<<RESULTS);
 </body>  </body>
 </html>  </html>
 RESULTS  RESULTS
     }  
 }  }
   
 # ------------------------------------------------------------- build_SQL_query  # ------------------------------------------------------------- build_SQL_query
Line 780  sub build_SQL_query { Line 968  sub build_SQL_query {
     return $sql_query;      return $sql_query;
 }  }
   
   # ------------------------------------------------- build custom metadata query
   sub build_custommetadata_query {
       my ($field_name,$logic_statement)=@_;
       my $q=new Text::Query('abc',
     -parse => 'Text::Query::ParseAdvanced',
     -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;
   }
   
 # - Recursively parse a reverse notation expression into a SQL query expression  # - Recursively parse a reverse notation expression into a SQL query expression
 sub recursive_SQL_query_build {  sub recursive_SQL_query_build {
     my ($dkey,$pattern)=@_;      my ($dkey,$pattern)=@_;
Line 792  sub recursive_SQL_query_build { Line 995  sub recursive_SQL_query_build {
  if ($key eq 'literal') {   if ($key eq 'literal') {
     $replacement="($dkey like \"\%$value\%\")";      $replacement="($dkey like \"\%$value\%\")";
  }   }
    elsif ($key eq 'not') {
       $value=~s/like/not like/;
   #    $replacement="($dkey not like $value)";
       $replacement="$value";
    }
  elsif ($key eq 'and') {   elsif ($key eq 'and') {
     $value=~/(.*[\"|\)]) ([|\(|\^].*)/;      $value=~/(.*[\"|\)]) ([|\(|\^].*)/;
     $replacement="($1 AND $2)";      $replacement="($1 AND $2)";
Line 814  sub detailed_citation_view { Line 1022  sub detailed_citation_view {
     my ($title,$author,$subject,$url,$keywords,$version,      my ($title,$author,$subject,$url,$keywords,$version,
  $notes,$shortabstract,$mime,$lang,   $notes,$shortabstract,$mime,$lang,
  $creationdate,$lastrevisiondate,$owner,$copyright,   $creationdate,$lastrevisiondate,$owner,$copyright,
  $hostname,$httphost)=@_;   $hostname,$httphost,$extrashow)=@_;
     my $result=<<END;      my $result=<<END;
 <i>$owner</i>, last revised $lastrevisiondate  <i>$owner</i>, last revised $lastrevisiondate
 <h3><A HREF="http://$httphost$url" TARGET='search_preview'>$title</A></h3>  <h3><A HREF="http://$httphost$url" TARGET='search_preview'>$title</A></h3>
Line 827  sub detailed_citation_view { Line 1035  sub detailed_citation_view {
 <b>MIME Type:</b> $mimetag{$mime}<br>  <b>MIME Type:</b> $mimetag{$mime}<br>
 <b>Language:</b> $language{$lang}<br>  <b>Language:</b> $language{$lang}<br>
 <b>Copyright/Distribution:</b> $cprtag{$copyright}<br>  <b>Copyright/Distribution:</b> $cprtag{$copyright}<br>
   </p>
   $extrashow
   <p>
 $shortabstract  $shortabstract
 </p>  </p>
 END  END
Line 838  sub summary_view { Line 1049  sub summary_view {
     my ($title,$author,$subject,$url,$keywords,$version,      my ($title,$author,$subject,$url,$keywords,$version,
  $notes,$shortabstract,$mime,$lang,   $notes,$shortabstract,$mime,$lang,
  $creationdate,$lastrevisiondate,$owner,$copyright,   $creationdate,$lastrevisiondate,$owner,$copyright,
  $hostname,$httphost)=@_;   $hostname,$httphost,$extrashow)=@_;
     my $result=<<END;      my $result=<<END;
 <a href="http://$httphost$url" TARGET='search_preview'>$author</a><br />  <a href="http://$httphost$url" TARGET='search_preview'>$author</a><br />
 $title<br />  $title<br />
 $owner -- $lastrevisiondate<br />  $owner -- $lastrevisiondate<br />
 $cprtag{$copyright}<br />  $cprtag{$copyright}<br />
   $extrashow
 </p>  </p>
 END  END
     return $result;      return $result;
Line 854  sub fielded_format_view { Line 1066  sub fielded_format_view {
     my ($title,$author,$subject,$url,$keywords,$version,      my ($title,$author,$subject,$url,$keywords,$version,
  $notes,$shortabstract,$mime,$lang,   $notes,$shortabstract,$mime,$lang,
  $creationdate,$lastrevisiondate,$owner,$copyright,   $creationdate,$lastrevisiondate,$owner,$copyright,
  $hostname,$httphost)=@_;   $hostname,$httphost,$extrashow)=@_;
     my $result=<<END;      my $result=<<END;
 <b>URL: </b> <A HREF="http://$httphost$url" TARGET='search_preview'>$url</A>  <b>URL: </b> <A HREF="http://$httphost$url" TARGET='search_preview'>$url</A>
 <br />  <br />
Line 871  sub fielded_format_view { Line 1083  sub fielded_format_view {
 <b>Copyright/Distribution:</b> $cprtag{$copyright}<br />  <b>Copyright/Distribution:</b> $cprtag{$copyright}<br />
 <b>Repository Location:</b> $hostname<br />  <b>Repository Location:</b> $hostname<br />
 <b>Abstract:</b> $shortabstract<br />  <b>Abstract:</b> $shortabstract<br />
   $extrashow
 </p>  </p>
 END  END
     return $result;      return $result;
Line 881  sub xml_sgml_view { Line 1094  sub xml_sgml_view {
     my ($title,$author,$subject,$url,$keywords,$version,      my ($title,$author,$subject,$url,$keywords,$version,
  $notes,$shortabstract,$mime,$lang,   $notes,$shortabstract,$mime,$lang,
  $creationdate,$lastrevisiondate,$owner,$copyright,   $creationdate,$lastrevisiondate,$owner,$copyright,
  $hostname,$httphost)=@_;   $hostname,$httphost,$extrashow)=@_;
     my $result=<<END;      my $result=<<END;
 <pre>  <pre>
 &lt;LonCapaResource&gt;  &lt;LonCapaResource&gt;
Line 910  sub xml_sgml_view { Line 1123  sub xml_sgml_view {
 &lt;shortabstract&gt;$shortabstract&lt;/shortabstract&gt;  &lt;shortabstract&gt;$shortabstract&lt;/shortabstract&gt;
 &lt;/LonCapaResource&gt;  &lt;/LonCapaResource&gt;
 </pre>  </pre>
   $extrashow
 END  END
     return $result;      return $result;
 }  }
Line 917  END Line 1131  END
 sub build_date_queries {  sub build_date_queries {
     my ($cmonth1,$cday1,$cyear1,$cmonth2,$cday2,$cyear2,      my ($cmonth1,$cday1,$cyear1,$cmonth2,$cday2,$cyear2,
  $lmonth1,$lday1,$lyear1,$lmonth2,$lday2,$lyear2)=@_;   $lmonth1,$lday1,$lyear1,$lmonth2,$lday2,$lyear2)=@_;
       my @queries;
     return "Incorrect for some reason.";      if ($cmonth1 or $cday1 or $cyear1 or $cmonth2 or $cday2 or $cyear2) {
    unless ($cmonth1 and $cday1 and $cyear1 and
    $cmonth2 and $cday2 and $cyear2) {
       return "Incorrect entry for the creation date.  You must specify ".
      "a starting month, day, and year and an ending month, ".
      "day, and year.";
    }
    my $cnumeric1=sprintf("%d%2d%2d",$cyear1,$cmonth1,$cday1);
    $cnumeric1+=0;
    my $cnumeric2=sprintf("%d%2d%2d",$cyear2,$cmonth2,$cday2);
    $cnumeric2+=0;
    if ($cnumeric1>$cnumeric2) {
       return "Incorrect entry for the creation date.  The starting ".
      "date must occur before the ending date.";
    }
    my $cquery="(creationdate BETWEEN '$cyear1-$cmonth1-$cday1' AND '".
              "$cyear2-$cmonth2-$cday2 23:59:59')";
    push @queries,$cquery;
       }
       if ($lmonth1 or $lday1 or $lyear1 or $lmonth2 or $lday2 or $lyear2) {
    unless ($lmonth1 and $lday1 and $lyear1 and
    $lmonth2 and $lday2 and $lyear2) {
       return "Incorrect entry for the last revision date.  You must ".
      "specify a starting month, day, and year and an ending ".
      "month, day, and year.";
    }
    my $lnumeric1=sprintf("%d%2d%2d",$lyear1,$lmonth1,$lday1);
    $lnumeric1+=0;
    my $lnumeric2=sprintf("%d%2d%2d",$lyear2,$lmonth2,$lday2);
    $lnumeric2+=0;
    if ($lnumeric1>$lnumeric2) {
       return "Incorrect entry for the last revision date.  The ".
      "starting date must occur before the ending date.";
    }
    my $lquery="(lastrevisiondate BETWEEN '$lyear1-$lmonth1-$lday1' AND '".
              "$lyear2-$lmonth2-$lday2 23:59:59')";
    push @queries,$lquery;
       }
       if (@queries) {
    return join(" AND ",@queries);
       }
       return '';
 }  }
   
 sub output_date_error {  sub output_date_error {
     my ($r,$message)=@_;      my ($r,$message)=@_;
     # make query information persistent to allow for subsequent revision      # make query information persistent to allow for subsequent revision
     my $persistent='';      my $persistent=&make_persistent();
     map {  
  if (/^form\./ && !/submit/) {  
     my $name=$_;  
     my $key=$name;  
     $name=~s/^form\.//;  
     $persistent.=<<END;  
 <INPUT TYPE='hidden' NAME='$name' VALUE='$ENV{$key}'>  
 END  
         }  
     } (keys %ENV);  
   
     $r->print(<<BEGINNING);      $r->print(<<BEGINNING);
 <html>  <html>
Line 961  $message Line 1206  $message
 RESULTS  RESULTS
 }  }
   
   sub make_persistent {
       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;
   <input type='hidden' name='$name' value='$ENV{$key}' />
   END
           }
       } (keys %ENV);
       return $persistent;
   }
 1;  1;
 __END__  __END__

Removed from v.1.60  
changed lines
  Added in v.1.97


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>