--- rat/lonuserstate.pm	2002/06/05 12:52:05	1.27
+++ rat/lonuserstate.pm	2002/09/04 19:37:32	1.41
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Construct and maintain state and binary representation of course for user
 #
-# $Id: lonuserstate.pm,v 1.27 2002/06/05 12:52:05 www Exp $
+# $Id: lonuserstate.pm,v 1.41 2002/09/04 19:37:32 www Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -67,7 +67,7 @@ my %parmhash;# The hash with the paramet
 my @cond;    # Array with all of the conditions
 my $errtext; # variable with all errors
 my $retfurl; # variable with the very first URL in the course
-
+my %randompick; # randomly picked resources
 # --------------------------------------------------------- Loads map from disk
 
 sub loadmap { 
@@ -79,7 +79,10 @@ sub loadmap {
     $hash{'map_pc_'.$uri}=$lpc;
     $hash{'map_id_'.$lpc}=$uri;
 
-    my $fn='/home/httpd/html'.$uri;
+# Determine and check filename
+    my $fn=&Apache::lonnet::filelocation('',$uri);
+
+    my $ispage=($fn=~/\.page$/);
 
     unless (($fn=~/\.sequence$/) ||
             ($fn=~/\.page$/)) { 
@@ -87,32 +90,12 @@ sub loadmap {
        return OK; 
     }
 
-    my $ispage=($fn=~/\.page$/);
+    my $instr=&Apache::lonnet::getfile($fn);
 
-    unless (-e $fn) {
-	my $returned=Apache::lonnet::repcopy($fn);
-        unless ($returned eq OK) {
-           $errtext.="Could not import: $fn - ";
-           if ($returned eq HTTP_SERVICE_UNAVAILABLE) {
-	      $errtext.="Server unavailable\n";
-           }
-           if ($returned eq HTTP_NOT_FOUND) {
-	      $errtext.="File not found\n";
-           }
-           if ($returned eq FORBIDDEN) {
-	      $errtext.="Access forbidden\n";
-           }
-           return OK;
-       }
-    }
+    unless ($instr == -1) {
+
+# Successfully got file, parse it
 
-    if (-e $fn) {
-        my @content;
-        {
-	    my $fh=Apache::File->new($fn);
-            @content=<$fh>;
-        }
-        my $instr=join('',@content);
         my $parser = HTML::TokeParser->new(\$instr);
         my $token;
 
@@ -135,11 +118,19 @@ sub loadmap {
                     unless ($ispage) {
                         $turi=~/\.(\w+)$/;
                         my $embstyle=&Apache::loncommon::fileembstyle($1);
-                        if ($token->[2]->{'external'} eq 'true') {
+                        if ($token->[2]->{'external'} eq 'true') { # external
                             $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;
-                        } else {
-                           my $embstyle=&Apache::loncommon::fileembstyle($1);
-                           if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
+                        } elsif ($turi=~/^\/*uploaded\//) { # uploaded
+			    if (($embstyle eq 'img') || ($embstyle eq 'emb')
+                             || ($embstyle eq 'ssi')) {
+                                $turi='/adm/wrapper'.$turi;
+                            } elsif ($turi!~/\.(sequence|page)$/) {
+				$turi='/adm/coursedocs?showdoc='.$turi;
+                            }
+                        } else { # normal internal resource
+                           if (($embstyle eq 'img') || ($embstyle eq 'emb')
+                          || ($turi=~/\/syllabus$/) || ($turi=~/\/aboutme$/)
+                          || ($turi=~/\/navmaps$/)) {
 			       $turi='/adm/wrapper'.$turi;
                            }
                         }
@@ -233,7 +224,12 @@ sub loadmap {
                     } else {
                         $hash{'param_'.$referid}=''.$newparam;
                     }
-
+                    if ($token->[2]->{'name'} eq 'parameter_mapalias') {
+			$hash{'mapalias_'.$token->[2]->{'value'}}=$referid;
+                    }
+                    if ($token->[2]->{'name'} eq 'parameter_randompick') {
+			$randompick{$referid}=$token->[2]->{'value'};
+                    }
                 } 
 
             }
@@ -272,8 +268,14 @@ sub traceroute {
     $sofar=simplify($sofar);
     unless ($beenhere=~/\&$rid\&/) {
        $beenhere.=$rid.'&';  
-       if ($retfurl eq '') {
-           $retfurl=$hash{'src_'.$rid};
+       if (($retfurl eq '') && ($hash{'src_'.$rid})) {
+           my ($mapid,$resid)=split(/\./,$rid);
+           $retfurl=$hash{'src_'.$rid}.
+           (($hash{'src_'.$rid}=~/\?/)?'&':'?').'symb='.
+           &Apache::lonnet::symbclean(
+                           &Apache::lonnet::declutter($hash{'map_id_'.$mapid}).
+                           '___'.$resid.'___'.
+                           &Apache::lonnet::declutter($hash{'src_'.$rid}));
        }
        if (defined($hash{'conditions_'.$rid})) {
 	   $hash{'conditions_'.$rid}=simplify(
@@ -396,6 +398,51 @@ sub accinit {
                             "request.course.uri" => $courseuri); 
 }
 
+# ------------------------------------- Selectively delete from randompick maps
+
+sub pickrandom {
+    my $randomoutentry='';
+    foreach my $rid (keys %randompick) {
+        my $rndpick=$randompick{$rid};
+        my $mpc=$hash{'map_pc_'.$hash{'src_'.$rid}};
+# ------------------------------------------- put existing resources into array
+        my @currentrids=();
+        foreach (keys %hash) {
+	    if ($_=~/^src_($mpc\.\d+)/) {
+		if ($hash{'src_'.$1}) { push @currentrids, $1; }
+            }
+        }
+        next if ($#currentrids<$rndpick);
+# -------------------------------- randomly eliminate the ones that should stay
+	srand(&Apache::lonnet::rndseed($rid)); # use rid instead of symb
+        for (my $i=1;$i<=$rndpick;$i++) {
+            while (1) {
+		my $randomidx=int(rand($#currentrids+1));
+                if ($currentrids[$randomidx]) {
+		    $currentrids[$randomidx]='';
+                    last;
+                }
+            }
+        }
+# -------------------------------------------------------- delete the leftovers
+        for (my $k=0; $k<=$#currentrids; $k++) {
+            if ($currentrids[$k]) {
+		$hash{'randomout_'.$currentrids[$k]}=1;
+                my ($mapid,$resid)=split(/\./,$currentrids[$k]);
+                $randomoutentry.='&'.
+                 &Apache::lonnet::symbclean(
+		    &Apache::lonnet::declutter($hash{'map_id_'.$mapid}).
+                    '___'.$resid.'___'.
+		    &Apache::lonnet::declutter($hash{'src_'.$currentrids[$k]})
+                 ).'&';
+            }
+        }
+    }
+    if ($randomoutentry) {
+	&Apache::lonnet::appenv('acc.randomout' => $randomoutentry);
+    }
+}
+
 # ---------------------------------------------------- Read map and all submaps
 
 sub readmap {
@@ -415,17 +462,24 @@ sub readmap {
    unlink($fn.'_symb.db');
    unlink($fn.'.state');
    unlink($fn.'parms.db');
+   undef %randompick;
    $retfurl='';
-   if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT,0640)) &&
-       (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT,0640))) {
+   if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) &&
+       (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640))) {
     %hash=();
     %parmhash=();
     $errtext='';
     $pc=0;
+    my $furi=&Apache::lonnet::clutter($uri);
+    $hash{'src_0.0'}=$furi;
+    $hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title');
+    $hash{'ids_'.$furi}='0.0';
+    $hash{'is_map_0.0'}=1;
     loadmap($uri);
     if (defined($hash{'map_start_'.$uri})) {
         &traceroute('0',$hash{'map_start_'.$uri},'&');
         &accinit($uri,$short,$fn);
+        &pickrandom();
     }
     unless ((untie(%hash)) && (untie(%parmhash))) {
       &Apache::lonnet::logthis("<font color=blue>WARNING: ".