[LON-CAPA-cvs] cvs: loncom /interface lonsearchcat.pm

matthew lon-capa-cvs@mail.lon-capa.org
Thu, 01 Aug 2002 14:11:57 -0000


This is a MIME encoded message

--matthew1028211117
Content-Type: text/plain

matthew		Thu Aug  1 10:11:57 2002 EDT

  Modified files:              
    /loncom/interface	lonsearchcat.pm 
  Log:
  Many changes to error reporting and better cleanups on errors/aborted 
  connections.
  Groupsearch and interactive imports (such as from editing a randomlabel problem)
  are now handled properly (at least on mozilla 1.0 linux, will test on 
  'alternative' operating systems soon).  
  Added new results view, &compact_view, which is the default for groupsearch
  and interactive imports.  
  Removed &write_status.
  Changed status reporting system in run_search to output general status, 
  number of hits, and seconds remaining in search instead of 'servers contacted',
  'servers read from' and number of hits.
  Change parameters to *_view functions.  Now accept 'prefix' html.
  Other minor changes.
  
  
--matthew1028211117
Content-Type: text/plain
Content-Disposition: attachment; filename="matthew-20020801101157.txt"

Index: loncom/interface/lonsearchcat.pm
diff -u loncom/interface/lonsearchcat.pm:1.149 loncom/interface/lonsearchcat.pm:1.150
--- loncom/interface/lonsearchcat.pm:1.149	Tue Jul 30 16:26:05 2002
+++ loncom/interface/lonsearchcat.pm	Thu Aug  1 10:11:57 2002
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Search Catalog
 #
-# $Id: lonsearchcat.pm,v 1.149 2002/07/30 20:26:05 matthew Exp $
+# $Id: lonsearchcat.pm,v 1.150 2002/08/01 14:11:57 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -25,14 +25,6 @@
 #
 # 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
-#
 ###############################################################################
 ###############################################################################
 
@@ -140,7 +132,8 @@
 my %Views = ("Detailed Citation View" => \&detailed_citation_view,
              "Summary View"           => \&summary_view,
              "Fielded Format"         => \&fielded_format_view,
-             "XML/SGML"               => \&xml_sgml_view );
+             "XML/SGML"               => \&xml_sgml_view,
+             "Compact View"           => \&compact_view);
 my %persistent_db;
 my $hidden_fields;
 ######################################################################
@@ -214,13 +207,28 @@
                 '_'.$ENV{'form.persistent_db_id'}.'_persistent_search.db';
     ##
     if (! &get_persistent_form_data($r,$persistent_db_file)) {
-        &write_status($r,"Unable to get persistent data");
+        if ($ENV{'form.phase'} =~ /(run_search|results)/) {
+            &Apache::lonnet::logthis("lonsearchcat:Unable to recover data ".
+                                     "from $persistent_db_file");
+            $r->print(<<END);
+<html>
+<head><title>LON-CAPA Search Error</title></head>
+<body>
+We were unable to retrieve data describing your search.  This is a serious
+error and has been logged.  Please alert your LON-CAPA administrator.
+</body>
+</html>
+END
+            return OK;
+        }
     }
     ##
     ## Clear out old values from groupsearch database
     ##
     untie %groupsearch_db if (tied(%groupsearch_db));
-    if ($ENV{'form.launch'} eq '1') {
+    if ($ENV{'form.launch'} eq '1' && 
+        ($ENV{'form.catalogmode'} eq 'groupsearch') && 
+        ($ENV{'form.phase'} eq 'results')) {
 	if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) {
 	    &start_fresh_session();
 	    untie %groupsearch_db;
@@ -231,18 +239,45 @@
 	}
     }
     ##
-    ## Configure dynamic components of interface
+    ## Configure hidden fields
     ##
     $hidden_fields = '<input type="hidden" name="persistent_db_id" value="'.
-        $ENV{'form.persistent_db_id'}.'" />';
+        $ENV{'form.persistent_db_id'}.'" />'."\n";
+    if (exists($ENV{'form.catalogmode'})) {
+        $hidden_fields .= '<input type="hidden" name="catalogmode" value="'.
+                $ENV{'form.catalogmode'}.'" />'."\n";
+    }
+    if (exists($ENV{'form.form'})) {
+        $hidden_fields .= '<input type="hidden" name="form" value="'.
+                $ENV{'form.form'}.'" />'."\n";
+    }
+    if (exists($ENV{'form.element'})) {
+        $hidden_fields .= '<input type="hidden" name="element" value="'.
+                $ENV{'form.element'}.'" />'."\n";
+    }
+    if (exists($ENV{'form.mode'})) {
+        $hidden_fields .= '<input type="hidden" name="mode" value="'.
+                $ENV{'form.mode'}.'" />'."\n";
+    }
+    ##
+    ## Configure dynamic components of interface
     ##
     if ($ENV{'form.catalogmode'} eq 'interactive') {
-        $closebutton="<input type='button' name='close' value='CLOSE' ".
-	    "onClick='self.close()'>"."\n";
+        $closebutton="<input type='button' name='close' value='CLOSE' ";
+        if ($ENV{'form.phase'} =~ /(results|run_search)/) {
+	    $closebutton .="onClick='parent.close()'";
+        } else {
+            $closebutton .="onClick='self.close()'";
+        }
+        $closebutton .=">\n";
     } elsif ($ENV{'form.catalogmode'} eq 'groupsearch') {
-        $closebutton=<<END;
-<input type='button' name='close' value='CLOSE' onClick='self.close()'>
-END
+        $closebutton="<input type='button' name='close' value='CLOSE' ";
+        if ($ENV{'form.phase'} =~ /(results|run_search)/) {
+	    $closebutton .="onClick='parent.close()'";
+        } else {
+            $closebutton .="onClick='self.close()'";
+        }
+        $closebutton .= ">";
         $importbutton=<<END;
 <input type='button' name='import' value='IMPORT'
 onClick='javascript:select_group()'>
@@ -255,7 +290,12 @@
     ## Sanity checks on form elements
     ##
     if (!defined($ENV{'form.viewselect'})) {
-        $ENV{'form.viewselect'} ="Detailed Citation View";
+        if (($ENV{'form.catalogmode'} eq 'groupsearch') ||
+            ($ENV{'form.catalogmode'} eq 'interactive')) {
+            $ENV{'form.viewselect'} ="Compact View";
+        } else {
+            $ENV{'form.viewselect'} ="Detailed Citation View";
+        }
     }
     $ENV{'form.phase'} = 'disp_basic' if (! exists($ENV{'form.phase'}));
     ##
@@ -272,11 +312,6 @@
             &get_persistent_data($persistent_db_file,
                  ['query','customquery','customshow',
                   'libraries','pretty_string']);
-        &write_status($r,"query         = $query");
-        &write_status($r,"customquery   = $customquery");
-        &write_status($r,"customshow    = $customshow");
-        &write_status($r,"libraries     = $libraries");
-        &write_status($r,"pretty_string = $pretty_string");
         &run_search($r,$query,$customquery,$customshow,
                     $libraries,$pretty_string);
     } elsif(($ENV{'form.phase'} eq 'basic_search') ||
@@ -376,8 +411,6 @@
 ENDDOCUMENT
     $scrout.='&nbsp;'.&simpletextfield('basicexp',$ENV{'form.basicexp'},40).
         '&nbsp;';
-#    $scrout.=&simplecheckbox('allversions',$ENV{'form.allversions'});
-#    $scrout.='<font color="#800000">Search historic archives</font>';
     my $checkbox = &simplecheckbox('related',$ENV{'form.related'});
     $scrout.=<<END;
 </td><td><a href="/adm/searchcat?phase=disp_adv">Advanced Search</a></td></tr>
@@ -755,7 +788,7 @@
     my $filename = shift;
     my %save;
     foreach (keys(%ENV)) {
-        next if (! /^form/ || /submit/);
+        next if (!/^form/ || /submit/);
         $save{$_} = $ENV{$_};
     }
     return &make_persistent($r,\%save,$filename);
@@ -1604,38 +1637,23 @@
 
 =pod
 
-=item &write_status()
-
-=cut
-
-######################################################################
-######################################################################
-sub write_status {
-    my ($r,$string) = @_;
-    $string =~ s/(\')/\$1/g;
-    $string =~ s/\n//sg;
-#    $r->print("<script>alert('$string');</script>\n");
-#    $r->rflush();
-    return;
-}
-
-######################################################################
-######################################################################
-
-=pod
-
 =item Search Status update functions
 
 Each of the following functions changes the values of one of the
-input fields used to display the search status to the user.
+input fields used to display the search status to the user.  The names
+should be explanatory.
+
+Inputs: Apache request handler ($r), text to display.
+
+Returns: Nothing.
 
 =over 4
 
 =item &update_count_status()
 
-=item &update_contact_status()
+=item &update_status()
 
-=item &update_read_status()
+=item &update_seconds()
 
 =back
 
@@ -1651,19 +1669,19 @@
     $r->rflush();
 }
 
-sub update_contact_status {
+sub update_status {
     my ($r,$text) = @_;
     $text =~ s/\'/\\\'/g;
     $r->print
-        ("<script>document.statusform.c_server.value = ' $text'</script>\n");
+        ("<script>document.statusform.status.value = ' $text'</script>\n");
     $r->rflush();
 }
 
-sub update_read_status {
+sub update_seconds {
     my ($r,$text) = @_;
     $text =~ s/\'/\\\'/g;
     $r->print
-        ("<script>document.statusform.r_server.value = ' $text'</script>\n");
+        ("<script>document.statusform.seconds.value = ' $text'</script>\n");
     $r->rflush();
 }
 
@@ -1680,7 +1698,7 @@
 ######################################################################
 sub run_search {
     my ($r,$query,$customquery,$customshow,$serverlist,$pretty_string) = @_;
-    my $c = $r->connection;
+    my $connection = $r->connection;
     #
     # Timing variables
     #
@@ -1703,7 +1721,7 @@
     }
     my %Server_status;
     my $table =$ENV{'form.table'};
-    if (! defined($table) || $table eq '') {
+    if (! defined($table) || $table eq '' || $table =~ /\D/ ) {
         $r->print("Unable to determine table id to store search results in.".
                   "The search has been aborted.</body></html>");
         return;
@@ -1730,18 +1748,22 @@
     my $status;
     $r->print(<<END);
 <form name="statusform" action="" method="post">
+<input type="hidden" name="Queue" value="" />
 <table>
-<tr><th>Contacting</th><th>Receiving</th><th>Total Matches</th></tr>
+<tr><th>Status</th><th>Total Matches</th><th>Time Remaining</th></tr>
 <tr>
-<td><input type="text" name="c_server" value="" size="15" /></td>
-<td><input type="text" name="r_server" value="" size="15" /></td>
-<td><input type="text" name="count" value="" size="10" /></td>
+<td><input type="text" name="status"  value="" size="30" /></td>
+<td><input type="text" name="count"   value="" size="10" /></td>
+<td><input type="text" name="seconds" value="" size="8" /></td>
 </tr>
 </table>
 </form>
 END
     $r->rflush();
-    while ((time - $starttime < $max_time) && 
+    my $time_remaining = $max_time - (time - $starttime) ;
+    my $last_time = $time_remaining;
+    &update_seconds($r,$time_remaining);
+    while (($time_remaining > 0) && 
            ((@Servers_to_contact) || keys(%Server_status))) {
         # Send out a search request if it needs to be done.
         if (@Servers_to_contact) {
@@ -1751,13 +1773,17 @@
                                                       $customshow,[$server]);
             ($server) = keys(%$reply);
             $Server_status{$server} = $reply->{$server};
-            &update_contact_status($r,$server);
+            &update_status($r,'contacting '.$server);
         } else {
-            &update_contact_status($r,'none');
-            sleep(1); # wait a sec. to give time for files to be written
+            # wait a sec. to give time for files to be written
+            # This sleep statement is here instead of outside the else 
+            # block because we do not want to pause if we have servers
+            # left to contact.  
+            sleep(1); 
         }
+        &update_status($r,'waiting on '.(join(' ',keys(%Server_status))));
         while (my ($server,$status) = each(%Server_status)) {
-            last if ($c->aborted());
+            last if ($connection->aborted());
             if ($status eq 'con_lost') {
                 delete ($Server_status{$server});
                 next;
@@ -1765,27 +1791,26 @@
             $status=~/^([\.\w]+)$/; 
        	    my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1;
             if (-e $datafile && ! -e "$datafile.end") {
+                &update_status($r,'Receiving results from '.$server);
                 next;
             }
-            last if ($c->aborted());
+            last if ($connection->aborted());
             if (-e "$datafile.end") {
-                &update_read_status($r,$server);
+                &update_status($r,'Reading results from '.$server);
                 if (-z "$datafile") {
                     delete($Server_status{$server});
                     next;
                 }
                 my $fh;
                 if (!($fh=Apache::File->new($datafile))) { 
-                    # Error opening file...
-                    # Tell the user and exit...?
-                    # Should I give up on opening it?
                     $r->print("Unable to open search results file for ".
                                   "server $server.  Omitting from search");
-                    next;
+                    delete($Server_status{$server}); 
+                   next;
                 }
                 # Read in the whole file.
                 while (my $result = <$fh>) {
-                    last if ($c->aborted());
+                    last if ($connection->aborted());
                     # handle custom fields?  Someday we will!
                     chomp($result);
                     next unless $result;
@@ -1800,22 +1825,32 @@
                     }
                     # $r->print(&Apache::lonmysql::get_debug());
                     $hitcountsum ++;
-                    &update_count_status($r,$hitcountsum) if ($hitcountsum % 50 == 0);
+                    $time_remaining = $max_time - (time - $starttime) ;
+                    if ($last_time - $time_remaining > 0) {
+                        &update_seconds($r,$time_remaining);
+                        $last_time = $time_remaining;
+                    }
+                    if ($hitcountsum % 50 == 0) {
+                        &update_count_status($r,$hitcountsum);
+                    }
                 } # End of foreach (@results)
                 $fh->close();
                 # $server is only deleted if the results file has been 
                 # found and (successfully) opened.  This may be a bad idea.
                 delete($Server_status{$server});
-                # $r->print("Received $new_count more results from ".
-                #              $server.".");
             }
-            last if ($c->aborted());
+            last if ($connection->aborted());
             &update_count_status($r,$hitcountsum);
         }
-        last if ($c->aborted());
+        last if ($connection->aborted());
         # Finished looping through the servers
+        $time_remaining = $max_time - (time - $starttime) ;
+        if ($last_time - $time_remaining > 0) {
+            $last_time = $time_remaining;
+            &update_seconds($r,$time_remaining);
+        }
     }
-    &update_read_status($r,'none');
+    &update_status($r,'Search Complete'.$server);
     &Apache::lonmysql::disconnect_from_db();
     # Let the user know
     #
@@ -1887,8 +1922,9 @@
 ######################################################################
 ######################################################################
 sub display_results {
-    my ($r,$mode,$importbutton,$closebutton) = @_;
-    $r->print(&search_results_header());
+    my ($r,$importbutton,$closebutton) = @_;
+    my $connection = $r->connection;
+    $r->print(&search_results_header($importbutton,$closebutton));
     ##
     ## Set viewing function
     ##
@@ -1908,7 +1944,7 @@
     if ($ENV{'form.catalogmode'} eq 'groupsearch') {
         if (! tie(%groupsearch_db,'GDBM_File',$diropendb,
                   &GDBM_WRCREAT(),0640)) {
-            $r->print('Unable to tie hash to db file</body></html>');
+            $r->print('Unable to store import results.</form></body></html>');
             $r->rflush();
             return;
         } 
@@ -1923,7 +1959,7 @@
     }
     my $table_check = &Apache::lonmysql::check_table($table);
     if (! defined($table_check)) {
-        $r->print("A MySQL error has occurred.</body></html>");
+        $r->print("A MySQL error has occurred.</form></body></html>");
         &Apache::lonnet::logthis("lonmysql was unable to determine the status".
                                  " of table ".$table);
         return;
@@ -1938,18 +1974,13 @@
     ##
     my $total_results = &Apache::lonmysql::number_of_rows($table);
     if (! defined($total_results)) {
-        $r->print("A MySQL error has occurred.</body></html>");
+        $r->print("A MySQL error has occurred.</form></body></html>");
         &Apache::lonnet::logthis("lonmysql was unable to determine the number".
                                  " of rows in table ".$table);
         &Apache::lonnet::logthis(&Apache::lonmysql::get_error());
         &Apache::lonnet::logthis(&Apache::lonmysql::get_debug());
         return;
     }
-    if ($total_results == 0) {
-        $r->print("There were no results matching your query.\n".
-                  "</form></body></html>");
-        return;
-    }
     ##
     ## Determine how many results we need to get
     ##
@@ -1967,7 +1998,6 @@
     ##
     ## Output links (if necessary) for 'prev' and 'next' pages.
     ##
-    $r->print("<center>Results $min to $max out of $total_results</center>\n");
     $r->print
         ('<center>'.
          &prev_next_buttons($min,$ENV{'form.show'},$total_results,
@@ -1976,6 +2006,14 @@
                             "&persistent_db_id=".$ENV{'form.persistent_db_id'})
          ."</center>\n"
          );
+    if ($total_results == 0) {
+        $r->print("There are currently no results.\n".
+                  "</form></body></html>");
+        return;
+    } else {
+        $r->print
+            ("<center>Results $min to $max out of $total_results</center>\n");
+    }
     ##
     ## Get results from MySQL table
     ##
@@ -1985,12 +2023,16 @@
     ## Loop through the results and output them.
     ##
     foreach my $row (@Results) {
+        if ($connection->aborted()) {
+            untie %groupsearch_db if (tied(%groupsearch_db));
+            &Apache::lonmysql::disconnect_from_db();
+            return;
+        }
         my %Fields = %{&parse_row(@$row)};
         my $output="<p>\n";
-        $output.=&catalogmode_output($Fields{'title'},$Fields{'url'});
+        my $prefix=&catalogmode_output($Fields{'title'},$Fields{'url'});
         # Render the result into html
-        $output.= &$viewfunction(%Fields);
-        $output.="</p>\n<hr align='left' width='200' noshade />";
+        $output.= &$viewfunction($prefix,%Fields);
         # Print them out as they come in.
         $r->print($output);
         $r->rflush();
@@ -2008,9 +2050,9 @@
              ."</center>\n"
              );
     }
-    $r->print("</body></html>");
+    $r->print("</form></body></html>");
     $r->rflush();
-    untie %groupsearch_db;
+    untie %groupsearch_db if (tied(%groupsearch_db));
     return;
 }
 
@@ -2030,13 +2072,13 @@
 ######################################################################
 ######################################################################
 { 
-my $fnum;
+my $fnum = 0;
 
 sub catalogmode_output {
     my $output = '';
     my ($title,$url) = @_;
     if ($ENV{'form.catalogmode'} eq 'interactive') {
-        $title=~ s/\'/\\'/g; # ' Escape single quotes.
+        $title=~ s/\'/\\\'/g;
         if ($ENV{'form.catalogmode'} eq 'interactive') {
             $output.=<<END 
 <font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT"
@@ -2044,9 +2086,7 @@
 </font>
 END
         }
-    }
-    if ($ENV{'form.catalogmode'} eq 'groupsearch') {
-        $fnum+=0;
+    } elsif ($ENV{'form.catalogmode'} eq 'groupsearch') {
         $groupsearch_db{"pre_${fnum}_link"}=$url;
         $groupsearch_db{"pre_${fnum}_title"}=$title;
         $output.=<<END;
@@ -2257,6 +2297,7 @@
 ######################################################################
 ######################################################################
 sub search_results_header {
+    my ($importbutton,$closebutton) = @_;
     my $result = '';
     # output beginning of search page
     # conditional output of script functions dependent on the mode in
@@ -2268,7 +2309,7 @@
     function select_data(title,url) {
 	changeTitle(title);
 	changeURL(url);
-	self.close();
+	parent.close();
     }
     function changeTitle(val) {
 	if (opener.inf.document.forms.resinfo.elements.t) {
@@ -2289,13 +2330,13 @@
 <script type="text/javascript">
 function select_data(title,url) {
     changeURL(url);
-    self.close();
+    parent.close();
 }
 function changeTitle(val) {
 }
 function changeURL(val) {
-    if (window.opener.document) {
-        window.opener.document.forms["$form"].elements["$element"].value=val;
+    if (parent.targetwin.document) {
+        parent.targetwin.document.forms["$form"].elements["$element"].value=val;
     } else {
 	var url = 'forms[\"$form\"].elements[\"$element\"].value';
         alert("Unable to transfer data to "+url);
@@ -2307,26 +2348,25 @@
     }
     $result.=<<SCRIPT if $ENV{'form.catalogmode'} eq 'groupsearch';
 <script type="text/javascript">
-    function select_data(title,url) {
-//	alert('DEBUG: Should be storing '+title+' and '+url);
-    }
     function queue(val) {
-	if (eval("document.forms.results.returnvalues["+val+"].checked")) {
-	    document.forms.results.acts.value+='1a'+val+'b';
-	}
-	else {
-	    document.forms.results.acts.value+='0a'+val+'b';
-	}
+        if (document.forms.results.returnvalues[val].checked) {
+            parent.statusframe.document.forms.statusform.elements.Queue.value +='1a'+val+'b';
+        } else {
+            parent.statusframe.document.forms.statusform.elements.Queue.value +='0a'+val+'b';
+        }
     }
     function select_group() {
-	window.location=
+	parent.window.location=
     "/adm/groupsort?mode=$ENV{'form.mode'}&catalogmode=groupsearch&acts="+
-	    document.forms.results.acts.value;
+	    parent.statusframe.document.forms.statusform.elements.Queue.value;
     }
 </script>
 SCRIPT
     $result.=<<END;
 </head>
+<form name="results" method="post" action="" >
+<input type="hidden" name="Queue" value="" />
+$importbutton
 END
     return $result;
 }
@@ -2342,6 +2382,14 @@
 ENDSTATUS
 }
 
+sub results_link {
+    my $basic_link   = "/adm/searchcat?"."&table=".$ENV{'form.table'}.
+        "&persistent_db_id=".$ENV{'form.persistent_db_id'};
+    my $results_link = $basic_link."&phase=results".
+        "&pause=10"."&start=0"."&show=20";
+    return $results_link;
+}
+
 ######################################################################
 ######################################################################
 sub print_frames_interface {
@@ -2349,11 +2397,13 @@
     my $basic_link = "/adm/searchcat?"."&table=".$ENV{'form.table'}.
         "&persistent_db_id=".$ENV{'form.persistent_db_id'};
     my $run_search_link = $basic_link."&phase=run_search";
-    my $results_link = $basic_link."&phase=results".
-        "&pause=10"."&start=0"."&show=20";
+    my $results_link = &results_link();
     my $result = <<"ENDFRAMES";
 <html>
 <head>
+<script>
+var targetwin = opener;
+</script>
 <title>LON-CAPA Digital Library Search Results</title>
 </head>
 <frameset rows="150,*">
@@ -2389,10 +2439,10 @@
 ######################################################################
 ######################################################################
 sub detailed_citation_view {
-    my %values = @_;
+    my ($prefix,%values) = @_;
     my $result=<<END;
-<h3><a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
-    target='search_preview'>$values{'title'}</a></h3>
+<b>$prefix<a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
+    target='search_preview'>$values{'title'}</a></b>
 <p>
 <b>$values{'author'}</b>, <i>$values{'owner'}</i><br />
 
@@ -2407,6 +2457,7 @@
 <p>
 $values{'shortabstract'}
 </p>
+<hr align='left' width='200' noshade />
 END
     return $result;
 }
@@ -2422,15 +2473,16 @@
 ######################################################################
 ######################################################################
 sub summary_view {
-    my %values = @_;
+    my ($prefix,%values) = @_;
     my $result=<<END;
-<a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
+$prefix<a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
    target='search_preview'>$values{'author'}</a><br />
 $values{'title'}<br />
 $values{'owner'} -- $values{'lastrevisiondate'}<br />
 $values{'copyrighttag'}<br />
 $values{'extrashow'}
 </p>
+<hr align='left' width='200' noshade />
 END
     return $result;
 }
@@ -2440,6 +2492,28 @@
 
 =pod 
 
+=item &compact_view() 
+
+=cut
+
+######################################################################
+######################################################################
+sub compact_view {
+    my ($prefix,%values) = @_;
+    my $result=<<END;
+$prefix <a href="http://$ENV{'HTTP_HOST'}$values{'url'}"  target='search_preview'>
+$values{'title'}</a>
+<b>$values{'author'}</b><br />
+END
+    return $result;
+}
+
+
+######################################################################
+######################################################################
+
+=pod 
+
 =item &fielded_format_view() 
 
 =cut
@@ -2447,8 +2521,9 @@
 ######################################################################
 ######################################################################
 sub fielded_format_view {
-    my %values = @_;
+    my ($prefix,%values) = @_;
     my $result=<<END;
+$prefix
 <b>URL: </b> <a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
               target='search_preview'>$values{'url'}</a>
 <br />
@@ -2467,6 +2542,7 @@
 <b>Abstract:</b> $values{'shortabstract'}<br />
 $values{'extrashow'}
 </p>
+<hr align='left' width='200' noshade />
 END
     return $result;
 }
@@ -2485,8 +2561,9 @@
 ######################################################################
 ######################################################################
 sub xml_sgml_view {
-    my %values = @_;
+    my ($prefix,%values) = @_;
     my $result=<<END;
+$prefix
 <pre>
 &lt;LonCapaResource&gt;
 &lt;url&gt;$values{'url'}&lt;/url&gt;
@@ -2515,6 +2592,7 @@
 &lt;/LonCapaResource&gt;
 </pre>
 $values{'extrashow'}
+<hr align='left' width='200' noshade />
 END
     return $result;
 }

--matthew1028211117--