File:  [LON-CAPA] / loncom / interface / lonindexer.pm
Revision 1.207: download - view: text, annotated - select for diffs
Sun Jun 6 02:40:30 2010 UTC (14 years ago) by raeburn
Branches: MAIN
CVS tags: version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, loncapaMITrelate_1, HEAD
- Bug 6251.
  - Third arg is now a ref to a hash, instead of a hash.
  - New (optional) fourth arg, is an additional attribute for the
    select tag, e.g., an onchange action.
- Update calls to loncommon::select_form() accordingly.

    1: # The LearningOnline Network with CAPA
    2: # Directory Indexer
    3: #
    4: # $Id: lonindexer.pm,v 1.207 2010/06/06 02:40:30 raeburn Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: ###
   29: 
   30: ###############################################################################
   31: ##                                                                           ##
   32: ## ORGANIZATION OF THIS PERL MODULE                                          ##
   33: ##                                                                           ##
   34: ## 1. Description of functions                                               ##
   35: ## 2. Modules used by this module                                            ##
   36: ## 3. Choices for different output views (detailed, summary, xml, etc)       ##
   37: ## 4. BEGIN block (to be run once after compilation)                         ##
   38: ## 5. Handling routine called via Apache and mod_perl                        ##
   39: ## 6. Other subroutines                                                      ##
   40: ##                                                                           ##
   41: ###############################################################################
   42: 
   43: package Apache::lonindexer;
   44: 
   45: # ------------------------------------------------- modules used by this module
   46: use strict;
   47: use Apache::lonnet;
   48: use Apache::loncommon();
   49: use Apache::lonhtmlcommon();
   50: use Apache::lonsequence();
   51: use Apache::Constants qw(:common);
   52: use Apache::lonmeta;
   53: use Apache::File;
   54: use Apache::lonlocal;
   55: use Apache::lonsource();
   56: use Apache::groupsort();
   57: use GDBM_File;
   58: use LONCAPA qw(:match);
   59: 
   60: # ---------------------------------------- variables used throughout the module
   61: my %hash; # global user-specific gdbm file
   62: my %dirs; # keys are directories, values are the open/close status
   63: my %language; # has the reference information present in language.tab
   64: my %dynhash; # hash of hashes for dynamic metadata
   65: my %dynread; # hash of directories already read for dynamic metadata
   66: my %fieldnames; # Metadata fieldnames
   67: # ----- Values which are set by the handler subroutine and are accessible to
   68: # -----     other methods.
   69: my $extrafield; # default extra table cell
   70: my $fnum; # file counter
   71: my $dnum; # directory counter
   72: 
   73: # ----- Used to include or exclude files with certain extensions.
   74: my @Only = ();
   75: my @Omit = ();
   76: 
   77: 
   78: 
   79: 
   80: # ----------------------------- Handling routine called via Apache and mod_perl
   81: sub handler {
   82:     my $r = shift;
   83:     my $c = $r->connection();
   84:     &Apache::loncommon::content_type($r,'text/html');
   85:     &Apache::loncommon::no_cache($r);
   86:     $r->send_http_header;
   87:     return OK if $r->header_only;
   88:     $fnum=0;
   89:     $dnum=0;
   90: 
   91:     # Deal with stupid global variables (is there a way around making
   92:     # these global to this package?  It is just so wrong....)
   93:     undef (@Only);
   94:     undef (@Omit);
   95:     %fieldnames=&Apache::lonmeta::fieldnames();
   96: 
   97: # ------------------------------------- read in machine configuration variables
   98:     my $iconpath= $r->dir_config('lonIconsURL') . "/";
   99:     my $domain  = $r->dir_config('lonDefDomain');
  100:     my $role    = $r->dir_config('lonRole');
  101:     my $loadlim = $r->dir_config('lonLoadLim');
  102:     my $servadm = $r->dir_config('lonAdmEMail');
  103:     my $sysadm  = $r->dir_config('lonSysEMail');
  104:     my $lonhost = $r->dir_config('lonHostID');
  105:     my $tabdir  = $r->dir_config('lonTabDir');
  106: 
  107: #SB my $fileclr='#ffffe6';
  108:     my $line;
  109:     my (@attrchk,@openpath,$typeselect);
  110:     my $uri=$r->uri;
  111: 
  112: # -------------------------------------- see if called from an interactive mode
  113:     # Get the parameters from the query string
  114:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
  115: 	     ['catalogmode','launch','acts','mode','form','element',
  116:               'only','omit','titleelement']);
  117:     #-------------------------------------------------------------------
  118:     my $closebutton='';
  119:     my $groupimportbutton='';
  120:     my $colspan=''; 
  121:     
  122:     $extrafield='';
  123:     my $diropendb = 
  124: 	"/home/httpd/perl/tmp/$env{'user.domain'}_$env{'user.name'}_sel_res.db";
  125:     %hash = ();
  126:     {
  127: 	my %dbfile;
  128: 	if (tie(%dbfile,'GDBM_File',$diropendb,&GDBM_WRITER(),0640)) {
  129: 	    if ($env{'form.launch'} eq '1') {
  130: 		&start_fresh_session(\%dbfile);
  131: 	    }
  132: 	    while(my($key,$value)=each(%dbfile)) {
  133: 		$hash{$key}=$value;
  134: 	    }
  135: 	    untie(%dbfile);
  136: 	}
  137:     }
  138: # - Evaluate actions from previous page (both cumulatively and chronologically)
  139:         if ($env{'form.catalogmode'} eq 'import' || $hash{'form.catalogmode'} eq 'import') {
  140: 	    &Apache::groupsort::update_actions_hash(\%hash);
  141: 	}
  142:     
  143:     {
  144:   #Hijack lonindexer to verify a title and be close down.
  145:    if ($env{'form.launch'} eq '2') {
  146:        &Apache::loncommon::content_type($r,'text/html');
  147:        my $extra='';
  148:        if (defined($env{'form.titleelement'}) && 
  149: 	   $env{'form.titleelement'} ne '') {
  150: 	   my $verify_title = &Apache::lonnet::gettitle($env{'form.acts'});
  151: #	   &Apache::lonnet::logthis("Hrrm $env{'form.acts'} -- $verify_title");
  152: 	   $verify_title=~s/'/\\'/g;
  153: 	   $extra='window.opener.document.forms["'.$env{'form.form'}.'"].elements["'.$env{'form.titleelement'}.'"].value=\''.$verify_title.'\';';
  154:        }
  155:        my $js = <<ENDSUBM;
  156: 	       <script type="text/javascript">
  157: 		function load() {
  158: 			window.opener.document.forms["$env{'form.form'}"]
  159: 			    .elements["$env{'form.element'}"]
  160: 			    .value='$env{'form.acts'}';
  161: 			$extra
  162: 			window.close();
  163: 		}
  164:    	       </script>
  165: ENDSUBM
  166:        $r->print(&Apache::loncommon::start_page(undef,$js,
  167: 						{'only_body'   =>1,
  168: 						 'add_entries' =>
  169: 						     {'onload' => "load();"},}
  170: 						).
  171: 		 &Apache::loncommon::end_page());
  172:        return OK;
  173:    }
  174:     
  175: # -------------------- refresh environment with user database values (in %hash)
  176: 	&setvalues(\%hash,'form.catalogmode',\%env,'form.catalogmode'   );
  177: 
  178: # --------------------- define extra fields and buttons in case of special mode
  179: 	if ($env{'form.catalogmode'} eq 'interactive') {
  180: #SB	    $extrafield='<td bgcolor="'.$fileclr.'" valign="bottom">'.
  181:             $extrafield='<td class="LC_bottom">'.
  182: 		'<img alt="" src="'.$iconpath.'whitespace1.gif"'.
  183: 		' class="LC_icon" /></td>';
  184: 	    $colspan=" colspan='2' ";
  185:             my $cl=&mt('Close');
  186:             $closebutton=<<END;
  187: <input type="button" name="close" value='$cl' onclick="self.close()" />
  188: END
  189:         }
  190: 	elsif ($env{'form.catalogmode'} eq 'import') {
  191: #SB	    $extrafield='<td bgcolor="'.$fileclr.'" valign="bottom">'.
  192:             $extrafield='<td class="LC_bottom">'.
  193: 		'<img alt="" src="'.$iconpath.'whitespace1.gif"'.
  194: 		' class="LC_icon" /></td>';
  195: 	    $colspan=" colspan='2' ";
  196: 	    my $cl=&mt('Close');
  197:             my $gi=&mt('Import');
  198:             $closebutton=<<END;
  199: <input type="button" name="close" value='$cl' onclick="self.close()" />
  200: END
  201:             $groupimportbutton=<<END;
  202: <input type="button" name="groupimport" value='$gi'
  203: onclick="javascript:select_group()" />
  204: END
  205:         }
  206: 	# Additions made by Matthew to make the browser a little easier to deal
  207: 	# with in the future.
  208: 	#
  209: 	# $mode (at this time) indicates if we are in edit mode.
  210: 	# $form is the name of the form that the URL is placed when the
  211: 	#       selection is made.
  212: 	# $element is the name of the element in $formname which receives
  213: 	#       the URL.
  214: 	#&Apache::lonxml::debug('Checking mode, form, element');
  215: 	&setvalues(\%hash,'form.mode'        ,\%env,'form.mode'   );
  216: 	&setvalues(\%hash,'form.form'        ,\%env,'form.form'   );
  217: 	&setvalues(\%hash,'form.element'     ,\%env,'form.element');
  218: 	&setvalues(\%hash,'form.titleelement',\%env,'form.titleelement');
  219: 	&setvalues(\%hash,'form.only'        ,\%env,'form.only'   );
  220: 	&setvalues(\%hash,'form.omit'        ,\%env,'form.omit'   );
  221: 
  222:         # Deal with 'omit' and 'only' 
  223:         if (exists $env{'form.omit'}) {
  224:             @Omit = split(',',$env{'form.omit'});
  225:         }
  226:         if (exists $env{'form.only'}) {
  227:             @Only = split(',',$env{'form.only'});
  228:         }
  229:         
  230: 	my $mode = $env{'form.mode'};
  231: 	my ($form,$element,$titleelement);
  232: 	if ($mode eq 'edit' || $mode eq 'parmset') {
  233: 	    $form         = $env{'form.form'};
  234: 	    $element      = $env{'form.element'};
  235: 	    $titleelement = $env{'form.titleelement'};
  236: 	}
  237: 	#&Apache::lonxml::debug("mode=$mode form=$form element=$element titleelement=$titleelement");
  238: # ------ set catalogmodefunctions to have extra needed javascript functionality
  239: 	my $catalogmodefunctions='';
  240: 	if ($env{'form.catalogmode'} eq 'interactive' or
  241: 	    $env{'form.catalogmode'} eq 'import') {
  242: 	    # The if statement below sets us up to use the old version
  243: 	    # by default (ie. if $mode is undefined).  This is the easy
  244: 	    # way out.  Hopefully in the future I'll find a way to get 
  245: 	    # the calls dealt with in a more comprehensive manner.
  246: 
  247: #
  248: # There is now also mode "simple", which is for the simple version of the rat
  249: #
  250: #
  251: 	    if (!defined($mode) || ($mode ne 'edit' && $mode ne 'parmset')) {
  252:                 my $location = "/adm/groupsort?&inhibitmenu=yes&catalogmode=import&";
  253:                 $location .= "mode=".$mode."&";
  254:                 $location .= "acts=";
  255: 		$catalogmodefunctions=<<"END";
  256: function select_data(url) {
  257:     changeURL(url);
  258:     self.close();
  259: }
  260: function select_group() {
  261:     window.location="$location"+document.forms.fileattr.acts.value;
  262: }
  263: function changeURL(val) {
  264:     if (opener.inf) {
  265:         if (opener.inf.document.forms.resinfo.elements.u) {
  266: 	    opener.inf.document.forms.resinfo.elements.u.value=val;
  267:         }
  268:     }
  269: }
  270: END
  271:             } elsif ($mode eq 'edit') { # we are in 'edit' mode
  272:                 my $location = "/adm/groupsort?catalogmode=interactive&";
  273:                 $location .= "form=$form&element=$element&mode=edit&acts=";
  274: 		$catalogmodefunctions=<<END;
  275: // mode = $mode
  276: function select_data(url) {
  277:    var location = "/res/?launch=2&form=$form&element=$element&titleelement=$titleelement&acts=" + url;
  278:    window.location=location;
  279:    if (window.opener.document.forms["$form"].elements["$element"].value != url) {
  280:        window.opener.unClean();
  281:    }
  282: }
  283: function select_group() {
  284:     window.location="$location"+document.forms.fileattr.acts.value;
  285: }
  286: 
  287: function changeURL(val) {
  288:     if (window.opener.document) {
  289: 	window.opener.document.forms["$form"].elements["$element"].value=val;
  290:     } else {
  291: 	    alert("The file you selected is: "+val);
  292:     }
  293: }
  294: END
  295:                 if (!$titleelement) {
  296: 		    $catalogmodefunctions.='function changeTitle(val) {}';
  297: 		} else {
  298: 		    $catalogmodefunctions.=<<END;
  299: function changeTitle(val) {
  300:     if (window.opener.document) {
  301: 	    window.opener.document.forms["$form"].elements["$titleelement"].value=val;
  302:     } else {
  303: 	    alert("The title of the file you selected is: "+val);
  304:     }
  305: }
  306: END
  307:                 }
  308:             } elsif ($mode eq 'parmset') {
  309:                 my $location = "/adm/groupsort?catalogmode=interactive&";
  310:                 $location .= "form=$form&element=$element&mode=parmset&acts=";
  311: 		$catalogmodefunctions=<<END;
  312: // mode = $mode
  313: function select_data(url) {
  314:     changeURL(url);
  315:     self.close();
  316: }
  317: 
  318: function select_group() {
  319:     window.location="$location"+document.forms.fileattr.acts.value;
  320: }
  321: 
  322: function changeURL(val) {
  323:     if (window.opener.document) {
  324:         var elementname  = "$element";
  325: 	window.opener.document.forms["$form"].elements[elementname].value=val;
  326:     } else {
  327: 	    alert("The file you selected is: "+val);
  328:     }
  329: }
  330: 
  331: END
  332:             }
  333:         }
  334:         $catalogmodefunctions.=<<END;
  335: var acts='';
  336: function rep_dirpath(suffix,val) {
  337:     eval("document.forms.dirpath"+suffix+".acts.value=val");
  338: }
  339: END
  340: 	if ($env{'form.catalogmode'} eq 'import') {
  341:             $catalogmodefunctions.=<<END;
  342: function queue(val) {
  343:     if (eval("document.forms."+val+".filelink.checked")) {
  344: 	var l=val.length;
  345: 	var v=val.substring(4,l);
  346: 	document.forms.fileattr.acts.value+='1a'+v+'b';
  347:     }
  348:     else {
  349: 	var l=val.length;
  350: 	var v=val.substring(4,l);
  351: 	document.forms.fileattr.acts.value+='0a'+v+'b';
  352:     }
  353: }
  354: END
  355: 	}
  356: 
  357:         my $inhibit_menu = "+'&".&Apache::loncommon::inhibit_menu_check()."'";
  358: # ---------------------------------------------------------------- Print Header
  359:         
  360: 	my $js = <<"ENDHEADER";
  361: <script type="text/javascript">
  362: // <![CDATA[
  363: $catalogmodefunctions;
  364: function update_only(field) {
  365:     alert(field.name);
  366: }
  367: function checkAll() {
  368:     var numForms = document.forms.length;
  369:     for (i=0;i<numForms;i++) {
  370:         var numElements = document.forms[i].elements.length;
  371:         for (j=0;j<numElements;j++){
  372:             var fieldName = document.forms[i].elements[j].name;
  373:             if (fieldName == 'filelink') {
  374:                 document.forms[i].elements[j].checked = true;
  375:                 queue(document.forms[i].name);
  376:             }
  377:         }
  378:     }
  379: }
  380: function uncheckAll() {
  381:     var numForms = document.forms.length;
  382:     for (i=0;i<numForms;i++) {
  383:         var numElements = document.forms[i].elements.length;
  384:         for (j=0;j<numElements;j++){
  385:             var fieldName = document.forms[i].elements[j].name;
  386:             if (fieldName == 'filelink') {
  387:                 document.forms[i].elements[j].checked = false;
  388:                 queue(document.forms[i].name);
  389:             }
  390:         }
  391:     }
  392: }
  393: function openWindow(url, wdwName, w, h, toolbar,scrollbar,locationbar) {
  394:     var xpos = (screen.width-w)/2;
  395:     xpos = (xpos < 0) ? '0' : xpos;
  396:     var ypos = (screen.height-h)/2-30;
  397:     ypos = (ypos < 0) ? '0' : ypos;
  398:     var options = "width=" + w + ",height=" + h + ",screenx="+xpos+",screeny="+ypos+",";
  399:     options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
  400:     options += "menubar=no,toolbar="+toolbar+",location="+locationbar+",directories=no";
  401:     var newWin = window.open(url, wdwName, options);
  402:     newWin.focus();
  403: }
  404: function gothere(val) {
  405:     window.location=val+'?acts='+document.forms.fileattr.acts.value$inhibit_menu;
  406: }
  407: // ]]>
  408: </script>
  409: ENDHEADER
  410: 
  411:         my ($headerdom)=($uri=~m{^/res/($match_domain)/});
  412: 
  413:         if ($env{'form.catalogmode'}) {
  414:             # "Popup mode"
  415:             $r->print(&Apache::loncommon::start_page('Browse published resources',$js,
  416:                                                      {'only_body' => 1,
  417:                                                       'domain' => $headerdom,}));
  418:         } else {
  419:             # Only display page header and breadcrumbs in non-popup mode
  420:             &Apache::lonhtmlcommon::clear_breadcrumbs();
  421:             &Apache::lonhtmlcommon::add_breadcrumb({
  422:                 'text'  => 'Browse published resources',
  423:                 'href'  => '/res/fhwfdev/?launch=1',
  424:             });
  425:             $r->print(&Apache::loncommon::start_page('Browse published resources',$js,
  426:                                                      {'domain' => $headerdom,})
  427:                      .&Apache::lonhtmlcommon::breadcrumbs()
  428:             );
  429:         }
  430: 
  431: # ---------------------------------- get state of file types to be showing
  432: 	if ($env{'form.only'}) {
  433: 	    $typeselect = $env{'form.only'};
  434: 	} else {
  435: 	    $typeselect = '';
  436: 	}
  437: 
  438: # ---------------------------------- get state of file attributes to be showing
  439: 	if ($env{'form.attrs'}) {
  440: 	    for (my $i=0; $i<=16; $i++) {
  441: 		delete $hash{'display_attrs_'.$i};
  442: 		if ($env{'form.attr'.$i} == 1) {
  443: 		    $attrchk[$i] = 'checked';
  444: 		    $hash{'display_attrs_'.$i} = 1;
  445: 		}
  446: 	    }
  447: 	} else {
  448: 	    for (my $i=0; $i<=16; $i++) {
  449: 		$attrchk[$i] = 'checked="checked"' if $hash{'display_attrs_'.$i} == 1;
  450: 	    }
  451: 	}
  452: 
  453:         my @file_categories = &Apache::loncommon::filecategories();
  454:         my %select_file_categories;
  455:         my @select_form_order = ('');
  456:         $select_file_categories{''} = &mt('All file types');
  457:         foreach my $cat (@file_categories) {
  458:             my $types = join(",",&Apache::loncommon::filecategorytypes($cat));
  459:             $select_file_categories{$types} = &mt($cat);
  460:             push(@select_form_order,$types);
  461:         }
  462:         $select_file_categories{'select_form_order'} = \@select_form_order;
  463:         my $onchange = 'this.form.submit();';
  464:         my $type_element=
  465:             &Apache::loncommon::select_form(
  466:                 $typeselect,
  467:                 'only',
  468:                 \%select_file_categories,$onchange);
  469:         my $type_selector = '<label>'.&mt('File Type Displayed: [_1]',
  470:                                           $type_element).'</label>';
  471: 
  472: # ------------------------------- output state of file attributes to be showing
  473: #                                 All versions has to the last item
  474: #                                 since it does not take an extra col
  475: 	my %lt=&Apache::lonlocal::texthash(
  476: 					   'av' => 'All versions',
  477: 					   'ud' => 'Update Display',
  478: 					   'pr' => 'Problems',
  479: 					   'gr' => 'Graphics',
  480: 					   'at' => 'All types',
  481: 					   'hd' => 'Display Options'
  482: 					   );
  483:         my @disp_order = ('0','4','5','6','13','1','2','3','10','14','8','11','7','12','15','16');
  484:         my %disp_options = &Apache::lonlocal::texthash (
  485:                               0  => 'Title',
  486:                               4  => 'Author',
  487:                               5  => 'Keywords',
  488:                               6  => 'Language',
  489:                               13 => 'Notes',
  490:                               1  => 'Size',
  491:                               2  => 'Last access',
  492:                               3  => 'Last modified',
  493:                               10 => 'Source Available',
  494:                               14 => 'Abstract',
  495:                               8  => 'Statistics',
  496:                               11 => 'Linked/Related Resources',
  497:                               7  => 'Show resource',
  498:                               12 => 'Subject',
  499:                               15 => 'Grade Level',
  500:                               16 => 'Standards',
  501:                            );
  502:         my $cell = 0;
  503:         my $numinrow = 4;
  504: 	$r->print('
  505: <form method="post" name="fileattr" action="'.$uri.'" enctype="application/x-www-form-urlencoded">
  506: <fieldset>
  507: <legend>'.$lt{'hd'}.'</legend>
  508: <table style=" border-collapse: collapse; border-style: none;">'."\n");
  509:         foreach my $item (@disp_order) {
  510:             my $style = 'padding-left: 12px; padding-right: 8px;';
  511:             if ($cell%$numinrow == 0) {
  512:                 $r->print('<tr>');
  513:             }
  514:             $cell ++;
  515:             if ($cell > 3 * $numinrow) {
  516:                 $style .= ' padding-bottom: 6px;'; 
  517:             }
  518:             if (defined($disp_options{$item})) {
  519:                 $r->print('<td style="'.$style.'"><span class="LC_nobreak">'.
  520:                           '<label><input type="checkbox" name="attr'.$item.'" value="1" '.
  521:                           $attrchk[$item].' onclick="this.form.submit();" /> '.$disp_options{$item}.
  522:                           '</label></span></td>'."\n");
  523:             }
  524:             if ($cell > 1 && $cell%$numinrow == 0) {
  525:                 $r->print('</tr>');
  526:             }
  527:         }
  528:         $r->print(<<END);
  529: <tr>
  530: <td style="font-style: italic; border-top: 1px solid black; padding-top: 6px"> 
  531: <label><input type="checkbox" name="attr9" value="1" $attrchk[9] onclick="this.form.submit();" /> $lt{'av'}</label>
  532: </td>
  533: <td colspan="3" style="padding-left:8px; padding-top: 4px; font-style: italic; border-top: 1px solid black; padding-top: 8px">$type_selector</td>
  534: </tr>
  535: </table>
  536: <input type="hidden" name="attrs" value="1" />
  537: </fieldset>
  538: <input type="submit" name="updatedisplay" value="$lt{'ud'}" />
  539: <input type="hidden" name="acts" value="" />
  540: $closebutton $groupimportbutton
  541: END
  542:         $r->print(&Apache::loncommon::inhibit_menu_check('input'));
  543:    
  544: # -------------- Filter out sequence containment in crumbs and "recent folders"
  545: 	my $storeuri=$uri;
  546: 	$storeuri='/'.(split(/\.(page|sequence)\/\//,$uri))[-1];
  547: 	$storeuri=~s/\/+/\//g;
  548: # ---------------------------------------------------------------- Bread crumbs
  549:         $r->print(
  550:             '<p>'
  551:            .&Apache::lonhtmlcommon::crumbs(
  552:                 $storeuri,
  553:                 '',
  554:                 '',
  555:                 (($env{'form.catalogmode'} eq 'import')?
  556:                                  'document.forms.fileattr':''))
  557:            .'<br />'
  558:            .&Apache::lonhtmlcommon::select_recent(
  559:                 'residx',
  560:                 'resrecent',
  561:                 'window.status=this.form.resrecent.options[this.form.resrecent.selectedIndex].value;this.form.action=this.form.resrecent.options[this.form.resrecent.selectedIndex].value;this.form.submit();')
  562:            .'</p>'
  563:         );
  564: # -------------------------------------------------------- Resource Home Button
  565: 	my $reshome=$env{'course.'.$env{'request.course.id'}.'.reshome'};
  566: 	if ($reshome) {
  567: 	    $r->print("<span class=\"LC_fontsize_large\"><a href='");
  568: 	    if ($env{'form.catalogmode'} eq 'import') {
  569: 		$r->print('javascript:document.forms.fileattr.action="'.&Apache::loncommon::inhibit_menu_check($reshome).'";document.forms.fileattr.submit();');
  570: 	    } else {
  571: 		$r->print($reshome);
  572: 	    }
  573: 	    $r->print("'>".&mt('Home').'</a></span>');
  574: 	}
  575: 	$r->print('</form>');
  576: # ------------------------------------------------------ Remember where we were
  577: 	&Apache::loncommon::storeresurl($storeuri);
  578: 	&Apache::lonhtmlcommon::store_recent('residx',$storeuri,$storeuri);
  579: # -------------------------------------------------- Check All and Uncheck all
  580: 	if ($env{'form.catalogmode'} eq 'import') {
  581: 	    $r->print('<p><input type="button" value="'.&mt("Check All").'" id="checkallbutton" onclick="javascript:checkAll()" />');
  582: 	    $r->print('<input type="button" value="'.&mt("Uncheck All").'" id="uncheckallbutton" onclick="javascript:uncheckAll()" /></p>');
  583: 	}
  584: # ----------------- output starting row to the indexed file/directory hierarchy
  585:         #$r->print(&initdebug());
  586:         #$r->print(&writedebug("Omit:@Omit")) if (@Omit);
  587:         #$r->print(&writedebug("Only:@Only")) if (@Only);
  588:         $r->print(&Apache::loncommon::start_data_table("LC_tableBrowseRes")
  589:                  .&Apache::loncommon::start_data_table_header_row());
  590: 	$r->print("<th $colspan>".&mt('Name')."</th>\n");
  591: 	$r->print("<th>".&mt('Title')."</th>\n") 
  592: 	    if ($hash{'display_attrs_0'} == 1);
  593: 	$r->print('<th class="LC_right">'.&mt("Size")." (".&mt("bytes").") ".
  594: 		  "</th>\n") if ($hash{'display_attrs_1'} == 1);
  595: 	$r->print("<th>".&mt("Last accessed")."</th>\n") 
  596: 	    if ($hash{'display_attrs_2'} == 1);
  597: 	$r->print("<th>".&mt("Last modified")."</th>\n")
  598: 	    if ($hash{'display_attrs_3'} == 1);
  599: 	$r->print("<th>".&mt("Author(s)")."</th>\n")
  600: 	    if ($hash{'display_attrs_4'} == 1);
  601: 	$r->print("<th>".&mt("Keywords")."</th>\n")
  602: 	    if ($hash{'display_attrs_5'} == 1);
  603: 	$r->print("<th>".&mt("Language")."</th>\n")
  604: 	    if ($hash{'display_attrs_6'} == 1);
  605: 	$r->print("<th>".&mt("Usage Statistics")." <br />(".
  606: 		  &mt("Courses/Network Hits").") ".&mt('updated periodically')."</th>\n")
  607: 	    if ($hash{'display_attrs_8'} == 1);
  608: 	$r->print("<th>".&mt("Source Available")."</th>\n")
  609: 	    if ($hash{'display_attrs_10'} == 1);
  610: 	$r->print("<th>".&mt("Linked/Related Resources")."</th>\n")
  611: 	    if ($hash{'display_attrs_11'} == 1);
  612: 	$r->print("<th>".&mt("Resource")."</th>\n")
  613: 	    if ($hash{'display_attrs_7'} == 1);
  614: 	$r->print("<th>".&mt("Subject")."</th>\n")
  615: 	    if ($hash{'display_attrs_12'} == 1);
  616: 	$r->print("<th>".&mt("Notes")."</th>\n")
  617: 	    if ($hash{'display_attrs_13'} == 1);
  618: 	$r->print("<th>".&mt("Abstract")."</th>\n")
  619: 	    if ($hash{'display_attrs_14'} == 1);
  620: 	$r->print("<th>".&mt("Grade Level")."</th>\n")
  621: 	    if ($hash{'display_attrs_15'} == 1);
  622: 	$r->print("<th>".&mt("Standards")."</th>\n")
  623: 	    if ($hash{'display_attrs_16'} == 1);
  624: 	    
  625:     $r->print(&Apache::loncommon::end_data_table_header_row());
  626:     
  627:     	
  628: 
  629: # ----------------- read in what directories have previously been set to "open"
  630: 	foreach (keys %hash) {
  631: 	    if ($_ =~ /^diropen_status_/) {
  632: 		my $key = $_;
  633: 		$key =~ s/^diropen_status_//;
  634: 		$dirs{$key} = $hash{$_};
  635: 	    }
  636: 	}
  637: 
  638: 	if ($env{'form.openuri'}) {  # take care of review and refresh options
  639: 	    my $uri=$env{'form.openuri'};
  640: 	    if (exists($hash{'diropen_status_'.$uri})) {
  641: 		my $cursta = $hash{'diropen_status_'.$uri};
  642: 		$dirs{$uri} = 'open';
  643: 		$hash{'diropen_status_'.$uri} = 'open';
  644: 		if ($cursta eq 'open') {
  645: 		    $dirs{$uri} = 'closed';
  646: 		    $hash{'diropen_status_'.$uri} = 'closed';
  647: 		}
  648: 	    } else {
  649: 		$hash{'diropen_status_'.$uri} = 'open';
  650: 		$dirs{$uri} = 'open';
  651: 	    }
  652: 	}
  653: 	
  654: 	my $toplevel;
  655: 	my $indent = 0;
  656: 	$uri = $uri.'/' if $uri !~ /.*\/$/;
  657: 
  658:  	if ($env{'form.dirPointer'} ne 'on') {
  659:  	    $hash{'top.level'} = $uri;
  660:  	    $toplevel = $uri;
  661:  	} else {
  662:  	    $toplevel = $hash{'top.level'};
  663:  	}
  664: 
  665: # -------------------------------- if not at top level, provide an uplink arrow
  666: 	if ($toplevel ne '/res/'){
  667: 	    my (@uri_com) = split(/\//,$uri);
  668: 	    pop @uri_com;
  669: 	    my $upone = join('/',@uri_com);
  670: 	    my @list = qw (0);
  671: 	    &display_line ($r,'opened',$upone.'&viewOneUp',0,$upone,@list);
  672: 	    $indent = 1;
  673: 	}
  674: 
  675: # -------- recursively go through all the directories and output as appropriate
  676: 	&scanDir ($r,$toplevel,$indent,\%hash);
  677: 
  678: # -------------------------------------------------------------- end the tables
  679:         $r->print(&Apache::loncommon::end_data_table());
  680: 
  681: # ---------------------------- embed hidden information useful for group import
  682: 	$r->print("<form name='fnum' action=''>");
  683: 	$r->print("<input type='hidden' name='fnum' value='$fnum' /></form>");
  684: 
  685: # --------------------------------------------------- end the output and return
  686: 	$r->print(&Apache::loncommon::end_page()."\n");
  687:     }
  688:     if(! $c->aborted()) {
  689: # write back into the temporary file
  690: 	my %dbfile;
  691:         if (tie(%dbfile,'GDBM_File',$diropendb,&GDBM_NEWDB(),0640)) {
  692:             while (my($key,$value) = each(%hash)) {
  693:                 $dbfile{$key}=$value;
  694:             }
  695:             untie(%dbfile);
  696:         }
  697:     }
  698: 
  699:     return OK;
  700: }
  701: 
  702: # ----------------------------------------------- recursive scan of a directory
  703: sub scanDir {
  704:     my ($r,$startdir,$indent,$hashref)=@_;
  705:     my $c = $r->connection();
  706:     my ($compuri,$curdir);
  707:     my $dirptr=16384;
  708:     my $obs;
  709:     $indent++;
  710:     my %dupdirs = %dirs;
  711:     my @list=&get_list($r,$startdir);
  712:     foreach my $line (@list) {
  713:         return if ($c->aborted());
  714: 	#This is a kludge, sorry aboot this
  715: 	my ($strip,$dom,undef,$testdir,undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,$obs,undef)=split(/\&/,$line,16); 
  716: 	next if($strip =~ /.*\.meta$/ | $obs eq '1');
  717: 	my (@fileparts) = split(/\./,$strip);
  718: 	if ($hash{'display_attrs_9'} != 1) {
  719:             # if not all versions to be shown
  720: 	    if (scalar(@fileparts) >= 3) {
  721: 		my $fext = pop @fileparts;
  722: 		my $ov = pop @fileparts;
  723: 		my $fname = join ('.',@fileparts,$fext);
  724: 		next if (grep /\Q$fname\E/,@list and $ov =~ /^\d+$/);
  725: 	    }
  726: 	}
  727: 
  728: 	if ($dom eq 'domain') {
  729: 	    # dom list has full path /res/<domain name>/ already
  730: 	    $curdir='';
  731: 	    $compuri = (split(/\&/,$line))[0];
  732: 	} else {
  733: 	    # user, dir & file have name only, i.e., w/o path
  734: 	    $compuri = join('',$startdir,$strip,'/');
  735: 	    $curdir = $startdir;
  736: 	}
  737: 	my $diropen = 'closed';
  738: 	if (($dirptr&$testdir) or ($dom =~ /^(domain|user)$/) or ($compuri=~/\.(sequence|page)\/$/)) {
  739: 	    while (my ($key,$val)= each %dupdirs) {
  740: 		if ($key eq $compuri and $val eq "open") {
  741: 		    $diropen = "opened";
  742: 		    delete($dupdirs{$key});
  743: 		    delete($dirs{$key});
  744: 		}
  745: 	    }
  746: 	}
  747: 	&display_line($r,$diropen,$line,$indent,$curdir,$hashref,@list);
  748: 	&scanDir ($r,$compuri,$indent) if $diropen eq 'opened';
  749:     }
  750:     $indent--;
  751: }
  752: 
  753: # --------------- get complete matched list based on the uri (returns an array)
  754: sub get_list {
  755:     my ($r,$uri)=@_;
  756:     my @list=();
  757:     (my $luri = $uri) =~ s/\//_/g;
  758:     if ($env{'form.updatedisplay'}) {
  759: 	foreach (keys %hash) {
  760: 	    delete $hash{$_} if ($_ =~ /^dirlist_files_/);
  761: 	    delete $hash{$_} if ($_ =~ /^dirlist_timestamp_files_/);
  762: 	}
  763:     }
  764: 
  765:     if (defined($hash{'dirlist_files_'.$luri}) &&
  766: 	$hash{'dirlist_timestamp_files_'.$luri}+600 > (time)) {
  767: 	@list = split(/\n/,$hash{'dirlist_files_'.$luri});
  768:     } elsif ($uri=~/\.(page|sequence)\/$/) {
  769: # is a page or a sequence
  770: 	$uri=~s/\/$//;
  771: 	$uri='/'.(split(/\.(page|sequence)\/\//,$uri))[-1];
  772: 	$uri=~s/\/+/\//g;
  773: 	foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$uri))) {
  774: 	    my @ratpart=split(/\:/,$_);
  775: 	    push(@list,&LONCAPA::map::qtescape($ratpart[1]));
  776: 	} 
  777: 	$hash{'dirlist_files_'.$luri} = join("\n",@list);
  778:     } else {
  779: # is really a directory
  780: 	@list = &Apache::lonnet::dirlist($uri);
  781: 	$hash{'dirlist_files_'.$luri} = join("\n",@list);
  782: 	$hash{'dirlist_timestamp_files_'.$luri} = time;
  783:     }
  784:     return @list=&match_ext($r,@list);    
  785: }
  786: 
  787: sub dynmetaread {
  788:     my $uri=shift;
  789:     if (($hash{'display_attrs_8'}==1) || ($hash{'display_attrs_11'}==1)) {
  790: # We don't want the filename
  791: 	$uri=~s/\/[^\/]+$//;
  792: # Did we already see this?
  793: 	my $builddir=$uri;
  794: 	while ($builddir) {
  795: 	    if ($dynread{$builddir}) {
  796: 		return 0;
  797: 	    }
  798: 	    $builddir=~s/\/[^\/]+$//;
  799: 	}
  800: # Actually get the data
  801: 	%dynhash=
  802: 	    (%dynhash,&Apache::lonmeta::get_dynamic_metadata_from_sql($uri.'/'));
  803: # Remember that we got it
  804: 	$dynread{$uri}=1;
  805:     } 
  806: }
  807: 
  808: sub initdebug {
  809:     my $start_page=
  810: 	&Apache::loncommon::start_page('Debug',undef,
  811: 				       {'only_body' => 1,});
  812:     $start_page =~ s/\n/ /g;
  813:     return <<ENDJS;
  814: <script type="text/javascript">
  815: var debugging = true;
  816: if (debugging) {
  817:     var debuggingWindow = window.open('','Debug','width=400,height=300',true);
  818: } 
  819: 
  820: function output(text) {
  821:     if (debugging) {
  822:         debuggingWindow.document.writeln(text);
  823:     }
  824: }
  825: output('$start_page<pre>');   
  826: </script>
  827: ENDJS
  828: }
  829: 
  830: sub writedebug {
  831:     my ($text) = @_;
  832:     return "<script type=\"text/javascript\">output('$text');</script>";
  833: }
  834: 
  835: # -------------------- filters out files based on extensions (returns an array)
  836: sub match_ext {
  837:     my ($r,@packlist)=@_;
  838:     my @trimlist;
  839:     my $nextline;
  840:     my @fileext;
  841:     my $dirptr=16384;
  842: 
  843:     foreach my $line (@packlist) {
  844: 	chomp $line;
  845: 	$line =~ s/^\/home\/httpd\/html//;
  846: 	my @unpackline = split (/\&/,$line);
  847: 	next if ($unpackline[0] eq '.');
  848: 	next if ($unpackline[0] eq '..');
  849: 	my @filecom = split (/\./,$unpackline[0]);
  850: 	my $fext = pop(@filecom);
  851: 	my $fnptr = ($unpackline[3]&$dirptr) || ($fext=~/\.(page|sequence)$/);
  852:  	if ($fnptr == 0 and $unpackline[3] ne "") {
  853: 	    my $embstyle = &Apache::loncommon::fileembstyle($fext);
  854:             push @trimlist,$line if (defined($embstyle) && 
  855: 				     ($embstyle ne 'hdn' or $fext eq 'meta'));
  856: 	} else {
  857: 	    push @trimlist,$line;
  858: 	}
  859:     }
  860:     @trimlist = sort {uc($a) cmp uc($b)} (@trimlist);
  861:     return @trimlist;
  862: }
  863: 
  864: # ------------------------------- displays one line in appropriate table format
  865: sub display_line {
  866:     my ($r,$diropen,$line,$indent,$startdir,$hashref,@list)=@_;
  867:     my (@pathfn, $fndir);
  868: # there could be relative paths (files actually belonging into this directory)
  869: # or absolute paths (for example, from sequences)
  870:     my $absolute;
  871:     my $pathprefix;
  872:     if ($line=~m|^/res/| && $startdir ne '') {
  873: 	$absolute=1;
  874: 	$pathprefix='';
  875:     } else {
  876: 	$absolute=0;
  877: 	$pathprefix=$startdir;
  878:     }
  879:     my $dirptr=16384;
  880: #SB my $fileclr="#ffffe6";
  881:     my $iconpath= $r->dir_config('lonIconsURL') . '/';
  882: 
  883:     my @filecom = split (/\&/,$line);
  884:     my @pathcom = split (/\//,$filecom[0]);
  885:     my $listname = $pathcom[scalar(@pathcom)-1];
  886:     my $fnptr = $filecom[3]&$dirptr;
  887:     my $msg = &mt('View').' '.$filecom[0].' '.&mt('resources');
  888:     $msg = &mt('Close').' '.$filecom[0].' '.&mt('directory') if $diropen eq 'opened';
  889:     my $nowOpen = ($diropen eq 'opened' ? 1 : 0);
  890: 
  891:     my $tabtag='</td>';
  892:     my $i=0;
  893:     while ($i<=16) {
  894: 	$tabtag=join('',$tabtag,"<td>&nbsp;</td>")
  895: 	    if ($i != 9 &&
  896: 		$hash{'display_attrs_'.$i} == 1);
  897: 	$i++;
  898:     }
  899:     my $valign = ($hash{'display_attrs_7'} == 1 ? 'top' : 'bottom');
  900: 
  901: # display uplink arrow
  902:     if ($filecom[1] eq 'viewOneUp') {
  903: 	my $updir=$startdir;
  904: # -------------- Filter out sequence containment in crumbs and "recent folders"
  905: 	$updir='/'.(split(/\.(page|sequence)\/\//,$startdir))[-1];
  906: 	$updir=~s/\/+/\//g;
  907: 
  908: #SB	$r->print("<tr valign='$valign' bgcolor=\"$fileclr\">$extrafield");
  909:         $r->print(&Apache::loncommon::start_data_table_row()); # valign="$valign" ?!?
  910:         $r->print($extrafield);
  911: 	$r->print("<td>\n");
  912: 	$r->print ('<form method="post" name="dirpathUP" action="'.$updir.
  913: 		   '/" '.
  914: 		   'onsubmit="return rep_dirpath(\'UP\','.
  915: 		   'document.forms.fileattr.acts.value)" '.
  916: 		   'enctype="application/x-www-form-urlencoded"'.
  917:                    '>'."\n");
  918: 	$r->print(&Apache::loncommon::inhibit_menu_check('input'));
  919: 	$r->print ('<input type="hidden" name="openuri" value="'.
  920: 		   $startdir.'" />'."\n");
  921:         $r->print ('<input type="hidden" name="acts" value="" />'."\n");
  922: 	$r->print ('<a href="#" onclick="document.dirpathUP.submit()"><img src="'.$iconpath.'arrow.up.gif"');
  923: 	$r->print (' alt="'.$msg.'" class="LC_fileicon" />'.
  924: 		   "\n");
  925: 	$r->print(&mt("Up")."</a></form>$tabtag");
  926:         $r->print(&Apache::loncommon::end_data_table_row());
  927: 	return OK;
  928:     }
  929: # Do we have permission to look at this?
  930:     if($filecom[15] ne '1') { return OK if ((!&Apache::lonnet::allowed('bre',$pathprefix.$filecom[0])) && (!&Apache::lonnet::allowed('bro',$pathprefix.$filecom[0]))); }
  931: 
  932: # make absolute links appear on different background
  933: #SB    if ($absolute) { $fileclr='#ccdd99'; }
  934: 
  935: # display domain
  936:     if ($filecom[1] eq 'domain') {
  937:  	$r->print ('<input type="hidden" name="dirPointer" value="on" />'."\n")
  938:  	    if ($env{'form.dirPointer'} eq "on");
  939: #SB	$r->print("<tr valign='$valign' bgcolor=\"$fileclr\">$extrafield");
  940: 	$r->print(&Apache::loncommon::start_data_table_row()); # valign="$valign" ?!?"
  941:         $r->print($extrafield);
  942: 	$r->print("<td>");
  943: 	&begin_form ($r,$filecom[0]);
  944: 	my $anchor = $filecom[0];
  945: 	$anchor =~ s/\W//g;
  946: 	$r->print ('<a name="'.$anchor.'"></a>');
  947: $r->print ('<input type="hidden" name="acts" value="" />');
  948: 	$r->print ('<a href="#" onclick="document.dirpath'.($dnum-1).'.submit()"><img src="'.$iconpath.'arrow.'.($nowOpen ? "open" : "closed" ).'.gif"'); 
  949: 	$r->print (' alt="'.$msg.'" class="LC_fileicon" /></a>'.
  950: 		   "\n");
  951: 	my $quotable_filecom = &Apache::loncommon::escape_single($filecom[0]);
  952: 	$r->print ('<a href="javascript:gothere(\''.$quotable_filecom.
  953: 		   '\')"><img alt="" src="'.$iconpath.'server.gif"');
  954: 	$r->print (' class="LC_fileicon" />'."\n");
  955: 	$r->print (&mt("Domain")." - $listname </a>");
  956: 	if (&Apache::lonnet::domain($listname,'description')) {
  957: 	    $r->print("<br />(".&Apache::lonnet::domain($listname,'description').
  958: 		      ")");
  959: 	}
  960: 	$r->print("</form>$tabtag");
  961:          $r->print(&Apache::loncommon::end_data_table_row());
  962: 	return OK;
  963: 
  964: # display user directory
  965:     }
  966:     if ($filecom[1] eq 'user') {
  967: 	# $r->print("<tr valign=$valign bgcolor=\"$fileclr\">$extrafield");
  968: 	my $curdir = $startdir.$filecom[0].'/';
  969: 	my $anchor = $curdir;
  970: 	$anchor =~ s/\W//g;
  971: #SB	$r->print("<tr bgcolor=\"$fileclr\">$extrafield<td valign=$valign>");
  972:         $r->print(&Apache::loncommon::start_data_table_row()
  973:                  .$extrafield.'<td class="LC_'.$valign.'">');
  974: 	&begin_form ($r,$curdir);
  975: 	$r->print ('<a name="'.$anchor.'"></a><img alt="" src="'.$iconpath.
  976: 		   'whitespace_21.gif" class="LC_icon" />'."\n");
  977: 	$r->print ('<input type="hidden" name="acts" value="" />');
  978: 	$r->print ('<a href="#" onclick="document.dirpath'.($dnum-1).'.submit()">');
  979:         $r->print ('<img src="'.$iconpath.'arrow.'.($nowOpen ? "open" : "closed" ).
  980: 		   '.gif" class="LC_fileicon"'); 
  981: 	$r->print (' alt="'.$msg.'"/></a>'.
  982: 		   "\n");
  983: 	my $quotable_curdir = &Apache::loncommon::escape_single($curdir);
  984: 	$r->print ('<a href="javascript:gothere(\''.$quotable_curdir
  985: 		   .'\')"><img alt="'.$msg.'" src="'.
  986: 		   $iconpath.'quill.gif" class="LC_fileicon" />');
  987: 	my $domain=(split(m|/|,$startdir))[2];
  988: 	my $plainname=&Apache::loncommon::plainname($listname,$domain);
  989:         $r->print ($listname.'</a>');
  990: 
  991:         if (defined($plainname) && $plainname) { $r->print(" ($plainname) "); }
  992:         $r->print('</form>'.$tabtag);
  993:         $r->print(&Apache::loncommon::end_data_table_row());
  994:         return OK;
  995:     }
  996: 
  997: # display file
  998:         if (($fnptr == 0 and $filecom[3] ne '') or $absolute) {
  999:             my $title;
 1000:             my $filelink = $pathprefix.$filecom[0];
 1001:             if ($hash{'display_attrs_0'} == 1) {
 1002:                 $title = &Apache::lonnet::gettitle($filelink);
 1003:             }
 1004:             my @file_ext = split (/\./,$listname);
 1005:             my $curfext = $file_ext[-1];
 1006:             if (@Omit) {
 1007:                 foreach (@Omit) { return OK if (lc($curfext) eq $_); }
 1008:             }
 1009:             if (@Only) {
 1010:                 my $skip = 1;
 1011:                 foreach (@Only) { $skip = 0 if (lc($curfext) eq $_); }
 1012:                 return OK if ($skip > 0);
 1013:             }
 1014:             # Set the icon for the file
 1015:             my $iconname = &Apache::loncommon::icon($listname);
 1016: #SB	$r->print("<tr valign='$valign' bgcolor=\"$fileclr\">);
 1017:         $r->print(&Apache::loncommon::start_data_table_row()); #SB valign="$valign" ?!?
 1018:         $r->print('<td class="LC_middle LC_nobreak">');
 1019: 	
 1020:         if ($env{'form.catalogmode'} eq 'interactive') {
 1021: 	    my $quotable_filelink = &Apache::loncommon::escape_single($filelink);
 1022:             $r->print("<a href=\"javascript:select_data(\'",
 1023:                       $quotable_filelink,"')\">");
 1024: 	    $r->print("<img alt=\"\" src='",$iconpath,"select.gif' class='LC_icon' /></a>".
 1025: 		      "\n");
 1026: 	    $r->print('</td><td class="LC_middle">');
 1027: 	} elsif ($env{'form.catalogmode'} eq 'import') {
 1028: 	    $r->print("<form name='form$fnum' action=''>\n");
 1029: 	    $r->print("<input type='checkbox' name='filelink"."' ".
 1030: 		      "value='$filelink' onclick='".
 1031: 		      "javascript:queue(\"form$fnum\")' ");
 1032: 	    if ($hash{'store_'.$filelink}) {
 1033: 		$r->print("checked");
 1034: 	    }
 1035: 	    $r->print(" />\n");
 1036: 	    $r->print('</form></td><td class="LC_middle">');
 1037: 	    $hash{"pre_${fnum}_link"}=$filelink;
 1038: 	    $hash{"pre_${fnum}_title"}=$title;
 1039: 	    if (!$hash{"pre_${fnum}_title"}) {
 1040: 	        $hash{"pre_${fnum}_title"} = 'Not_retrieved';
 1041: 	    }
 1042:   	    $fnum++;
 1043: 	}
 1044: # Form to open or close sequences
 1045: 	if ($filelink=~/\.(page|sequence)$/) {
 1046: 	    my $curdir = $startdir.$filecom[0].'/';
 1047: 	    &begin_form($r,$curdir);
 1048: 	    $indent--;
 1049: 	}
 1050: # General indentation
 1051: 	    my $count = 0;
 1052: 	    while ($count < $indent) {
 1053:             $r->print('<img alt="" src="'.$iconpath.'whitespace_21.gif" 
 1054:                 class="LC_icon" />');
 1055: 	        $count++;
 1056: 	    }
 1057: # Sequence open/close icon
 1058: 	if ($filelink=~/\.(page|sequence)$/) {
 1059: 	    my $curdir = $startdir.$filecom[0].'/';
 1060: 	    my $anchor = $curdir;
 1061: 	    $anchor =~ s/\W//g;
 1062: 	    $r->print ('<input type="hidden" name="acts" value="" />');
 1063: 	    $r->print ('<a name="'.$anchor.'"></a>');
 1064:             $r->print ('<a href="#" onclick="document.dirpath'.($dnum-1).'.submit()">');
 1065:             $r->print ('<img src="'.$iconpath.'arrow.'.($nowOpen ? "open" : "closed" ).
 1066:                        '.gif" class="LC_fileicon"');
 1067: 	    $r->print (' alt="'.$msg.'" /></a>'.
 1068: 		       "\n");
 1069: 	}
 1070: # Filetype icons
 1071: 	$r->print("<img alt=\"\" src='$iconname' class='LC_fileicon' />\n");
 1072: 	my $quotable_filelink = &Apache::loncommon::escape_single($filelink);
 1073: 
 1074: 	$r->print (" <a href=\"javascript:openWindow('".$quotable_filelink.
 1075: 		   "?inhibitmenu=yes','previewfile','450','500','no','yes','yes');\"".
 1076: 		   " target=\"_self\">$listname</a> ");
 1077: 	$quotable_filelink = &Apache::loncommon::escape_single($filelink.'.meta');
 1078: 	&Apache::loncommon::inhibit_menu_check(\$quotable_filelink);
 1079: 	$r->print (" (<a href=\"javascript:openWindow('".$quotable_filelink.
 1080: 		   "?inhibitmenu=yes','metadatafile','500','550','no','yes','no');\" ".
 1081: 		   " target=\"_self\">".&mt('metadata')."</a>) ");
 1082: # Close form to open/close sequence
 1083: 	if ($filelink=~/\.(page|sequence)$/) {
 1084: 	    $r->print('</form>');
 1085: 	}
 1086: 	$r->print("</td>\n");
 1087: 	if ($hash{'display_attrs_0'} == 1) {
 1088: 	    $r->print('<td> '.($title eq '' ? '&nbsp;' : $title).
 1089: 		      ' </td>'."\n");
 1090: 	}
 1091: 	$r->print('<td class="LC_right"> ',
 1092: 		  $filecom[8]," </td>\n") 
 1093: 	    if $hash{'display_attrs_1'} == 1;
 1094: 	$r->print('<td class="LC_nobreak"> '.
 1095:                   (&Apache::lonlocal::locallocaltime($filecom[9]))." </td>\n")
 1096: 	    if $hash{'display_attrs_2'} == 1;
 1097: 	$r->print('<td class="LC_nobreak"> '.
 1098:                   (&Apache::lonlocal::locallocaltime($filecom[10]))." </td>\n")
 1099: 	    if $hash{'display_attrs_3'} == 1;
 1100: 
 1101: 	if ($hash{'display_attrs_4'} == 1) {
 1102: 	    my $author = &Apache::lonnet::metadata($filelink,'author');
 1103: 	    $r->print('<td class="LC_nobreak"> '.($author eq '' ? '&nbsp;' : $author).
 1104: 		      " </td>\n");
 1105: 	}
 1106: 	if ($hash{'display_attrs_5'} == 1) {
 1107: 	    my $keywords = &Apache::lonnet::metadata($filelink,'keywords');
 1108: 	    # $keywords = '&nbsp;' if (!$keywords);
 1109: 	    $r->print('<td> '.($keywords eq '' ? '&nbsp;' : $keywords).
 1110: 		      " </td>\n");
 1111: 	}
 1112: 
 1113: 	if ($hash{'display_attrs_6'} == 1) {
 1114: 	    my $lang = &Apache::lonnet::metadata($filelink,'language');
 1115: 	    $lang = &Apache::loncommon::languagedescription($lang);
 1116: 	    $r->print('<td> '.($lang eq '' ? '&nbsp;' : $lang).
 1117: 		      " </td>\n");
 1118: 	}
 1119: 	if ($hash{'display_attrs_8'} == 1) {
 1120: # statistics
 1121: 	    &dynmetaread($filelink);
 1122: 	    $r->print("<td>");
 1123: 
 1124:         for (qw(count course stdno avetries difficulty disc clear technical
 1125:             correct helpful depth)) {
 1126: 
 1127:             dynmetaprint($r,$filelink,$_);
 1128:         }
 1129: 
 1130: 	    $r->print("&nbsp;</td>\n");
 1131: 
 1132: 	}
 1133: 	if ($hash{'display_attrs_10'} == 1) {
 1134: 	    my $source = &Apache::lonnet::metadata($filelink,'sourceavail');
 1135: 	    if($source eq 'open') {
 1136: 		my $sourcelink = &Apache::lonsource::make_link($filelink,$listname);
 1137: 		my $quotable_sourcelink = &Apache::loncommon::escape_single($sourcelink);
 1138: 		&Apache::loncommon::inhibit_menu_check(\$quotable_sourcelink);
 1139: 		$r->print('<td>'."<a href=\"javascript:openWindow('"
 1140: 			  .$quotable_sourcelink.
 1141: 			  "', 'previewsource', '700', '700', 'no', 'yes','yes');\"".
 1142: 			  " target=\"_self\">".&mt('Source Code')."</a> "."</td>\n");
 1143: 	    } else { #A cuddled else. :P
 1144: 		$r->print("<td>&nbsp;</td>\n");
 1145: 	    }
 1146: 	}
 1147: 	if ($hash{'display_attrs_11'} == 1) {
 1148: # links
 1149: 	   &dynmetaread($filelink);
 1150: 	   $r->print('<td>');
 1151: 	   &coursecontext($r,$filelink);
 1152:        for (qw(goto_list comefrom_list sequsage_list dependencies course_list)) {
 1153:              dynmetaprint($r,$filelink,$_);
 1154:        }
 1155: 	   $r->print('</td>');
 1156:         }
 1157:         
 1158:    
 1159: 	
 1160: 	if ($hash{'display_attrs_7'} == 1) {
 1161: # Show resource
 1162: 	   my $output=&showpreview($filelink);
 1163:            $r->print('<td class="LC_fontsize_medium">'.($output eq '' ? '&nbsp;':$output).
 1164: 		      " </td>\n");
 1165:     }
 1166:     
 1167:     if ($hash{'display_attrs_12'} == 1) {
 1168: 	    my $subject = &Apache::lonnet::metadata($filelink,'subject');
 1169: 	    $r->print('<td> '.($subject eq '' ? '&nbsp;' : $subject).
 1170: 		      " </td>\n");
 1171: 	}
 1172: 	
 1173: 	if ($hash{'display_attrs_13'} == 1) {
 1174: 	    my $notes = &Apache::lonnet::metadata($filelink,'notes');
 1175: 	    $r->print('<td> '.($notes eq '' ? '&nbsp;' : $notes).
 1176: 		      " </td>\n");
 1177: 	}
 1178: 	
 1179: 	if ($hash{'display_attrs_14'} == 1) {
 1180: 	    my $abstract = &Apache::lonnet::metadata($filelink,'abstract');
 1181: 	    $r->print('<td> '.($abstract eq '' ? '&nbsp;' : $abstract).
 1182: 		      " </td>\n");
 1183: 	}
 1184: 	
 1185: 	if ($hash{'display_attrs_15'} == 1) {
 1186: 	    my $gradelevel = &Apache::lonnet::metadata($filelink,'gradelevel');
 1187: 	    $r->print('<td> '.($gradelevel eq '' ? '&nbsp;' : $gradelevel).
 1188: 		      " </td>\n");
 1189: 	}
 1190: 	
 1191: 	if ($hash{'display_attrs_16'} == 1) {
 1192: 	    my $standards = &Apache::lonnet::metadata($filelink,'standards');
 1193: 	    $r->print('<td> '.($standards eq '' ? '&nbsp;' : $standards).
 1194: 		      " </td>\n");
 1195: 	}
 1196: 	
 1197: 	$r->print(&Apache::loncommon::end_data_table_row());
 1198: }
 1199:     
 1200:     
 1201: 
 1202: # -- display directory
 1203:     if ($fnptr == $dirptr) {
 1204: 	my $curdir = $startdir.$filecom[0].'/';
 1205: 	my $anchor = $curdir;
 1206: 	$anchor =~ s/\W//g;
 1207: #SB	$r->print("<tr bgcolor=\"$fileclr\">$extrafield<td valign=$valign>");
 1208:         $r->print(&Apache::loncommon::start_data_table_row()); # SB: bgcolor suggestion: darkgrey ("LC_info_row"?!?)
 1209: #	$r->print('<tr class="LC_info_row">');
 1210:         $r->print($extrafield.'<td class="LC_middle LC_nobreak">');
 1211: 	&begin_form ($r,$curdir);
 1212: 	my $indentm1 = $indent-1;
 1213: 	my $count = 0;
 1214: 	while ($count < $indentm1) {
 1215: 	    $r->print ('<img alt="" src="',$iconpath
 1216: 	               ,'whitespace_21.gif" class="LC_icon" />');
 1217:             $count++;
 1218: 	}
 1219: 	$r->print ('<input type="hidden" name="acts" value="" />');
 1220: 	$r->print ('<a name="'.$anchor.'"></a>');
 1221:         $r->print ('<a href="#" onclick="document.dirpath'.($dnum-1).'.submit()"><img src="'.$iconpath.
 1222: 		   'arrow.'.($nowOpen ? "open" : "closed" ).'.gif"');
 1223: 	$r->print (' alt="'.$msg.'" class="LC_fileicon" /></a>'.
 1224: 		   "\n");
 1225: 	my $quotable_curdir = &Apache::loncommon::escape_single($curdir);
 1226:         
 1227:         my $location = &Apache::loncommon::lonhttpdurl("/adm/lonIcons");
 1228: 	my $icon = "navmap.folder.".($nowOpen ? "open":"closed").'.gif';
 1229:         $r->print ('<a href="javascript:gothere('
 1230:                   ."'$quotable_curdir'".');">'
 1231:                   .'<img class="LC_fileicon" alt="'.&mt('Open Folder').'" src="'
 1232:                   .$location.'/'.$icon.'" />'
 1233:                   ."\n");
 1234: 	$r->print ("$listname</a></form></td>\n");
 1235: # Attributes
 1236: 	my $filelink = $startdir.$filecom[0].'/default';
 1237: 
 1238: 	if ($hash{'display_attrs_0'} == 1) {
 1239: 	    my $title = &Apache::lonnet::gettitle($filelink);
 1240: 	    $r->print('<td> '.($title eq '' ? '&nbsp;' : $title).
 1241: 		      ' </td>'."\n");
 1242: 	}
 1243: 	$r->print('<td class="LC_right"> ',
 1244: 		  $filecom[8]," </td>\n") 
 1245: 	    if $hash{'display_attrs_1'} == 1;
 1246: 	$r->print('<td class="LC_break"> '.
 1247:                   (&Apache::lonlocal::locallocaltime($filecom[9]))." </td>\n")
 1248: 	    if $hash{'display_attrs_2'} == 1;
 1249: 	$r->print('<td class="LC_break"> '.
 1250:                   (&Apache::lonlocal::locallocaltime($filecom[10]))." </td>\n")
 1251: 	    if $hash{'display_attrs_3'} == 1;
 1252: 
 1253: 	if ($hash{'display_attrs_4'} == 1) {
 1254: 	    my $author = &Apache::lonnet::metadata($filelink,'author');
 1255: 	    $r->print('<td> '.($author eq '' ? '&nbsp;' : $author).
 1256: 		      " </td>\n");
 1257: 	}
 1258: 	if ($hash{'display_attrs_5'} == 1) {
 1259: 	    my $keywords = &Apache::lonnet::metadata($filelink,'keywords');
 1260: 	    # $keywords = '&nbsp;' if (!$keywords);
 1261: 	    $r->print('<td> '.($keywords eq '' ? '&nbsp;' : $keywords).
 1262: 		      " </td>\n");
 1263: 	}
 1264: 	if ($hash{'display_attrs_6'} == 1) {
 1265: 	    my $lang = &Apache::lonnet::metadata($filelink,'language');
 1266: 	    $lang = &Apache::loncommon::languagedescription($lang);
 1267: 	    $r->print('<td> '.($lang eq '' ? '&nbsp;' : $lang).
 1268: 		      " </td>\n");
 1269: 	}
 1270: 	
 1271: 	if ($hash{'display_attrs_8'} == 1) {
 1272: 	   $r->print('<td>&nbsp;</td>');
 1273: 	}
 1274:  	if ($hash{'display_attrs_10'} == 1) {
 1275: 	   $r->print('<td>&nbsp;</td>');
 1276: 	}
 1277: 	if ($hash{'display_attrs_7'} == 1) {
 1278: 	   $r->print('<td>&nbsp;</td>');
 1279:     }     
 1280:     if ($hash{'display_attrs_11'} == 1) {
 1281: 	   $r->print('<td>&nbsp;</td>');
 1282: 	}
 1283: 	if ($hash{'display_attrs_12'} == 1) {
 1284: 	    my $subject = &Apache::lonnet::metadata($filelink,'subject');
 1285: 	    $r->print('<td> '.($subject eq '' ? '&nbsp;' : $subject).
 1286: 		      " </td>\n");
 1287: 	}
 1288: 	if ($hash{'display_attrs_13'} == 1) {
 1289: 	    my $notes = &Apache::lonnet::metadata($filelink,'notes');
 1290: 	    $r->print('<td> '.($notes eq '' ? '&nbsp;' : $notes).
 1291: 		      " </td>\n");
 1292: 	}
 1293: 	
 1294: 	if ($hash{'display_attrs_14'} == 1) {
 1295: 	    my $abstract = &Apache::lonnet::metadata($filelink,'abstract');
 1296: 	    $r->print('<td> '.($abstract eq '' ? '&nbsp;' : $abstract).
 1297: 		      " </td>\n");
 1298: 	}
 1299: 	
 1300: 	if ($hash{'display_attrs_15'} == 1) {
 1301: 	    my $gradelevel = &Apache::lonnet::metadata($filelink,'gradelevel');
 1302: 	    $r->print('<td> '.($gradelevel eq '' ? '&nbsp;' : $gradelevel).
 1303: 		      " </td>\n");
 1304: 	}
 1305: 	
 1306: 	if ($hash{'display_attrs_16'} == 1) {
 1307: 	    my $standards = &Apache::lonnet::metadata($filelink,'standards');
 1308: 	    $r->print('<td> '.($standards eq '' ? '&nbsp;' : $standards).
 1309: 		      " </td>\n");
 1310: 	}
 1311: 	
 1312: 	
 1313: 	$r->print(&Apache::loncommon::end_data_table_row());
 1314:     }
 1315: 
 1316: }
 1317: 
 1318: sub coursecontext {
 1319:     my ($r,$filelink)=@_;
 1320:     my $filesymb=&Apache::lonnet::symbread($filelink);
 1321:     if ($filesymb) {
 1322: 	my ($map,$index,$resource)=&Apache::lonnet::decode_symb($filesymb);
 1323: 	$r->print(&mt('Already in this course:<br />[_1] in folder/map [_2].<br />',
 1324: 	      &Apache::lonnet::gettitle($resource),
 1325: 	      &Apache::lonnet::gettitle($map)));
 1326:     }
 1327: }
 1328: 
 1329: sub showpreview {
 1330:     my ($filelink)=@_;
 1331:     if ($filelink=~m-^(/ext/|http://)-) {
 1332: 	return &mt('External Resource, preview not enabled');
 1333:     }
 1334:     my ($curfext)=($filelink=~/\.(\w+)$/);
 1335:     my $output='';
 1336:     my $embstyle=&Apache::loncommon::fileembstyle($curfext);
 1337:     if ($embstyle eq 'ssi') {
 1338:        my $cache=$Apache::lonnet::perlvar{'lonDocRoot'}.$filelink.
 1339:                     '.tmp';
 1340:        if ((!$env{'form.updatedisplay'}) &&
 1341:                     (-e $cache)) {
 1342:           open(FH,$cache);
 1343:           $output=join("\n",<FH>);
 1344:           close(FH);
 1345:        } else {
 1346: # In update display mode, remove old cache. This is done to retroactively
 1347: # clean up course context renderings.
 1348: 	  if (-e $cache) {
 1349: 	       unlink($cache);
 1350: 	  }
 1351:           $output=&Apache::lonnet::ssi_body($filelink);
 1352: # Is access denied? Don't render, don't store
 1353:           if ($output=~/LONCAPAACCESSCONTROLERRORSCREEN/s) {
 1354:              $output='';
 1355: # Was this rendered in course content? Don't store
 1356:           } elsif (!&Apache::lonnet::symbread($filelink)) {
 1357:              open(FH,">$cache");
 1358:              print FH $output;
 1359:              close(FH);
 1360:           }
 1361:        }
 1362:     } elsif ($embstyle eq 'img') {
 1363:        $output='<img alt="'.&mt('Preview').'" src="'.$filelink.'" />';
 1364:     } elsif ($filelink=~m{^/res/($match_domain)/($match_username)/}) {
 1365:        $output='<img  alt="'.&mt('Preview').'" src="http://'.
 1366:                  &Apache::lonnet::hostname(&Apache::lonnet::homeserver($2,$1)).
 1367:                  '/cgi-bin/thumbnail.gif?url='.$filelink.'" />';
 1368:     }
 1369:     return $output;
 1370: }
 1371: 
 1372: sub dynmetaprint {
 1373:     my ($r,$filelink,$item)=@_;
 1374:     if ($dynhash{$filelink}->{$item}) {
 1375: 	$r->print("\n<br />".$fieldnames{$item}.': '.
 1376: 		  &Apache::lonmeta::prettyprint($item,
 1377: 						$dynhash{$filelink}->{$item},
 1378: 		  (($env{'form.catalogmode'} ne 'import')?'preview':''),
 1379: 		  '',
 1380: 		  (($env{'form.catalogmode'} eq 'import')?'document.forms.fileattr':''),1));
 1381:     }
 1382: }
 1383: 
 1384: # ------------------- prints the beginning of a form for directory or file link
 1385: sub begin_form {
 1386:     my ($r,$uri) = @_;
 1387:     my $anchor = $uri;
 1388:     $anchor =~ s/\W//g;
 1389:     $uri=&Apache::loncommon::escape_single($uri);
 1390:     $r->print ('<form method="post" name="dirpath'.$dnum.'" action="'.$uri.
 1391: 	       '#'.$anchor.
 1392: 	       '" onsubmit="return rep_dirpath(\''.$dnum.'\''.
 1393: 	       ',document.forms.fileattr.acts.value)" '.
 1394: 	       'enctype="application/x-www-form-urlencoded">'."\n");
 1395:     $r->print ('<input type="hidden" name="openuri" value="'.$uri.'" />'.
 1396: 	       "\n");
 1397:     $r->print ('<input type="hidden" name="dirPointer" value="on" />'."\n");
 1398:     $r->print(&Apache::loncommon::inhibit_menu_check('input'));
 1399:     $dnum++;
 1400: }
 1401: 
 1402: # --------- settings whenever the user causes the indexer window to be launched
 1403: sub start_fresh_session {
 1404:     my ($hash) = @_;
 1405:     delete $hash->{'form.catalogmode'};
 1406:     delete $hash->{'form.mode'};
 1407:     delete $hash->{'form.form'};
 1408:     delete $hash->{'form.element'};
 1409:     delete $hash->{'form.omit'};
 1410:     delete $hash->{'form.only'};
 1411:     foreach (keys %{$hash}) {
 1412:         delete $hash->{$_} if (/^(pre_|store)/);
 1413:     }
 1414: }
 1415: 
 1416: # ------------------------------------------------------------------- setvalues
 1417: sub setvalues {
 1418:     # setvalues is used in registerurl to synchronize the database
 1419:     # hash and environment hashes
 1420:     my ($H1,$h1key,$H2,$h2key) =@_;
 1421:     #
 1422:     if (exists $H2->{$h2key}) {
 1423: 	$H1->{$h1key} = $H2->{$h2key};
 1424:     } elsif (exists $H1->{$h1key}) {
 1425: 	$H2->{$h2key} = $H1->{$h1key};
 1426:     } 
 1427: }
 1428: 
 1429: 1;
 1430: 
 1431: sub cleanup {
 1432:     if (tied(%hash)){
 1433: 	&Apache::lonnet::logthis('Cleanup indexer: hash');
 1434:     }
 1435:     return OK;
 1436: }
 1437: 
 1438: 
 1439: 
 1440: 
 1441: 
 1442: =head1 NAME
 1443: 
 1444: Apache::lonindexer - mod_perl module for cross server filesystem browsing
 1445: 
 1446: =head1 SYNOPSIS
 1447: 
 1448: Invoked by /etc/httpd/conf/srm.conf:
 1449: 
 1450:  <LocationMatch "^/res.*/$">
 1451:  SetHandler perl-script
 1452:  PerlHandler Apache::lonindexer
 1453:  </LocationMatch>
 1454: 
 1455: =head1 INTRODUCTION
 1456: 
 1457: This module enables a scheme of browsing across a cross server.
 1458: 
 1459: This is part of the LearningOnline Network with CAPA project
 1460: described at http://www.lon-capa.org.
 1461: 
 1462: =head1 BEGIN SUBROUTINE
 1463: 
 1464: This routine is only run once after compilation.
 1465: 
 1466: =over 4
 1467: 
 1468: =item *
 1469: 
 1470: Initializes %language hash table.
 1471: 
 1472: =back
 1473: 
 1474: =head1 HANDLER SUBROUTINE
 1475: 
 1476: This routine is called by Apache and mod_perl.
 1477: 
 1478: =over 4
 1479: 
 1480: =item *
 1481: 
 1482: read in machine configuration variables
 1483: 
 1484: =item *
 1485: 
 1486: see if called from an interactive mode
 1487: 
 1488: =item *
 1489: 
 1490: refresh environment with user database values (in %hash)
 1491: 
 1492: =item *
 1493: 
 1494: define extra fields and buttons in case of special mode
 1495: 
 1496: =item *
 1497: 
 1498: set catalogmodefunctions to have extra needed javascript functionality
 1499: 
 1500: =item *
 1501: 
 1502: print header
 1503: 
 1504: =item *
 1505: 
 1506: evaluate actions from previous page (both cumulatively and chronologically)
 1507: 
 1508: =item *
 1509: 
 1510: output title
 1511: 
 1512: =item *
 1513: 
 1514: get state of file attributes to be showing
 1515: 
 1516: =item *
 1517: 
 1518: output state of file attributes to be showing
 1519: 
 1520: =item *
 1521: 
 1522: output starting row to the indexed file/directory hierarchy
 1523: 
 1524: =item *
 1525: 
 1526: read in what directories have previously been set to "open"
 1527: 
 1528: =item *
 1529: 
 1530: if not at top level, provide an uplink arrow
 1531: 
 1532: =item *
 1533: 
 1534: recursively go through all the directories and output as appropriate
 1535: 
 1536: =item *
 1537: 
 1538: information useful for group import
 1539: 
 1540: =item *
 1541: 
 1542: end the tables
 1543: 
 1544: =item *
 1545: 
 1546: end the output and return
 1547: 
 1548: =back
 1549: 
 1550: =head1 OTHER SUBROUTINES
 1551: 
 1552: =over 4
 1553: 
 1554: =item *
 1555: 
 1556: scanDir - recursive scan of a directory
 1557: 
 1558: =item *
 1559: 
 1560: get_list - get complete matched list based on the uri (returns an array)
 1561: 
 1562: =item *
 1563: 
 1564: match_ext - filters out files based on extensions (returns an array)
 1565: 
 1566: =item *
 1567: 
 1568: display_line - displays one line in appropriate table format
 1569: 
 1570: =item *
 1571: 
 1572: begin_form - prints the beginning of a form for directory or file link
 1573: 
 1574: =item *
 1575: 
 1576: start_fresh_session - settings whenever the user causes the indexer window
 1577: to be launched
 1578: 
 1579: =back
 1580: 
 1581: =cut

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.