--- loncom/lonnet/perl/lonnet.pm	2001/11/20 22:30:20	1.174
+++ loncom/lonnet/perl/lonnet.pm	2001/12/07 20:17:44	1.188
@@ -1,6 +1,30 @@
 # The LearningOnline Network
 # TCP networking package
 #
+# $Id: lonnet.pm,v 1.188 2001/12/07 20:17:44 www Exp $
+#
+# Copyright Michigan State University Board of Trustees
+#
+# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
+#
+# LON-CAPA is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# LON-CAPA is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with LON-CAPA; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+# /home/httpd/html/adm/gpl.txt
+#
+# http://www.lon-capa.org/
+#
 # 6/1/99,6/2,6/10,6/11,6/12,6/14,6/26,6/28,6/29,6/30,
 # 7/1,7/2,7/9,7/10,7/12,7/14,7/15,7/19,
 # 11/8,11/16,11/18,11/22,11/23,12/22,
@@ -35,9 +59,12 @@
 # 8/4,8/7,8/8,8/9,8/11,8/16,8/17,8/18,8/20,8/23,9/20,9/21,9/26,
 # 10/2 Gerd Kortemeyer
 # 10/5,10/10,11/13,11/15 Scott Harrison
-# 11/17 Gerd Kortemeyer
+# 11/17,11/20,11/22,11/29 Gerd Kortemeyer
+# 12/5 Matthew Hall
+# 12/5 Guy Albertelli
+# 12/6,12/7 Gerd Kortemeyer
 #
-# $Id: lonnet.pm,v 1.174 2001/11/20 22:30:20 www Exp $
+# $Id: lonnet.pm,v 1.188 2001/12/07 20:17:44 www Exp $
 #
 ###
 
@@ -145,7 +172,10 @@ use Apache::File;
 use LWP::UserAgent();
 use HTTP::Headers;
 use vars 
-qw(%perlvar %hostname %homecache %hostip %spareid %hostdom %libserv %pr %prp %fe %fd $readit %metacache %packagetab %courselogs);
+qw(%perlvar %hostname %homecache %hostip %spareid %hostdom 
+   %libserv %pr %prp %fe %fd %metacache %packagetab 
+   %courselogs %accesshash $processmarker $dumpcount 
+   %coursedombuf %coursehombuf);
 use IO::Socket;
 use GDBM_File;
 use Apache::Constants qw(:common :http);
@@ -728,10 +758,9 @@ sub flushcourselogs {
     &logthis('Flushing course log buffers');
     map {
         my $crsid=$_;
-        if (&reply('log:'.$ENV{'course.'.$crsid.'.domain'}.':'.
-		          $ENV{'course.'.$crsid.'.num'}.':'.
-		           &escape($courselogs{$crsid}),
-		          $ENV{'course.'.$crsid.'.home'}) eq 'ok') {
+        if (&reply('log:'.$coursedombuf{$crsid}.':'.
+		          &escape($courselogs{$crsid}),
+		          $coursehombuf{$crsid}) eq 'ok') {
 	    delete $courselogs{$crsid};
         } else {
             &logthis('Failed to flush log buffer for '.$crsid);
@@ -742,12 +771,27 @@ sub flushcourselogs {
             }
         }        
     } keys %courselogs;
+    &logthis('Flushing access logs');
+    map {
+        my $entry=$_;
+        $entry=~/\_\_\_(\w+)\/(\w+)\/(.*)\_\_\_(\w+)$/;
+        my %temphash=($entry => $accesshash{$entry});
+        if (&Apache::lonnet::put('resevaldata',\%temphash,$1,$2) eq 'ok') {
+	    delete $accesshash{$entry};
+        }
+    } keys %accesshash;
+    $dumpcount++;
 }
 
 sub courselog {
     my $what=shift;
     $what=time.':'.$what;
     unless ($ENV{'request.course.id'}) { return ''; }
+    $coursedombuf{$ENV{'request.course.id'}}=
+       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}.':'.
+       $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
+    $coursehombuf{$ENV{'request.course.id'}}=
+       $ENV{'course.'.$ENV{'request.course.id'}.'.home'};
     if (defined $courselogs{$ENV{'request.course.id'}}) {
 	$courselogs{$ENV{'request.course.id'}}.='&'.$what;
     } else {
@@ -763,6 +807,7 @@ sub courseacclog {
     unless ($ENV{'request.course.id'}) { return ''; }
     my $what=$fnsymb.':'.$ENV{'user.name'}.':'.$ENV{'user.domain'};
     if ($what=~/(problem|exam|quiz|assess|survey|form)$/) {
+        $what.=':POST';
 	map {
             if ($_=~/^form\.(.*)/) {
 		$what.=':'.$1.'='.$ENV{$_};
@@ -772,6 +817,18 @@ sub courseacclog {
     &courselog($what);
 }
 
+sub countacc {
+    my $url=&declutter(shift);
+    unless ($ENV{'request.course.id'}) { return ''; }
+    $accesshash{$ENV{'request.course.id'}.'___'.$url.'___course'}=1;
+    my $key=$processmarker.'_'.$dumpcount.'___'.$url.'___count';
+    if (defined($accesshash{$key})) {
+	$accesshash{$key}++;
+    } else {
+        $accesshash{$key}=1;
+    }
+}
+    
 # ----------------------------------------------------------- Check out an item
 
 sub checkout {
@@ -939,7 +996,7 @@ sub tmpreset {
 	  $path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db',
 	  &GDBM_WRCREAT,0640)) {
     foreach my $key (keys %hash) {
-      if ($key=~ /:$symb:/) {
+      if ($key=~ /:$symb/) {
 	delete($hash{$key});
       }
     }
@@ -1053,7 +1110,11 @@ sub store {
     &devalidate($symb);
 
     $symb=escape($symb);
-    if (!$namespace) { unless ($namespace=$ENV{'request.course.id'}) { return ''; } }
+    if (!$namespace) { 
+       unless ($namespace=$ENV{'request.course.id'}) { 
+          return ''; 
+       } 
+    }
     if (!$domain) { $domain=$ENV{'user.domain'}; }
     if (!$stuname) { $stuname=$ENV{'user.name'}; }
     if (!$home) { $home=$ENV{'user.home'}; }
@@ -1062,6 +1123,7 @@ sub store {
         $namevalue.=escape($_).'='.escape($$storehash{$_}).'&';
     } keys %$storehash;
     $namevalue=~s/\&$//;
+    &courselog($symb.':'.$stuname.':'.$domain.':STORE:'.$namevalue);
     return reply("store:$domain:$stuname:$namespace:$symb:$namevalue","$home");
 }
 
@@ -1078,7 +1140,11 @@ sub cstore {
     &devalidate($symb);
 
     $symb=escape($symb);
-    if (!$namespace) { unless ($namespace=$ENV{'request.course.id'}) { return ''; } }
+    if (!$namespace) { 
+       unless ($namespace=$ENV{'request.course.id'}) { 
+          return ''; 
+       } 
+    }
     if (!$domain) { $domain=$ENV{'user.domain'}; }
     if (!$stuname) { $stuname=$ENV{'user.name'}; }
     if (!$home) { $home=$ENV{'user.home'}; }
@@ -1088,7 +1154,9 @@ sub cstore {
         $namevalue.=escape($_).'='.escape($$storehash{$_}).'&';
     } keys %$storehash;
     $namevalue=~s/\&$//;
-    return critical("store:$domain:$stuname:$namespace:$symb:$namevalue","$home");
+    &courselog($symb.':'.$stuname.':'.$domain.':CSTORE:'.$namevalue);
+    return critical
+                ("store:$domain:$stuname:$namespace:$symb:$namevalue","$home");
 }
 
 # --------------------------------------------------------------------- Restore
@@ -1104,7 +1172,11 @@ sub restore {
     } else {
       $symb=&escape($symb);
     }
-    if (!$namespace) { unless ($namespace=$ENV{'request.course.id'}) { return ''; } }
+    if (!$namespace) { 
+       unless ($namespace=$ENV{'request.course.id'}) { 
+          return ''; 
+       } 
+    }
     if (!$domain) { $domain=$ENV{'user.domain'}; }
     if (!$stuname) { $stuname=$ENV{'user.name'}; }
     if (!$home) { $home=$ENV{'user.home'}; }
@@ -1688,14 +1760,14 @@ sub plaintext {
 # ------------------------------------------------------------------ Plain Text
 
 sub fileembstyle {
-    my $ending=shift;
+    my $ending=lc(shift);
     return $fe{$ending};
 }
 
 # ------------------------------------------------------------ Description Text
 
 sub filedescription {
-    my $ending=shift;
+    my $ending=lc(shift);
     return $fd{$ending};
 }
 
@@ -2232,14 +2304,14 @@ sub EXT {
 # ---------------------------------------------------------------- Get metadata
 
 sub metadata {
-    my ($uri,$what,$liburi,$prefix)=@_;
+    my ($uri,$what,$liburi,$prefix,$depthcount)=@_;
 
     $uri=&declutter($uri);
     my $filename=$uri;
     $uri=~s/\.meta$//;
 #
 # Is the metadata already cached?
-# If "keys" are set, the assumption is that everything is already cached.
+# Look at timestamp of caching
 # Everything is cached by the main uri, libraries are never directly cached
 #
     unless (abs($metacache{$uri.':cachedtimestamp'}-time)<600) {
@@ -2301,18 +2373,15 @@ sub metadata {
 #
 # This is not a package - some other kind of start tag
 # 
-	     my $entry=$token->[1];
-             if ($entry eq 'import') {
-#
-# Importing a library here
-#
-                my $libid=$token->[2]->{'id'};
-
-              
-             } else { 
-              my $unikey=$entry;
+              my $entry=$token->[1];
+              my $unikey;
+              if ($entry eq 'import') {
+                 $unikey='';
+              } else {
+                 $unikey=$entry;
+	      }
               if ($prefix) {
-		  $unikey.='_'.$prefix;
+		  $unikey.=$prefix;
               } else {
                 if (defined($token->[2]->{'part'})) { 
                    $unikey.='_'.$token->[2]->{'part'}; 
@@ -2321,6 +2390,22 @@ sub metadata {
               if (defined($token->[2]->{'id'})) { 
                  $unikey.='_'.$token->[2]->{'id'}; 
 	      }
+
+             if ($entry eq 'import') {
+#
+# Importing a library here
+#                
+		 if (defined($depthcount)) { $depthcount++; } else 
+                                           { $depthcount=0; }
+                 if ($depthcount<20) {
+		     map {
+                         $metathesekeys{$_}=1;
+		     } split(/\,/,&metadata($uri,'keys',
+                                  $parser->get_text('/import'),$unikey,
+                                  $depthcount));
+		 }
+             } else { 
+
               if (defined($token->[2]->{'name'})) { 
                  $unikey.='_'.$token->[2]->{'name'}; 
 	      }
@@ -2334,7 +2419,7 @@ sub metadata {
 			      $metacache{$uri.':'.$unikey.'.default'};
 		      }
 # end of not-a-package not-a-library import
-	     }
+	   }
 # end of not-a-package start tag
 	  }
 # the next is the end of "start tag"
@@ -2342,6 +2427,7 @@ sub metadata {
        }
        $metacache{$uri.':keys'}=join(',',keys %metathesekeys);
        $metacache{$uri.':cachedtimestamp'}=time;
+# this is the end of "was not already recently cached
     }
     return $metacache{$uri.':'.$what};
 }
@@ -2371,6 +2457,7 @@ sub symblist {
 sub symbread {
     my $thisfn=shift;
     unless ($thisfn) {
+        if ($ENV{'request.symb'}) { return $ENV{'request.symb'}; }
 	$thisfn=$ENV{'request.filename'};
     }
     $thisfn=declutter($thisfn);
@@ -2567,8 +2654,12 @@ sub unescape {
 
 # ================================================================ Main Program
 
-sub BEGIN {
-unless ($readit) {
+sub goodbye {
+   &flushcourselogs();
+   &logthis("Shutting down");
+}
+
+BEGIN {
 # ------------------------------------------------------------ Read access.conf
 {
     my $config=Apache::File->new("/etc/httpd/conf/access.conf");
@@ -2653,10 +2744,11 @@ unless ($readit) {
     my $config=Apache::File->new("$perlvar{'lonTabDir'}/filetypes.tab");
 
     while (my $configline=<$config>) {
+       next if ($configline =~ /^\#/);
        chomp($configline);
        my ($ending,$emb,@descr)=split(/\s+/,$configline);
        if ($descr[0] ne '') { 
-         $fe{$ending}=$emb;
+         $fe{$ending}=lc($emb);
          $fd{$ending}=join(' ',@descr);
        }
     }
@@ -2664,9 +2756,11 @@ unless ($readit) {
 
 %metacache=();
 
-$readit='done';
+$processmarker=$$.'_'.time.'_'.$perlvar{'lonHostID'};
+$dumpcount=0;
+
 &logtouch();
 &logthis('<font color=yellow>INFO: Read configuration</font>');
 }
-}
+
 1;