File:  [LON-CAPA] / loncom / interface / lonindexer.pm
Revision 1.103: download - view: text, annotated - select for diffs
Mon May 10 08:34:50 2004 UTC (20 years, 1 month ago) by taceyjo1
Branches: MAIN
CVS tags: HEAD
Here is the fix for bug 2884 that is better and fixes the problem
without slowing everything down, leaving the 1.101 in there as it
seems
to be good.  If these changes seem to open up some type of blackhole
of
some sort or anything else that is no good, just let me know.

Teaches groupsort about metadata to sort it's self out.  Tested and
works ok.

    1: # The LearningOnline Network with CAPA
    2: # Directory Indexer
    3: #
    4: # $Id: lonindexer.pm,v 1.103 2004/05/10 08:34:50 taceyjo1 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 GDBM_File;
   56: 
   57: # ---------------------------------------- variables used throughout the module
   58: my %hash; # global user-specific gdbm file
   59: my %dirs; # keys are directories, values are the open/close status
   60: my %language; # has the reference information present in language.tab
   61: 
   62: # ----- Values which are set by the handler subroutine and are accessible to
   63: # -----     other methods.
   64: my $extrafield; # default extra table cell
   65: my $fnum; # file counter
   66: my $dnum; # directory counter
   67: 
   68: # ----- Used to include or exclude files with certain extensions.
   69: my @Only = ();
   70: my @Omit = ();
   71: 
   72: 
   73: # ----------------------------- Handling routine called via Apache and mod_perl
   74: sub handler {
   75:     my $r = shift;
   76:     my $c = $r->connection();
   77:     &Apache::loncommon::content_type($r,'text/html');
   78:     &Apache::loncommon::no_cache($r);
   79:     $r->send_http_header;
   80:     return OK if $r->header_only;
   81:     $fnum=0;
   82:     $dnum=0;
   83: 
   84:     # Deal with stupid global variables (is there a way around making
   85:     # these global to this package?  It is just so wrong....)
   86:     undef (@Only);
   87:     undef (@Omit);
   88: 
   89: # ------------------------------------- read in machine configuration variables
   90:     my $iconpath= $r->dir_config('lonIconsURL') . "/";
   91:     my $domain  = $r->dir_config('lonDefDomain');
   92:     my $role    = $r->dir_config('lonRole');
   93:     my $loadlim = $r->dir_config('lonLoadLim');
   94:     my $servadm = $r->dir_config('lonAdmEMail');
   95:     my $sysadm  = $r->dir_config('lonSysEMail');
   96:     my $lonhost = $r->dir_config('lonHostID');
   97:     my $tabdir  = $r->dir_config('lonTabDir');
   98: 
   99:     my $fileclr='#ffffe6';
  100:     my $line;
  101:     my (@attrchk,@openpath);
  102:     my $uri=$r->uri;
  103: 
  104: # -------------------------------------- see if called from an interactive mode
  105:     # Get the parameters from the query string
  106:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
  107: 	     ['catalogmode','launch','acts','mode','form','element',
  108:               'only','omit','titleelement']);
  109:     #-------------------------------------------------------------------
  110:     my $closebutton='';
  111:     my $groupimportbutton='';
  112:     my $colspan=''; 
  113: 
  114:     $extrafield='';
  115:     my $diropendb = 
  116: 	"/home/httpd/perl/tmp/$ENV{'user.domain'}_$ENV{'user.name'}_indexer.db";
  117:     %hash = ();
  118:     {
  119: 	my %dbfile;
  120: 	if (tie(%dbfile,'GDBM_File',$diropendb,&GDBM_READER(),0640)) {
  121: 	    while(my($key,$value)=each(%dbfile)) {
  122: 		$hash{$key}=$value;
  123: 	    }
  124: 	    untie(%dbfile);
  125: 	}
  126:     }
  127:     {
  128: 	if ($ENV{'form.launch'} eq '1') {
  129: 	    &start_fresh_session();
  130:         }
  131: # -------------------- refresh environment with user database values (in %hash)
  132: 	&setvalues(\%hash,'form.catalogmode',\%ENV,'form.catalogmode'   );
  133: 
  134: # --------------------- define extra fields and buttons in case of special mode
  135: 	if ($ENV{'form.catalogmode'} eq 'interactive') {
  136: 	    $extrafield='<td bgcolor="'.$fileclr.'" valign="bottom">'.
  137: 		'<a name="$anchor"><img src="'.$iconpath.'whitespace1.gif"'.
  138: 		' border="0" /></td>';
  139: 	    $colspan=" colspan='2' ";
  140:             my $cl=&mt('Close');
  141:             $closebutton=<<END;
  142: <input type="button" name="close" value='$cl' onClick="self.close()">
  143: END
  144:         }
  145: 	elsif ($ENV{'form.catalogmode'} eq 'groupimport') {
  146: 	    $extrafield='<td bgcolor="'.$fileclr.'" valign="bottom">'.
  147: 		'<a name="$anchor"><img src="'.$iconpath.'whitespace1.gif"'.
  148: 		' border="0" /></td>';
  149: 	    $colspan=" colspan='2' ";
  150: 	    my $cl=&mt('Close');
  151:             my $gi=&mt('Group Import');
  152:             $closebutton=<<END;
  153: <input type="button" name="close" value='$cl' onClick="self.close()">
  154: END
  155:             $groupimportbutton=<<END;
  156: <input type="button" name="groupimport" value='$gi'
  157: onClick="javascript:select_group()">
  158: END
  159:         }
  160: 	# Additions made by Matthew to make the browser a little easier to deal
  161: 	# with in the future.
  162: 	#
  163: 	# $mode (at this time) indicates if we are in edit mode.
  164: 	# $form is the name of the form that the URL is placed when the
  165: 	#       selection is made.
  166: 	# $element is the name of the element in $formname which receives
  167: 	#       the URL.
  168: 	#&Apache::lonxml::debug('Checking mode, form, element');
  169: 	&setvalues(\%hash,'form.mode'        ,\%ENV,'form.mode'   );
  170: 	&setvalues(\%hash,'form.form'        ,\%ENV,'form.form'   );
  171: 	&setvalues(\%hash,'form.element'     ,\%ENV,'form.element');
  172: 	&setvalues(\%hash,'form.titleelement',\%ENV,'form.titleelement');
  173: 	&setvalues(\%hash,'form.only'        ,\%ENV,'form.only'   );
  174: 	&setvalues(\%hash,'form.omit'        ,\%ENV,'form.omit'   );
  175: 
  176:         # Deal with 'omit' and 'only' 
  177:         if (exists $ENV{'form.omit'}) {
  178:             @Omit = split(',',$ENV{'form.omit'});
  179:         }
  180:         if (exists $ENV{'form.only'}) {
  181:             @Only = split(',',$ENV{'form.only'});
  182:         }
  183:         
  184: 	my $mode = $ENV{'form.mode'};
  185: 	my ($form,$element,$titleelement);
  186: 	if ($mode eq 'edit' || $mode eq 'parmset') {
  187: 	    $form         = $ENV{'form.form'};
  188: 	    $element      = $ENV{'form.element'};
  189: 	    $titleelement = $ENV{'form.titleelement'};
  190: 	}
  191: 	#&Apache::lonxml::debug("mode=$mode form=$form element=$element titleelement=$titleelement");
  192: # ------ set catalogmodefunctions to have extra needed javascript functionality
  193: 	my $catalogmodefunctions='';
  194: 	if ($ENV{'form.catalogmode'} eq 'interactive' or
  195: 	    $ENV{'form.catalogmode'} eq 'groupimport') {
  196: 	    # The if statement below sets us up to use the old version
  197: 	    # by default (ie. if $mode is undefined).  This is the easy
  198: 	    # way out.  Hopefully in the future I'll find a way to get 
  199: 	    # the calls dealt with in a more comprehensive manner.
  200: 
  201: #
  202: # There is now also mode "simple", which is for the simple version of the rat
  203: #
  204: #
  205: 	    if (!defined($mode) || ($mode ne 'edit' && $mode ne 'parmset')) {
  206:                 my $location = "/adm/groupsort?catalogmode=groupimport&";
  207:                 $location .= "mode=".$mode."&";
  208:                 $location .= "acts=";
  209: 		$catalogmodefunctions=<<"END";
  210: function select_data(title,url) {
  211:     changeTitle(title);
  212:     changeURL(url);
  213:     self.close();
  214: }
  215: function select_group() {
  216:     window.location="$location"+document.forms.fileattr.acts.value;
  217: }
  218: function changeTitle(val) {
  219:     if (opener.inf) {
  220:         if (opener.inf.document.forms.resinfo.elements.t) {
  221:             opener.inf.document.forms.resinfo.elements.t.value=val;
  222:         }
  223:     }
  224: }
  225: function changeURL(val) {
  226:     if (opener.inf) {
  227:         if (opener.inf.document.forms.resinfo.elements.u) {
  228: 	    opener.inf.document.forms.resinfo.elements.u.value=val;
  229:         }
  230:     }
  231: }
  232: END
  233:             } elsif ($mode eq 'edit') { # we are in 'edit' mode
  234:                 my $location = "/adm/groupsort?catalogmode=interactive&";
  235:                 $location .= "form=$form&element=$element&mode=edit&acts=";
  236: 		$catalogmodefunctions=<<END;
  237: // mode = $mode
  238: function select_data(title,url) {
  239:     changeURL(url);
  240:     changeTitle(title);
  241:     self.close();
  242: }
  243: 
  244: function select_group() {
  245:     window.location="$location"+document.forms.fileattr.acts.value;
  246: }
  247: 
  248: function changeURL(val) {
  249:     if (window.opener.document) {
  250: 	window.opener.document.forms["$form"].elements["$element"].value=val;
  251:     } else {
  252: 	    alert("The file you selected is: "+val);
  253:     }
  254: }
  255: END
  256:                 if (!$titleelement) {
  257: 		    $catalogmodefunctions.='function changeTitle(val) {}';
  258: 		} else {
  259: 		    $catalogmodefunctions.=<<END;
  260: function changeTitle(val) {
  261:     if (window.opener.document) {
  262: 	    window.opener.document.forms["$form"].elements["$titleelement"].value=val;
  263:     } else {
  264: 	    alert("The title of the file you selected is: "+val);
  265:     }
  266: }
  267: END
  268:                 }
  269:             } elsif ($mode eq 'parmset') {
  270:                 my $location = "/adm/groupsort?catalogmode=interactive&";
  271:                 $location .= "form=$form&element=$element&mode=parmset&acts=";
  272: 		$catalogmodefunctions=<<END;
  273: // mode = $mode
  274: function select_data(title,url) {
  275:     changeURL(url);
  276:     self.close();
  277: }
  278: 
  279: function select_group() {
  280:     window.location="$location"+document.forms.fileattr.acts.value;
  281: }
  282: 
  283: function changeURL(val) {
  284:     if (window.opener.document) {
  285:         var elementname  = "$element"+"_value";
  286:         var checkboxname = "$element"+"_setparmval";
  287: 	window.opener.document.forms["$form"].elements[elementname].value=val;
  288:         window.opener.document.forms["$form"].elements[checkboxname].checked=true;
  289:     } else {
  290: 	    alert("The file you selected is: "+val);
  291:     }
  292: }
  293: 
  294: END
  295:             }
  296:         }
  297:         $catalogmodefunctions.=<<END;
  298: var acts='';
  299: function rep_dirpath(suffix,val) {
  300:     eval("document.forms.dirpath"+suffix+".acts.value=val");
  301: }
  302: END
  303: 	if ($ENV{'form.catalogmode'} eq 'groupimport') {
  304:             $catalogmodefunctions.=<<END;
  305: function queue(val) {
  306:     if (eval("document.forms."+val+".filelink.checked")) {
  307: 	var l=val.length;
  308: 	var v=val.substring(4,l);
  309: 	document.forms.fileattr.acts.value+='1a'+v+'b';
  310:     }
  311:     else {
  312: 	var l=val.length;
  313: 	var v=val.substring(4,l);
  314: 	document.forms.fileattr.acts.value+='0a'+v+'b';
  315:     }
  316: }
  317: END
  318: 	}
  319: 
  320: # ---------------------------------------------------------------- Print Header
  321: 	$r->print(<<ENDHEADER);
  322: <html>
  323: <head>
  324: <title>The LearningOnline Network With CAPA Directory Browser</title>
  325: 
  326: <script type="text/javascript">
  327: $catalogmodefunctions
  328: function openWindow(url, wdwName, w, h, toolbar,scrollbar,locationbar) {
  329:     var xpos = (screen.width-w)/2;
  330:     xpos = (xpos < 0) ? '0' : xpos;
  331:     var ypos = (screen.height-h)/2-30;
  332:     ypos = (ypos < 0) ? '0' : ypos;
  333:     var options = "width=" + w + ",height=" + h + ",screenx="+xpos+",screeny="+ypos+",";
  334:     options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
  335:     options += "menubar=no,toolbar="+toolbar+",location="+locationbar+",directories=no";
  336:     var newWin = window.open(url, wdwName, options);
  337:     newWin.focus();
  338: }
  339: function gothere(val) {
  340:     window.location=val+'?acts='+document.forms.fileattr.acts.value;
  341: }
  342: </script>
  343: 
  344: </head>
  345: ENDHEADER
  346: my ($headerdom)=($uri=~/^\/res\/(\w+)\//);
  347: $r->print(&Apache::loncommon::bodytag('Browse Resources',undef,undef,undef,
  348: 				      $headerdom));
  349: # - Evaluate actions from previous page (both cumulatively and chronologically)
  350:         if ($ENV{'form.catalogmode'} eq 'groupimport') {
  351: 	    my $acts=$ENV{'form.acts'};
  352: 	    my @Acts=split(/b/,$acts);
  353: 	    my %ahash;
  354: 	    my %achash;
  355: 	    my $ac=0;
  356: 	    # some initial hashes for working with data
  357: 	    foreach (@Acts) {
  358: 		my ($state,$ref)=split(/a/);
  359: 		$ahash{$ref}=$state;
  360: 		$achash{$ref}=$ac;
  361: 		$ac++;
  362: 	    }
  363: 	    # sorting through the actions and changing the global database hash
  364: 	    foreach (sort {$achash{$a}<=>$achash{$b}} (keys %ahash)) {
  365: 		my $key=$_;
  366: 		if ($ahash{$key} eq '1') {
  367: 		    $hash{'store_'.$hash{'pre_'.$key.'_link'}}=
  368: 			$hash{'pre_'.$key.'_title'};
  369: 		    $hash{'storectr_'.$hash{'pre_'.$key.'_link'}}=
  370: 			$hash{'storectr'}+0;
  371: 		    $hash{'storectr'}++;
  372: 		}
  373: 		if ($ahash{$key} eq '0') {
  374: 		    if ($hash{'store_'.$hash{'pre_'.$key.'_link'}}) {
  375: 			delete $hash{'store_'.$hash{'pre_'.$key.'_link'}};
  376: 		    }
  377: 		}
  378: 	    }
  379: 	    # deleting the previously cached listing
  380: 	    foreach (keys %hash) {
  381: 		if ($_ =~ /^pre_/ && $_ =~/link$/) {
  382: 		    my $key = $_;
  383: 		    $key =~ s/^pre_//;
  384: 		    $key =~ s/_[^_]*$//;
  385: 		    delete $hash{'pre_'.$key.'_title'};
  386: 		    delete $hash{'pre_'.$key.'_link'};
  387: 		}
  388: 	    }
  389: 	}
  390: 	
  391: # ---------------------------------- get state of file attributes to be showing
  392: 	if ($ENV{'form.attrs'}) {
  393: 	    for (my $i=0; $i<=9; $i++) {
  394: 		delete $hash{'display_attrs_'.$i};
  395: 		if ($ENV{'form.attr'.$i} == 1) {
  396: 		    $attrchk[$i] = 'checked';
  397: 		    $hash{'display_attrs_'.$i} = 1;
  398: 		}
  399: 	    }
  400: 	} else {
  401: 	    for (my $i=0; $i<=9; $i++) {
  402: 		$attrchk[$i] = 'checked' if $hash{'display_attrs_'.$i} == 1;
  403: 	    }
  404: 	}
  405: 
  406: # ------------------------------- output state of file attributes to be showing
  407: #                                 All versions has to the last item
  408: #                                 since it does not take an extra col
  409: 	my %lt=&Apache::lonlocal::texthash(
  410: 					   'ti' => 'Title',
  411: 					   'si' => 'Size',
  412: 					   'la' => 'Last access',
  413: 					   'lm' => 'Last modified',
  414: 					   'st' => 'Statistics',
  415: 					   'au' => 'Author',
  416: 					   'kw' => 'Keywords',
  417: 					   'ln' => 'Language',
  418: 					   'sr' => 'Show resource',
  419: 					   'av' => 'All versions',
  420: 					   'ud' => 'Update Display'
  421: 					   );
  422:         my $Displayfileattributes=&mt('Display file attributes');
  423: 	$r->print(<<END);
  424: <form method="post" name="fileattr" action="$uri"
  425:  enctype="application/x-www-form-urlencoded">
  426: <b><font color="#666666">$Displayfileattributes</font></b><br />
  427: <table border=0><tr>
  428: <td><input type="checkbox" name="attr0" value="1" $attrchk[0] onClick="this.form.submit();" /> $lt{'ti'}</td>
  429: <td><input type="checkbox" name="attr1" value="1" $attrchk[1] onClick="this.form.submit();" /> $lt{'si'}</td>
  430: <td><input type="checkbox" name="attr2" value="1" $attrchk[2] onClick="this.form.submit();" /> $lt{'la'}</td>
  431: <td><input type="checkbox" name="attr3" value="1" $attrchk[3] onClick="this.form.submit();" /> $lt{'lm'}</td>
  432: <td><input type="checkbox" name="attr8" value="1" $attrchk[8] onClick="this.form.submit();" /> $lt{'st'}</td>
  433: </tr><tr>
  434: <td><input type="checkbox" name="attr4" value="1" $attrchk[4] onClick="this.form.submit();" /> $lt{'au'}</td>
  435: <td><input type="checkbox" name="attr5" value="1" $attrchk[5] onClick="this.form.submit();" /> $lt{'kw'}</td>
  436: <td><input type="checkbox" name="attr6" value="1" $attrchk[6] onClick="this.form.submit();" /> $lt{'ln'}</td>
  437: <td><input type="checkbox" name="attr7" value="1" $attrchk[7] onClick="this.form.submit();" /> $lt{'sr'}</td>
  438: <td><input type="checkbox" name="attr9" value="1" $attrchk[9] onClick="this.form.submit();" /> $lt{'av'}</td>
  439: <td>&nbsp;</td>
  440: </tr></table>
  441: <input type="hidden" name="attrs" value="1" />
  442: <input type="submit" name="updatedisplay" value="$lt{'ud'}" />
  443: <input type="hidden" name="acts" value="" />
  444: $closebutton $groupimportbutton
  445: END
  446: # -------------- Filter out sequence containment in crumbs and "recent folders"
  447: 	my $storeuri=$uri;
  448: 	$storeuri='/'.(split(/\.(page|sequence)\/\//,$uri))[-1];
  449: 	$storeuri=~s/\/+/\//g;
  450: # ---------------------------------------------------------------- Bread crumbs
  451:         $r->print(&Apache::lonhtmlcommon::crumbs($storeuri,'','',
  452: 				(($ENV{'form.catalogmode'} eq 'groupimport')?
  453: 				 'document.forms.fileattr':'')).
  454: 		  &Apache::lonhtmlcommon::select_recent('residx','resrecent',
  455: 'this.form.action=this.form.resrecent.options[this.form.resrecent.selectedIndex].value;this.form.submit();'));
  456: # -------------------------------------------------------- Resource Home Button
  457: 	my $reshome=$ENV{'course.'.$ENV{'request.course.id'}.'.reshome'};
  458: 	if ($reshome) {
  459: 	    $r->print("<font size='+2'><a href='");
  460: 	    if ($ENV{'form.catalogmode'} eq 'groupimport') {
  461: 		$r->print('javascript:document.forms.fileattr.action="'.$reshome.'";document.forms.fileattr.submit();');
  462: 	    } else {
  463: 		$r->print($reshome);
  464: 	    }
  465: 	    $r->print("'>".&mt('Home').'</a></font>');
  466: 	}
  467: 	$r->print('</form>');
  468: # ------------------------------------------------------ Remember where we were
  469: 	&Apache::loncommon::storeresurl($storeuri);
  470: 	&Apache::lonhtmlcommon::store_recent('residx',$storeuri,$storeuri);
  471: # ----------------- output starting row to the indexed file/directory hierarchy
  472:         my $titleclr="#ddffff";
  473: #        $r->print(&initdebug());
  474: #        $r->print(&writedebug("Omit:@Omit")) if (@Omit);
  475: #        $r->print(&writedebug("Only:@Only")) if (@Only);
  476:         $r->print("<table width='100\%' border=0><tr><td bgcolor=#777777>\n");
  477: 	$r->print("<table width='100\%' border=0><tr bgcolor=$titleclr>\n");
  478: 	$r->print("<td $colspan><b>".&mt('Name')."</b></td>\n");
  479: 	$r->print("<td><b>".&mt('Title')."</b></td>\n") 
  480: 	    if ($hash{'display_attrs_0'} == 1);
  481: 	$r->print("<td align=right><b>".&mt("Size")." (".&mt("bytes").") ".
  482: 		  "</b></td>\n") if ($hash{'display_attrs_1'} == 1);
  483: 	$r->print("<td><b>".&mt("Last accessed")."</b></td>\n") 
  484: 	    if ($hash{'display_attrs_2'} == 1);
  485: 	$r->print("<td><b>".&mt("Last modified")."</b></td>\n")
  486: 	    if ($hash{'display_attrs_3'} == 1);
  487: 	$r->print("<td><b>".&mt("Author(s)")."</b></td>\n")
  488: 	    if ($hash{'display_attrs_4'} == 1);
  489: 	$r->print("<td><b>".&mt("Keywords")."</b></td>\n")
  490: 	    if ($hash{'display_attrs_5'} == 1);
  491: 	$r->print("<td><b>".&mt("Language")."</b></td>\n")
  492: 	    if ($hash{'display_attrs_6'} == 1);
  493: 	$r->print("<td><b>".&mt("Resource")."</b></td>\n")
  494: 	    if ($hash{'display_attrs_7'} == 1);
  495: 	$r->print("<td><b>".&mt("Usage Statistics")." <br />(".
  496: 		  &mt("Courses/Network Hits").")</b></td>\n")
  497: 	    if ($hash{'display_attrs_8'} == 1);
  498: 	$r->print('</tr>');
  499: 
  500: # ----------------- read in what directories have previously been set to "open"
  501: 	foreach (keys %hash) {
  502: 	    if ($_ =~ /^diropen_status_/) {
  503: 		my $key = $_;
  504: 		$key =~ s/^diropen_status_//;
  505: 		$dirs{$key} = $hash{$_};
  506: 	    }
  507: 	}
  508: 
  509: 	if ($ENV{'form.openuri'}) {  # take care of review and refresh options
  510: 	    my $uri=$ENV{'form.openuri'};
  511: 	    if (exists($hash{'diropen_status_'.$uri})) {
  512: 		my $cursta = $hash{'diropen_status_'.$uri};
  513: 		$dirs{$uri} = 'open';
  514: 		$hash{'diropen_status_'.$uri} = 'open';
  515: 		if ($cursta eq 'open') {
  516: 		    $dirs{$uri} = 'closed';
  517: 		    $hash{'diropen_status_'.$uri} = 'closed';
  518: 		}
  519: 	    } else {
  520: 		$hash{'diropen_status_'.$uri} = 'open';
  521: 		$dirs{$uri} = 'open';
  522: 	    }
  523: 	}
  524: 	
  525: 	my $toplevel;
  526: 	my $indent = 0;
  527: 	$uri = $uri.'/' if $uri !~ /.*\/$/;
  528: 
  529:  	if ($ENV{'form.dirPointer'} ne 'on') {
  530:  	    $hash{'top.level'} = $uri;
  531:  	    $toplevel = $uri;
  532:  	} else {
  533:  	    $toplevel = $hash{'top.level'};
  534:  	}
  535: 
  536: # -------------------------------- if not at top level, provide an uplink arrow
  537: 	if ($toplevel ne '/res/'){
  538: 	    my (@uri_com) = split(/\//,$uri);
  539: 	    pop @uri_com;
  540: 	    my $upone = join('/',@uri_com);
  541: 	    my @list = qw (0);
  542: 	    &display_line ($r,'opened',$upone.'&viewOneUp',0,$upone,@list);
  543: 	    $indent = 1;
  544: 	}
  545: 
  546: # -------- recursively go through all the directories and output as appropriate
  547: 	&scanDir ($r,$toplevel,$indent,\%hash);
  548: 	
  549: # ---------------------------- embed hidden information useful for group import
  550: 	$r->print("<form name='fnum'>");
  551: 	$r->print("<input type='hidden' name='fnum' value='$fnum'></form>");
  552: 
  553: # -------------------------------------------------------------- end the tables
  554: 	$r->print('</table>');
  555: 	$r->print('</td></tr></table>');
  556: 
  557: # --------------------------------------------------- end the output and return
  558: 	$r->print('</body></html>'."\n");
  559:     }
  560:     if(! $c->aborted()) {
  561: # write back into the temporary file
  562: 	my %dbfile;
  563:         if (tie(%dbfile,'GDBM_File',$diropendb,&GDBM_NEWDB(),0640)) {
  564:             while (my($key,$value) = each(%hash)) {
  565:                 $dbfile{$key}=$value;
  566:             }
  567:             untie(%dbfile);
  568:         }
  569:     }
  570: 
  571:     return OK;
  572: }
  573: 
  574: # ----------------------------------------------- recursive scan of a directory
  575: sub scanDir {
  576:     my ($r,$startdir,$indent,$hashref)=@_;
  577:     my $c = $r->connection();
  578:     my ($compuri,$curdir);
  579:     my $dirptr=16384;
  580:     my $obs;
  581:     $indent++;
  582:     my %dupdirs = %dirs;
  583:     my @list=&get_list($r,$startdir);
  584:     foreach my $line (@list) {
  585:         return if ($c->aborted());
  586: 	#This is a kludge, sorry aboot this
  587: 	my ($strip,$dom,undef,$testdir,undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,$obs,undef)=split(/\&/,$line,16); 
  588: 	next if($strip =~ /.*\.meta$/ | $obs eq '1');
  589: 	my (@fileparts) = split(/\./,$strip);
  590: 	if ($hash{'display_attrs_9'} != 1) {
  591: # if not all versions to be shown
  592: 	    if (scalar(@fileparts) >= 3) {
  593: 		my $fext = pop @fileparts;
  594: 		my $ov = pop @fileparts;
  595: 		my $fname = join ('.',@fileparts,$fext);
  596: 		next if (grep /\Q$fname\E/,@list and $ov =~ /^\d+$/);
  597: 	    }
  598: 	}
  599: 
  600: 	if ($dom eq 'domain') {
  601: 	    # dom list has full path /res/<domain name>/ already
  602: 	    $curdir='';
  603: 	    $compuri = (split(/\&/,$line))[0];
  604: 	} else {
  605: 	    # user, dir & file have name only, i.e., w/o path
  606: 	    $compuri = join('',$startdir,$strip,'/');
  607: 	    $curdir = $startdir;
  608: 	}
  609: 	my $diropen = 'closed';
  610: 	if (($dirptr&$testdir) or ($dom =~ /^(domain|user)$/) or ($compuri=~/\.(sequence|page)\/$/)) {
  611: 	    while (my ($key,$val)= each %dupdirs) {
  612: 		if ($key eq $compuri and $val eq "open") {
  613: 		    $diropen = "opened";
  614: 		    delete($dupdirs{$key});
  615: 		    delete($dirs{$key});
  616: 		}
  617: 	    }
  618: 	}
  619: 	&display_line($r,$diropen,$line,$indent,$curdir,$hashref,@list);
  620: 	&scanDir ($r,$compuri,$indent) if $diropen eq 'opened';
  621:     }
  622:     $indent--;
  623: }
  624: 
  625: # --------------- get complete matched list based on the uri (returns an array)
  626: sub get_list {
  627:     my ($r,$uri)=@_;
  628:     my @list=();
  629:     (my $luri = $uri) =~ s/\//_/g;
  630:     if ($ENV{'form.updatedisplay'}) {
  631: 	foreach (keys %hash) {
  632: 	    delete $hash{$_} if ($_ =~ /^dirlist_files_/);
  633: 	}
  634:     }
  635: 
  636:     if ($hash{'dirlist_files_'.$luri}) {
  637: 	@list = split(/\n/,$hash{'dirlist_files_'.$luri});
  638:     } elsif ($uri=~/\.(page|sequence)\/$/) {
  639: # is a page or a sequence
  640: 	$uri=~s/\/$//;
  641: 	$uri='/'.(split(/\.(page|sequence)\/\//,$uri))[-1];
  642: 	$uri=~s/\/+/\//g;
  643: 	foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$uri))) {
  644: 	    my @ratpart=split(/\:/,$_);
  645: 	    push @list,$ratpart[1];
  646: 	} 
  647: 	$hash{'dirlist_files_'.$luri} = join("\n",@list);
  648:     } else {
  649: # is really a directory
  650: 	@list = &Apache::lonnet::dirlist($uri);
  651: 	$hash{'dirlist_files_'.$luri} = join("\n",@list);
  652:     }
  653:     return @list=&match_ext($r,@list);
  654: }
  655: 
  656: sub initdebug {
  657:     return <<ENDJS;
  658: <script>
  659: var debugging = true;
  660: if (debugging) {
  661:     var debuggingWindow = window.open('','Debug','width=400,height=300',true);
  662: } 
  663: 
  664: function output(text) {
  665:     if (debugging) {
  666:         debuggingWindow.document.writeln(text);
  667:     }
  668: }
  669: output("<html><head><title>Debugging Window</title></head><body><pre>");   
  670: </script>
  671: ENDJS
  672: }
  673: 
  674: sub writedebug {
  675:     my $text = shift;
  676:     return "<script>output('$text');</script>";
  677: }
  678: 
  679: # -------------------- filters out files based on extensions (returns an array)
  680: sub match_ext {
  681:     my ($r,@packlist)=@_;
  682:     my @trimlist;
  683:     my $nextline;
  684:     my @fileext;
  685:     my $dirptr=16384;
  686: 
  687:     foreach my $line (@packlist) {
  688: 	chomp $line;
  689: 	$line =~ s/^\/home\/httpd\/html//;
  690: 	my @unpackline = split (/\&/,$line);
  691: 	next if ($unpackline[0] eq '.');
  692: 	next if ($unpackline[0] eq '..');
  693: 	my @filecom = split (/\./,$unpackline[0]);
  694: 	my $fext = pop(@filecom);
  695: 	my $fnptr = ($unpackline[3]&$dirptr) || ($fext=~/\.(page|sequence)$/);
  696:  	if ($fnptr == 0 and $unpackline[3] ne "") {
  697: 	    my $embstyle = &Apache::loncommon::fileembstyle($fext);
  698:             push @trimlist,$line if (defined($embstyle) && 
  699: 				     ($embstyle ne 'hdn' or $fext eq 'meta'));
  700: 	} else {
  701: 	    push @trimlist,$line;
  702: 	}
  703:     }
  704:     @trimlist = sort {uc($a) cmp uc($b)} (@trimlist);
  705:     return @trimlist;
  706: }
  707: 
  708: # ------------------------------- displays one line in appropriate table format
  709: sub display_line {
  710:     my ($r,$diropen,$line,$indent,$startdir,$hashref,@list)=@_;
  711:     my (@pathfn, $fndir);
  712: # there could be relative paths (files actually belonging into this directory)
  713: # or absolute paths (for example, from sequences)
  714:     my $absolute;
  715:     my $pathprefix;
  716:     if ($line=~/^\/res\//) {
  717: 	$absolute=1;
  718: 	$pathprefix='';
  719:     } else {
  720: 	$absolute=0;
  721: 	$pathprefix=$startdir;
  722:     }
  723:     my $dirptr=16384;
  724:     my $fileclr="#ffffe6";
  725:     my $iconpath= $r->dir_config('lonIconsURL') . '/';
  726: 
  727:     my @filecom = split (/\&/,$line);
  728:     my @pathcom = split (/\//,$filecom[0]);
  729:     my $listname = $pathcom[scalar(@pathcom)-1];
  730:     my $fnptr = $filecom[3]&$dirptr;
  731:     my $msg = &mt('View').' '.$filecom[0].' '.&mt('resources');
  732:     $msg = &mt('Close').' '.$filecom[0].' '.&mt('directory') if $diropen eq 'opened';
  733: 
  734:     my $tabtag='</td>';
  735:     my $i=0;
  736:     while ($i<=8) {
  737: 	$tabtag=join('',$tabtag,"<td>&nbsp;</td>")
  738: 	    if $hash{'display_attrs_'.$i} == 1;
  739: 	$i++;
  740:     }
  741: 	
  742:     my $valign = ($hash{'display_attrs_7'} == 1 ? 'top' : 'bottom');
  743: 
  744: # display uplink arrow
  745:     if ($filecom[1] eq 'viewOneUp') {
  746: 	my $updir=$startdir;
  747: # -------------- Filter out sequence containment in crumbs and "recent folders"
  748: 	$updir='/'.(split(/\.(page|sequence)\/\//,$startdir))[-1];
  749: 	$updir=~s/\/+/\//g;
  750: 
  751: 	$r->print("<tr valign='$valign' bgcolor=$fileclr>$extrafield");
  752: 	$r->print("<td>\n");
  753: 	$r->print ('<form method="post" name="dirpathUP" action="'.$updir.
  754: 		   '/" '.
  755: 		   'onSubmit="return rep_dirpath(\'UP\','.
  756: 		   'document.forms.fileattr.acts.value)" '.
  757: 		   'enctype="application/x-www-form-urlencoded"'.
  758:                    '>'."\n");
  759: 	$r->print ('<input type=hidden name=openuri value="'.
  760: 		   $startdir.'">'."\n");
  761: 	$r->print ('<input type="hidden" name="acts" value="">'."\n");
  762: 	$r->print ('<input src="'.$iconpath.'arrow_up.gif"');
  763: 	$r->print (' name="'.$msg.'" height="22" type="image" border="0">'.
  764: 		   "\n");
  765: 	$r->print(&mt("Up")." $tabtag</tr></form>\n");
  766: 	return OK;
  767:     }
  768: # Do we have permission to look at this?
  769: 
  770:     if($filecom[15] ne '1') { return OK if (!&Apache::lonnet::allowed('bre',$pathprefix.$filecom[0])); }
  771: 
  772: # make absolute links appear on different background
  773:     if ($absolute) { $fileclr='#aaaa88'; }
  774: 
  775: # display domain
  776:     if ($filecom[1] eq 'domain') {
  777:  	$r->print ('<input type="hidden" name="dirPointer" value="on">'."\n")
  778:  	    if ($ENV{'form.dirPointer'} eq "on");
  779: 	$r->print("<tr valign='$valign' bgcolor=$fileclr>$extrafield");
  780: 	$r->print("<td>");
  781: 	&begin_form ($r,$filecom[0]);
  782: 	my $anchor = $filecom[0];
  783: 	$anchor =~ s/\///g;
  784: 	$r->print ('<a name="'.$anchor.'">');
  785: 	$r->print ('<input type="hidden" name="acts" value="">');
  786: 	$r->print ('<input src="'.$iconpath.'folder_pointer_'.
  787: 		   $diropen.'.gif"'); 
  788: 	$r->print (' name="'.$msg.'" height="22" type="image" border="0">'.
  789: 		   "\n");
  790: 	$r->print ('<a href="javascript:gothere(\''.$filecom[0].
  791: 		   '\')"><img src="'.$iconpath.'server.gif"');
  792: 	$r->print (' border="0" /></a>'."\n");
  793: 	$r->print (&mt("Domain")." - $listname ");
  794: 	if ($Apache::lonnet::domaindescription{$listname}) {
  795: 	    $r->print("(".$Apache::lonnet::domaindescription{$listname}.
  796: 		      ")");
  797: 	}
  798: 	$r->print (" $tabtag</tr></form>\n");
  799: 	return OK;
  800: 
  801: # display user directory
  802:     }
  803:     if ($filecom[1] eq 'user') {
  804: 	$r->print("<tr valign=$valign bgcolor=$fileclr>$extrafield");
  805: 	$r->print("<td nowrap>\n");
  806: 	my $curdir = $startdir.$filecom[0].'/';
  807: 	my $anchor = $curdir;
  808: 	$anchor =~ s/\///g;
  809: 	&begin_form ($r,$curdir);
  810: 	$r->print ('<a name="'.$anchor.'"><img src="'.$iconpath.
  811: 		   'whitespace1.gif" border="0" />'."\n");
  812: 	$r->print ('<input type="hidden" name="acts" value="">');
  813: 	$r->print ('<input src="'.$iconpath.'folder_pointer_'.$diropen.
  814: 		   '.gif"'); 
  815: 	$r->print (' name="'.$msg.'" height="22" type="image" border="0">'.
  816: 		   "\n");
  817: 	$r->print ('<a href="javascript:gothere(\''.$curdir.'\')"><img src='.
  818: 		   $iconpath.'quill.gif border="0" name="'.$msg.
  819: 		   '" height="22" /></a>');
  820: 	my $domain=(split(m|/|,$startdir))[2];
  821: 	my $plainname=&Apache::loncommon::plainname($listname,$domain);
  822: 	$r->print ($listname);
  823: 	if (defined($plainname) && $plainname) { $r->print(" ($plainname) "); }
  824: 	$r->print ($tabtag.'</tr></form>'."\n");
  825: 	return OK;
  826:     }
  827: 
  828: # display file
  829:     if (($fnptr == 0 and $filecom[3] ne '') or $absolute) {
  830: 	my $filelink = $pathprefix.$filecom[0];
  831: 	my @file_ext = split (/\./,$listname);
  832: 	my $curfext = $file_ext[-1];
  833:         if (@Omit) {
  834:             foreach (@Omit) { return OK if ($curfext eq $_); }
  835:         }
  836:         if (@Only) {
  837:             my $skip = 1;
  838:             foreach (@Only) { $skip = 0 if ($curfext eq $_); }
  839:             return OK if ($skip > 0);
  840:         }
  841: 	# Set the icon for the file
  842: 	my $iconname = &Apache::loncommon::icon($listname);
  843: 	$r->print("<tr valign='$valign' bgcolor=$fileclr><td nowrap>");
  844: 	my $metafile = grep /^\Q$filecom[0]\E\.meta\&/, @list;
  845: #	my $metafile=1;
  846: 	my $title;
  847:         if ($ENV{'form.catalogmode'} eq 'interactive') {
  848: 	    $title=$listname;
  849: 	    $title = &Apache::lonnet::metadata($filelink,'title')
  850: 		if ($metafile == 1);
  851: 	    $title=$listname unless $title;
  852: 	    my $titleesc=HTML::Entities::encode($title,'<>&"');
  853: 	    $titleesc=~s/\'/\\'/; #' (clean up this spare quote)
  854:             $r->print("<a href=\"javascript:select_data(\'",
  855:                       $titleesc,"','",$filelink,"')\">");
  856: 	    $r->print("<img src='",$iconpath,"select.gif' border='0' /></a>".
  857: 		      "\n");
  858: 	    $r->print("</td><td nowrap>");
  859: 	} elsif ($ENV{'form.catalogmode'} eq 'groupimport') {
  860: 	    $title=$listname;
  861: 	    $title = &Apache::lonnet::metadata($filelink,'title')
  862: 		if ($metafile == 1);
  863: 		$title=$listname unless $title;
  864: 	    my $titleesc=&HTML::Entities::encode($title,'<>&"');
  865: 	    $r->print("<form name='form$fnum'>\n");
  866: 	    $r->print("<input type='checkbox' name='filelink"."' ".
  867: 		      "value='$filelink' onClick='".
  868: 		      "javascript:queue(\"form$fnum\")' ");
  869: 	    if ($hash{'store_'.$filelink}) {
  870: 		$r->print("checked");
  871: 	    }
  872: 	    $r->print(">\n");
  873: 	    $r->print("<input type='hidden' name='title"."' ".
  874: 		      "value='$titleesc'>\n");
  875: 	    $r->print("</form>\n");
  876: 	    $r->print("</td><td nowrap>");
  877: 	    $hash{"pre_${fnum}_link"}=$filelink;
  878: 	    $hash{"pre_${fnum}_title"}=$titleesc;
  879:   	    $fnum++;
  880: 	}
  881: # Form to open or close sequences
  882: 	if ($filelink=~/\.(page|sequence)$/) {
  883: 	    my $curdir = $startdir.$filecom[0].'/';
  884: 	    my $anchor = $curdir;
  885: 	    $anchor =~ s/\///g;
  886: 	    &begin_form($r,$curdir);
  887: 	    $indent--;
  888: 	}
  889: # General indentation
  890: 	if ($indent > 0 and $indent < 11) {
  891: 	    $r->print("<img src=",$iconpath,"whitespace",$indent,
  892: 		      ".gif border='0' />\n");
  893: 	} elsif ($indent >0) {
  894: 	    my $ten = int($indent/10.);
  895: 	    my $rem = $indent%10.0;
  896: 	    my $count = 0;
  897: 	    while ($count < $ten) {
  898: 		$r->print("<img src=",$iconpath,
  899: 			  "whitespace10.gif border='0' />\n");
  900: 	    $count++;
  901: 	    }
  902: 	    $r->print("<img src=",$iconpath,"whitespace",$rem,
  903: 		      ".gif border='0' />\n") if $rem > 0;
  904: 	}
  905: # Sequence open/close icon
  906: 	if ($filelink=~/\.(page|sequence)$/) {
  907: 	    my $curdir = $startdir.$filecom[0].'/';
  908: 	    my $anchor = $curdir;
  909: 	    $anchor =~ s/\///g;
  910: 	    $r->print ('<input type="hidden" name="acts" value="">');
  911: 	    $r->print ('<a name="'.$anchor.'"><input src="'.$iconpath.
  912: 		       'folder_pointer_'.$diropen.'.gif"');
  913: 	    $r->print (' name="'.$msg.'" height="22" type="image" border="0">'.
  914: 		       "\n");
  915: 	}
  916: # Filetype icons
  917: 	$r->print("<img src='$iconname' border='0' />\n");
  918: # Close form to open/close sequence
  919: 	if ($filelink=~/\.(page|sequence)$/) {
  920: 	    $r->print('</form>');
  921: 	}
  922: 	$r->print (" <a href=\"javascript:openWindow('".$filelink.
  923: 		   "', 'previewfile', '450', '500', 'no', 'yes','yes')\";".
  924: 		   " TARGET=_self>$listname</a> ");
  925: 
  926: 	$r->print (" (<a href=\"javascript:openWindow('".$filelink.
  927: 		   ".meta', 'metadatafile', '500', '550', 'no', 'yes','no')\"; ".
  928: 		   "TARGET=_self>metadata</a>) ") if ($metafile == 1);
  929: 
  930: 	$r->print("</td>\n");
  931: 	if ($hash{'display_attrs_0'} == 1) {
  932: 	    my $title = &Apache::lonnet::gettitle($filelink,'title')
  933: 		if ($metafile == 1);
  934: 	    $r->print('<td> '.($title eq '' ? '&nbsp;' : $title).
  935: 		      ' </td>'."\n");
  936: 	}
  937: 	$r->print('<td align=right> ',
  938: 		  $filecom[8]," </td>\n") 
  939: 	    if $hash{'display_attrs_1'} == 1;
  940: 	$r->print('<td> '.
  941: 		  (localtime($filecom[9]))." </td>\n") 
  942: 	    if $hash{'display_attrs_2'} == 1;
  943: 	$r->print('<td> '.
  944: 		  (localtime($filecom[10]))." </td>\n") 
  945: 	    if $hash{'display_attrs_3'} == 1;
  946: 
  947: 	if ($hash{'display_attrs_4'} == 1) {
  948: 	    my $author = &Apache::lonnet::metadata($filelink,'author')
  949: 		if ($metafile == 1);
  950: 	    $r->print('<td> '.($author eq '' ? '&nbsp;' : $author).
  951: 		      " </td>\n");
  952: 	}
  953: 	if ($hash{'display_attrs_5'} == 1) {
  954: 	    my $keywords = &Apache::lonnet::metadata($filelink,'keywords')
  955: 		if ($metafile == 1);
  956: 	    # $keywords = '&nbsp;' if (!$keywords);
  957: 	    $r->print('<td> '.($keywords eq '' ? '&nbsp;' : $keywords).
  958: 		      " </td>\n");
  959: 	}
  960: 	if ($hash{'display_attrs_6'} == 1) {
  961: 	    my $lang = &Apache::lonnet::metadata($filelink,'language')
  962: 		if ($metafile == 1);
  963: 	    $lang = &Apache::loncommon::languagedescription($lang);
  964: 	    $r->print('<td> '.($lang eq '' ? '&nbsp;' : $lang).
  965: 		      " </td>\n");
  966: 	}
  967:         if ($hash{'display_attrs_7'} == 1) {
  968:             my $output='';
  969:             my $embstyle=&Apache::loncommon::fileembstyle($curfext);
  970: 	    if ($embstyle eq 'ssi') {
  971: 		my $cache=$Apache::lonnet::perlvar{'lonDocRoot'}.$filelink.
  972: 		    '.tmp';
  973: 		if ((!$ENV{'form.updatedisplay'}) &&
  974: 		    (-e $cache)) {
  975: 		    open(FH,$cache);
  976: 		    $output=join("\n",<FH>);
  977: 		    close(FH);
  978: 		} else {
  979: 		    $output=&Apache::lonnet::ssi_body($filelink);
  980: 		    open(FH,">$cache");
  981: 		    print FH $output;
  982: 		    close(FH);
  983: 		}
  984: 		$output='<font size="-2">'.$output.'</font>';
  985: 	   } elsif ($embstyle eq 'img') {
  986:                $output='<img src="'.$filelink.'" />';
  987:            } elsif ($filelink=~/^\/res\/(\w+)\/(\w+)\//) {
  988:                $output='<img src="http://'.
  989: 		 $Apache::lonnet::hostname{&Apache::lonnet::homeserver($2,$1)}.
  990:                  '/cgi-bin/thumbnail.gif?url='.$filelink.'" />';
  991:            }
  992: 	   $r->print('<td> '.($output eq '' ? '&nbsp;':$output).
  993: 		      " </td>\n");
  994:         }
  995: 	if ($hash{'display_attrs_8'} == 1) {
  996: 	    my (%stat) = &Apache::lonmeta::dynamicmeta($filelink) if ($metafile == 1);
  997: 	    my $stat = (exists($stat{'course'}) ? $stat{'course'} : '').
  998: 		((exists($stat{'course'}) || exists($stat{'count'})) ? '/' : '').
  999: 		(exists($stat{'count'}) ? $stat{'count'} : '');
 1000: 	    $r->print('<td align=center> '.($stat eq '' ? '&nbsp;' : $stat).
 1001: 		      ' </td>'."\n");
 1002: 	}
 1003: 
 1004: 	$r->print("</tr>\n");
 1005:     }
 1006: 
 1007: # -- display directory
 1008:     if ($fnptr == $dirptr) {
 1009: 	my $curdir = $startdir.$filecom[0].'/';
 1010: 	my $anchor = $curdir;
 1011: 	$anchor =~ s/\///g;
 1012: 	$r->print("<tr bgcolor=$fileclr>$extrafield<td valign=$valign>");
 1013: 	&begin_form ($r,$curdir);
 1014: 	my $indentm1 = $indent-1;
 1015: 	if ($indentm1 < 11 and $indentm1 > 0) {
 1016: 	    $r->print("<img src=",$iconpath,"whitespace",$indentm1,
 1017: 		      ".gif border='0' />\n");
 1018: 	} else {
 1019: 	    my $ten = int($indentm1/10.);
 1020: 	    my $rem = $indentm1%10.0;
 1021: 	    my $count = 0;
 1022: 	    while ($count < $ten) {
 1023: 		$r->print ("<img src=",$iconpath
 1024: 			   ,"whitespace10.gif border='0' />\n");
 1025: 		$count++;
 1026: 	    }
 1027: 	    $r->print ("<img src=",$iconpath,"whitespace",$rem,
 1028: 		       ".gif border='0' />\n") if $rem > 0;
 1029: 	}
 1030: 	$r->print ('<input type="hidden" name="acts" value="">');
 1031: 	$r->print ('<a name="'.$anchor.'"><input src="'.$iconpath.
 1032: 		   'folder_pointer_'.$diropen.'.gif"');
 1033: 	$r->print (' name="'.$msg.'" height="22" type="image" border="0">'.
 1034: 		   "\n");
 1035: 	$r->print ('<a href="javascript:gothere(\''.$curdir.'\')"><img src="'.
 1036: 		   $iconpath.'folder_'.$diropen.'.gif" border="0" /></a>'.
 1037: 		   "\n");
 1038: 	$r->print ("$listname</td>\n");
 1039: # Attributes
 1040: 	my $filelink = $startdir.$filecom[0].'/default';
 1041: 
 1042: 	if ($hash{'display_attrs_0'} == 1) {
 1043: 	    my $title = &Apache::lonnet::gettitle($filelink,'title');
 1044: 	    $r->print('<td> '.($title eq '' ? '&nbsp;' : $title).
 1045: 		      ' </td>'."\n");
 1046: 	}
 1047: 	$r->print('<td align=right> ',
 1048: 		  $filecom[8]," </td>\n") 
 1049: 	    if $hash{'display_attrs_1'} == 1;
 1050: 	$r->print('<td> '.
 1051: 		  (localtime($filecom[9]))." </td>\n") 
 1052: 	    if $hash{'display_attrs_2'} == 1;
 1053: 	$r->print('<td> '.
 1054: 		  (localtime($filecom[10]))." </td>\n") 
 1055: 	    if $hash{'display_attrs_3'} == 1;
 1056: 
 1057: 	if ($hash{'display_attrs_4'} == 1) {
 1058: 	    my $author = &Apache::lonnet::metadata($filelink,'author');
 1059: 	    $r->print('<td> '.($author eq '' ? '&nbsp;' : $author).
 1060: 		      " </td>\n");
 1061: 	}
 1062: 	if ($hash{'display_attrs_5'} == 1) {
 1063: 	    my $keywords = &Apache::lonnet::metadata($filelink,'keywords');
 1064: 	    # $keywords = '&nbsp;' if (!$keywords);
 1065: 	    $r->print('<td> '.($keywords eq '' ? '&nbsp;' : $keywords).
 1066: 		      " </td>\n");
 1067: 	}
 1068: 	if ($hash{'display_attrs_6'} == 1) {
 1069: 	    my $lang = &Apache::lonnet::metadata($filelink,'language');
 1070: 	    $lang = &Apache::loncommon::languagedescription($lang);
 1071: 	    $r->print('<td> '.($lang eq '' ? '&nbsp;' : $lang).
 1072: 		      " </td>\n");
 1073: 	}
 1074:         if ($hash{'display_attrs_7'} == 1) {
 1075: 	   $r->print('<td>&nbsp;</td>');
 1076:         }
 1077: 	if ($hash{'display_attrs_8'} == 1) {
 1078: 	   $r->print('<td>&nbsp;</td>');
 1079: 	}
 1080: 	$r->print('</form></tr>');
 1081:     }
 1082: 
 1083: }
 1084: 
 1085: # ------------------- prints the beginning of a form for directory or file link
 1086: sub begin_form {
 1087:     my ($r,$uri) = @_;
 1088:     my $anchor = $uri;
 1089:     $anchor =~ s/\///g;
 1090:     $r->print ('<form method="post" name="dirpath'.$dnum.'" action="'.$uri.
 1091: 	       '#'.$anchor.
 1092: 	       '" onSubmit="return rep_dirpath(\''.$dnum.'\''.
 1093: 	       ',document.forms.fileattr.acts.value)" '.
 1094: 	       'enctype="application/x-www-form-urlencoded">'."\n");
 1095:     $r->print ('<input type="hidden" name="openuri" value="'.$uri.'">'.
 1096: 	       "\n");
 1097:     $r->print ('<input type="hidden" name="dirPointer" value="on">'."\n");
 1098:     $dnum++;
 1099: }
 1100: 
 1101: # --------- settings whenever the user causes the indexer window to be launched
 1102: sub start_fresh_session {
 1103:     delete $hash{'form.catalogmode'};
 1104:     delete $hash{'form.mode'};
 1105:     delete $hash{'form.form'};
 1106:     delete $hash{'form.element'};
 1107:     delete $hash{'form.omit'};
 1108:     delete $hash{'form.only'};
 1109:     foreach (keys %hash) {
 1110:         delete $hash{$_} if (/^(pre_|store)/);
 1111:     }
 1112: }
 1113: 
 1114: # ------------------------------------------------------------------- setvalues
 1115: sub setvalues {
 1116:     # setvalues is used in registerurl to synchronize the database
 1117:     # hash and environment hashes
 1118:     my ($H1,$h1key,$H2,$h2key) =@_;
 1119:     #
 1120:     if (exists $H2->{$h2key}) {
 1121: 	$H1->{$h1key} = $H2->{$h2key};
 1122:     } elsif (exists $H1->{$h1key}) {
 1123: 	$H2->{$h2key} = $H1->{$h1key};
 1124:     } 
 1125: }
 1126: 
 1127: 1;
 1128: 
 1129: sub cleanup {
 1130:     if (tied(%hash)){
 1131: 	&Apache::lonnet::logthis('Cleanup indexer: hash');
 1132:     }
 1133: }
 1134: 
 1135: =head1 NAME
 1136: 
 1137: Apache::lonindexer - mod_perl module for cross server filesystem browsing
 1138: 
 1139: =head1 SYNOPSIS
 1140: 
 1141: Invoked by /etc/httpd/conf/srm.conf:
 1142: 
 1143:  <LocationMatch "^/res.*/$">
 1144:  SetHandler perl-script
 1145:  PerlHandler Apache::lonindexer
 1146:  </LocationMatch>
 1147: 
 1148: =head1 INTRODUCTION
 1149: 
 1150: This module enables a scheme of browsing across a cross server.
 1151: 
 1152: This is part of the LearningOnline Network with CAPA project
 1153: described at http://www.lon-capa.org.
 1154: 
 1155: =head1 BEGIN SUBROUTINE
 1156: 
 1157: This routine is only run once after compilation.
 1158: 
 1159: =over 4
 1160: 
 1161: =item *
 1162: 
 1163: Initializes %language hash table.
 1164: 
 1165: =back
 1166: 
 1167: =head1 HANDLER SUBROUTINE
 1168: 
 1169: This routine is called by Apache and mod_perl.
 1170: 
 1171: =over 4
 1172: 
 1173: =item *
 1174: 
 1175: read in machine configuration variables
 1176: 
 1177: =item *
 1178: 
 1179: see if called from an interactive mode
 1180: 
 1181: =item *
 1182: 
 1183: refresh environment with user database values (in %hash)
 1184: 
 1185: =item *
 1186: 
 1187: define extra fields and buttons in case of special mode
 1188: 
 1189: =item *
 1190: 
 1191: set catalogmodefunctions to have extra needed javascript functionality
 1192: 
 1193: =item *
 1194: 
 1195: print header
 1196: 
 1197: =item *
 1198: 
 1199: evaluate actions from previous page (both cumulatively and chronologically)
 1200: 
 1201: =item *
 1202: 
 1203: output title
 1204: 
 1205: =item *
 1206: 
 1207: get state of file attributes to be showing
 1208: 
 1209: =item *
 1210: 
 1211: output state of file attributes to be showing
 1212: 
 1213: =item *
 1214: 
 1215: output starting row to the indexed file/directory hierarchy
 1216: 
 1217: =item *
 1218: 
 1219: read in what directories have previously been set to "open"
 1220: 
 1221: =item *
 1222: 
 1223: if not at top level, provide an uplink arrow
 1224: 
 1225: =item *
 1226: 
 1227: recursively go through all the directories and output as appropriate
 1228: 
 1229: =item *
 1230: 
 1231: information useful for group import
 1232: 
 1233: =item *
 1234: 
 1235: end the tables
 1236: 
 1237: =item *
 1238: 
 1239: end the output and return
 1240: 
 1241: =back
 1242: 
 1243: =head1 OTHER SUBROUTINES
 1244: 
 1245: =over 4
 1246: 
 1247: =item *
 1248: 
 1249: scanDir - recursive scan of a directory
 1250: 
 1251: =item *
 1252: 
 1253: get_list - get complete matched list based on the uri (returns an array)
 1254: 
 1255: =item *
 1256: 
 1257: match_ext - filters out files based on extensions (returns an array)
 1258: 
 1259: =item *
 1260: 
 1261: display_line - displays one line in appropriate table format
 1262: 
 1263: =item *
 1264: 
 1265: begin_form - prints the beginning of a form for directory or file link
 1266: 
 1267: =item *
 1268: 
 1269: start_fresh_session - settings whenever the user causes the indexer window
 1270: to be launched
 1271: 
 1272: =back
 1273: 
 1274: =cut

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