File:
[LON-CAPA] /
loncom /
interface /
lonindexer.pm
Revision
1.104:
download - view:
text,
annotated -
select for diffs
Tue May 11 05:19:30 2004 UTC (20 years, 3 months ago) by
albertel
Branches:
MAIN
CVS tags:
HEAD
- this properly handles the metadata avoidance to speed things up
it now
1) checks if the metadata file already exists, if it does, it always loads the metadata up for that file
2) if the user is browsing with a metadata field display turned on (stats/title) it always replicates/loads up the metadata for that file
3) it always provides the link to the metadata
- this means in the simplest case (no metadata display turned on) (just wandering around)
no data is replicated, but in all cases where metadata is desired to be shown it is shown and is replicated.
1: # The LearningOnline Network with CAPA
2: # Directory Indexer
3: #
4: # $Id: lonindexer.pm,v 1.104 2004/05/11 05:19:30 albertel 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> </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> </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:
845: my $metafile = $Apache::lonnet::perlvar{'lonDocRoot'}.$pathprefix.
846: $filecom[0].'.meta';
847: if (-e $metafile) {
848: $metafile=1;
849: } else {
850: $metafile=0;
851: }
852: my $title;
853: if ($ENV{'form.catalogmode'} eq 'interactive') {
854: $title=$listname;
855: $title = &Apache::lonnet::metadata($filelink,'title')
856: if ($metafile == 1);
857: $title=$listname unless $title;
858: my $titleesc=HTML::Entities::encode($title,'<>&"');
859: $titleesc=~s/\'/\\'/; #' (clean up this spare quote)
860: $r->print("<a href=\"javascript:select_data(\'",
861: $titleesc,"','",$filelink,"')\">");
862: $r->print("<img src='",$iconpath,"select.gif' border='0' /></a>".
863: "\n");
864: $r->print("</td><td nowrap>");
865: } elsif ($ENV{'form.catalogmode'} eq 'groupimport') {
866: $title=$listname;
867: $title = &Apache::lonnet::metadata($filelink,'title')
868: if ($metafile == 1);
869: $title=$listname unless $title;
870: my $titleesc=&HTML::Entities::encode($title,'<>&"');
871: $r->print("<form name='form$fnum'>\n");
872: $r->print("<input type='checkbox' name='filelink"."' ".
873: "value='$filelink' onClick='".
874: "javascript:queue(\"form$fnum\")' ");
875: if ($hash{'store_'.$filelink}) {
876: $r->print("checked");
877: }
878: $r->print(">\n");
879: $r->print("<input type='hidden' name='title"."' ".
880: "value='$titleesc'>\n");
881: $r->print("</form>\n");
882: $r->print("</td><td nowrap>");
883: $hash{"pre_${fnum}_link"}=$filelink;
884: $hash{"pre_${fnum}_title"}=$titleesc;
885: $fnum++;
886: }
887: # Form to open or close sequences
888: if ($filelink=~/\.(page|sequence)$/) {
889: my $curdir = $startdir.$filecom[0].'/';
890: my $anchor = $curdir;
891: $anchor =~ s/\///g;
892: &begin_form($r,$curdir);
893: $indent--;
894: }
895: # General indentation
896: if ($indent > 0 and $indent < 11) {
897: $r->print("<img src=",$iconpath,"whitespace",$indent,
898: ".gif border='0' />\n");
899: } elsif ($indent >0) {
900: my $ten = int($indent/10.);
901: my $rem = $indent%10.0;
902: my $count = 0;
903: while ($count < $ten) {
904: $r->print("<img src=",$iconpath,
905: "whitespace10.gif border='0' />\n");
906: $count++;
907: }
908: $r->print("<img src=",$iconpath,"whitespace",$rem,
909: ".gif border='0' />\n") if $rem > 0;
910: }
911: # Sequence open/close icon
912: if ($filelink=~/\.(page|sequence)$/) {
913: my $curdir = $startdir.$filecom[0].'/';
914: my $anchor = $curdir;
915: $anchor =~ s/\///g;
916: $r->print ('<input type="hidden" name="acts" value="">');
917: $r->print ('<a name="'.$anchor.'"><input src="'.$iconpath.
918: 'folder_pointer_'.$diropen.'.gif"');
919: $r->print (' name="'.$msg.'" height="22" type="image" border="0">'.
920: "\n");
921: }
922: # Filetype icons
923: $r->print("<img src='$iconname' border='0' />\n");
924: # Close form to open/close sequence
925: if ($filelink=~/\.(page|sequence)$/) {
926: $r->print('</form>');
927: }
928: $r->print (" <a href=\"javascript:openWindow('".$filelink.
929: "', 'previewfile', '450', '500', 'no', 'yes','yes')\";".
930: " TARGET=_self>$listname</a> ");
931:
932: $r->print (" (<a href=\"javascript:openWindow('".$filelink.
933: ".meta', 'metadatafile', '500', '550', 'no', 'yes','no')\"; ".
934: "TARGET=_self>metadata</a>) ");
935: $r->print("</td>\n");
936: if ($hash{'display_attrs_0'} == 1) {
937: my $title = &Apache::lonnet::gettitle($filelink,'title');
938: $r->print('<td> '.($title eq '' ? ' ' : $title).
939: ' </td>'."\n");
940: }
941: $r->print('<td align=right> ',
942: $filecom[8]," </td>\n")
943: if $hash{'display_attrs_1'} == 1;
944: $r->print('<td> '.
945: (localtime($filecom[9]))." </td>\n")
946: if $hash{'display_attrs_2'} == 1;
947: $r->print('<td> '.
948: (localtime($filecom[10]))." </td>\n")
949: if $hash{'display_attrs_3'} == 1;
950:
951: if ($hash{'display_attrs_4'} == 1) {
952: my $author = &Apache::lonnet::metadata($filelink,'author');
953: $r->print('<td> '.($author eq '' ? ' ' : $author).
954: " </td>\n");
955: }
956: if ($hash{'display_attrs_5'} == 1) {
957: my $keywords = &Apache::lonnet::metadata($filelink,'keywords');
958: # $keywords = ' ' if (!$keywords);
959: $r->print('<td> '.($keywords eq '' ? ' ' : $keywords).
960: " </td>\n");
961: }
962: if ($hash{'display_attrs_6'} == 1) {
963: my $lang = &Apache::lonnet::metadata($filelink,'language');
964: $lang = &Apache::loncommon::languagedescription($lang);
965: $r->print('<td> '.($lang eq '' ? ' ' : $lang).
966: " </td>\n");
967: }
968: if ($hash{'display_attrs_7'} == 1) {
969: my $output='';
970: my $embstyle=&Apache::loncommon::fileembstyle($curfext);
971: if ($embstyle eq 'ssi') {
972: my $cache=$Apache::lonnet::perlvar{'lonDocRoot'}.$filelink.
973: '.tmp';
974: if ((!$ENV{'form.updatedisplay'}) &&
975: (-e $cache)) {
976: open(FH,$cache);
977: $output=join("\n",<FH>);
978: close(FH);
979: } else {
980: $output=&Apache::lonnet::ssi_body($filelink);
981: open(FH,">$cache");
982: print FH $output;
983: close(FH);
984: }
985: $output='<font size="-2">'.$output.'</font>';
986: } elsif ($embstyle eq 'img') {
987: $output='<img src="'.$filelink.'" />';
988: } elsif ($filelink=~/^\/res\/(\w+)\/(\w+)\//) {
989: $output='<img src="http://'.
990: $Apache::lonnet::hostname{&Apache::lonnet::homeserver($2,$1)}.
991: '/cgi-bin/thumbnail.gif?url='.$filelink.'" />';
992: }
993: $r->print('<td> '.($output eq '' ? ' ':$output).
994: " </td>\n");
995: }
996: if ($hash{'display_attrs_8'} == 1) {
997: my (%stat) = &Apache::lonmeta::dynamicmeta($filelink);
998: my $stat = (exists($stat{'course'}) ? $stat{'course'} : '').
999: ((exists($stat{'course'}) || exists($stat{'count'})) ? '/' : '').
1000: (exists($stat{'count'}) ? $stat{'count'} : '');
1001: $r->print('<td align=center> '.($stat eq '' ? ' ' : $stat).
1002: ' </td>'."\n");
1003: }
1004:
1005: $r->print("</tr>\n");
1006: }
1007:
1008: # -- display directory
1009: if ($fnptr == $dirptr) {
1010: my $curdir = $startdir.$filecom[0].'/';
1011: my $anchor = $curdir;
1012: $anchor =~ s/\///g;
1013: $r->print("<tr bgcolor=$fileclr>$extrafield<td valign=$valign>");
1014: &begin_form ($r,$curdir);
1015: my $indentm1 = $indent-1;
1016: if ($indentm1 < 11 and $indentm1 > 0) {
1017: $r->print("<img src=",$iconpath,"whitespace",$indentm1,
1018: ".gif border='0' />\n");
1019: } else {
1020: my $ten = int($indentm1/10.);
1021: my $rem = $indentm1%10.0;
1022: my $count = 0;
1023: while ($count < $ten) {
1024: $r->print ("<img src=",$iconpath
1025: ,"whitespace10.gif border='0' />\n");
1026: $count++;
1027: }
1028: $r->print ("<img src=",$iconpath,"whitespace",$rem,
1029: ".gif border='0' />\n") if $rem > 0;
1030: }
1031: $r->print ('<input type="hidden" name="acts" value="">');
1032: $r->print ('<a name="'.$anchor.'"><input src="'.$iconpath.
1033: 'folder_pointer_'.$diropen.'.gif"');
1034: $r->print (' name="'.$msg.'" height="22" type="image" border="0">'.
1035: "\n");
1036: $r->print ('<a href="javascript:gothere(\''.$curdir.'\')"><img src="'.
1037: $iconpath.'folder_'.$diropen.'.gif" border="0" /></a>'.
1038: "\n");
1039: $r->print ("$listname</td>\n");
1040: # Attributes
1041: my $filelink = $startdir.$filecom[0].'/default';
1042:
1043: if ($hash{'display_attrs_0'} == 1) {
1044: my $title = &Apache::lonnet::gettitle($filelink,'title');
1045: $r->print('<td> '.($title eq '' ? ' ' : $title).
1046: ' </td>'."\n");
1047: }
1048: $r->print('<td align=right> ',
1049: $filecom[8]," </td>\n")
1050: if $hash{'display_attrs_1'} == 1;
1051: $r->print('<td> '.
1052: (localtime($filecom[9]))." </td>\n")
1053: if $hash{'display_attrs_2'} == 1;
1054: $r->print('<td> '.
1055: (localtime($filecom[10]))." </td>\n")
1056: if $hash{'display_attrs_3'} == 1;
1057:
1058: if ($hash{'display_attrs_4'} == 1) {
1059: my $author = &Apache::lonnet::metadata($filelink,'author');
1060: $r->print('<td> '.($author eq '' ? ' ' : $author).
1061: " </td>\n");
1062: }
1063: if ($hash{'display_attrs_5'} == 1) {
1064: my $keywords = &Apache::lonnet::metadata($filelink,'keywords');
1065: # $keywords = ' ' if (!$keywords);
1066: $r->print('<td> '.($keywords eq '' ? ' ' : $keywords).
1067: " </td>\n");
1068: }
1069: if ($hash{'display_attrs_6'} == 1) {
1070: my $lang = &Apache::lonnet::metadata($filelink,'language');
1071: $lang = &Apache::loncommon::languagedescription($lang);
1072: $r->print('<td> '.($lang eq '' ? ' ' : $lang).
1073: " </td>\n");
1074: }
1075: if ($hash{'display_attrs_7'} == 1) {
1076: $r->print('<td> </td>');
1077: }
1078: if ($hash{'display_attrs_8'} == 1) {
1079: $r->print('<td> </td>');
1080: }
1081: $r->print('</form></tr>');
1082: }
1083:
1084: }
1085:
1086: # ------------------- prints the beginning of a form for directory or file link
1087: sub begin_form {
1088: my ($r,$uri) = @_;
1089: my $anchor = $uri;
1090: $anchor =~ s/\///g;
1091: $r->print ('<form method="post" name="dirpath'.$dnum.'" action="'.$uri.
1092: '#'.$anchor.
1093: '" onSubmit="return rep_dirpath(\''.$dnum.'\''.
1094: ',document.forms.fileattr.acts.value)" '.
1095: 'enctype="application/x-www-form-urlencoded">'."\n");
1096: $r->print ('<input type="hidden" name="openuri" value="'.$uri.'">'.
1097: "\n");
1098: $r->print ('<input type="hidden" name="dirPointer" value="on">'."\n");
1099: $dnum++;
1100: }
1101:
1102: # --------- settings whenever the user causes the indexer window to be launched
1103: sub start_fresh_session {
1104: delete $hash{'form.catalogmode'};
1105: delete $hash{'form.mode'};
1106: delete $hash{'form.form'};
1107: delete $hash{'form.element'};
1108: delete $hash{'form.omit'};
1109: delete $hash{'form.only'};
1110: foreach (keys %hash) {
1111: delete $hash{$_} if (/^(pre_|store)/);
1112: }
1113: }
1114:
1115: # ------------------------------------------------------------------- setvalues
1116: sub setvalues {
1117: # setvalues is used in registerurl to synchronize the database
1118: # hash and environment hashes
1119: my ($H1,$h1key,$H2,$h2key) =@_;
1120: #
1121: if (exists $H2->{$h2key}) {
1122: $H1->{$h1key} = $H2->{$h2key};
1123: } elsif (exists $H1->{$h1key}) {
1124: $H2->{$h2key} = $H1->{$h1key};
1125: }
1126: }
1127:
1128: 1;
1129:
1130: sub cleanup {
1131: if (tied(%hash)){
1132: &Apache::lonnet::logthis('Cleanup indexer: hash');
1133: }
1134: }
1135:
1136: =head1 NAME
1137:
1138: Apache::lonindexer - mod_perl module for cross server filesystem browsing
1139:
1140: =head1 SYNOPSIS
1141:
1142: Invoked by /etc/httpd/conf/srm.conf:
1143:
1144: <LocationMatch "^/res.*/$">
1145: SetHandler perl-script
1146: PerlHandler Apache::lonindexer
1147: </LocationMatch>
1148:
1149: =head1 INTRODUCTION
1150:
1151: This module enables a scheme of browsing across a cross server.
1152:
1153: This is part of the LearningOnline Network with CAPA project
1154: described at http://www.lon-capa.org.
1155:
1156: =head1 BEGIN SUBROUTINE
1157:
1158: This routine is only run once after compilation.
1159:
1160: =over 4
1161:
1162: =item *
1163:
1164: Initializes %language hash table.
1165:
1166: =back
1167:
1168: =head1 HANDLER SUBROUTINE
1169:
1170: This routine is called by Apache and mod_perl.
1171:
1172: =over 4
1173:
1174: =item *
1175:
1176: read in machine configuration variables
1177:
1178: =item *
1179:
1180: see if called from an interactive mode
1181:
1182: =item *
1183:
1184: refresh environment with user database values (in %hash)
1185:
1186: =item *
1187:
1188: define extra fields and buttons in case of special mode
1189:
1190: =item *
1191:
1192: set catalogmodefunctions to have extra needed javascript functionality
1193:
1194: =item *
1195:
1196: print header
1197:
1198: =item *
1199:
1200: evaluate actions from previous page (both cumulatively and chronologically)
1201:
1202: =item *
1203:
1204: output title
1205:
1206: =item *
1207:
1208: get state of file attributes to be showing
1209:
1210: =item *
1211:
1212: output state of file attributes to be showing
1213:
1214: =item *
1215:
1216: output starting row to the indexed file/directory hierarchy
1217:
1218: =item *
1219:
1220: read in what directories have previously been set to "open"
1221:
1222: =item *
1223:
1224: if not at top level, provide an uplink arrow
1225:
1226: =item *
1227:
1228: recursively go through all the directories and output as appropriate
1229:
1230: =item *
1231:
1232: information useful for group import
1233:
1234: =item *
1235:
1236: end the tables
1237:
1238: =item *
1239:
1240: end the output and return
1241:
1242: =back
1243:
1244: =head1 OTHER SUBROUTINES
1245:
1246: =over 4
1247:
1248: =item *
1249:
1250: scanDir - recursive scan of a directory
1251:
1252: =item *
1253:
1254: get_list - get complete matched list based on the uri (returns an array)
1255:
1256: =item *
1257:
1258: match_ext - filters out files based on extensions (returns an array)
1259:
1260: =item *
1261:
1262: display_line - displays one line in appropriate table format
1263:
1264: =item *
1265:
1266: begin_form - prints the beginning of a form for directory or file link
1267:
1268: =item *
1269:
1270: start_fresh_session - settings whenever the user causes the indexer window
1271: to be launched
1272:
1273: =back
1274:
1275: =cut
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>