[LON-CAPA-cvs] cvs: rat / lonuserstate.pm

albertel lon-capa-cvs-allow@mail.lon-capa.org
Wed, 29 Aug 2007 00:50:52 -0000


This is a MIME encoded message

--albertel1188348652
Content-Type: text/plain

albertel		Tue Aug 28 20:50:52 2007 EDT

  Modified files:              
    /rat	lonuserstate.pm 
  Log:
  - forward port 1.118.2.2 (BUG#3960) random ordering of resources
     - better randomizing then 1.118.2.2
     - adv users get resources in ordered state
  
  
  
--albertel1188348652
Content-Type: text/plain
Content-Disposition: attachment; filename="albertel-20070828205052.txt"

Index: rat/lonuserstate.pm
diff -u rat/lonuserstate.pm:1.123 rat/lonuserstate.pm:1.124
--- rat/lonuserstate.pm:1.123	Tue Aug 28 12:45:20 2007
+++ rat/lonuserstate.pm	Tue Aug 28 20:50:50 2007
@@ -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.123 2007/08/28 16:45:20 albertel Exp $
+# $Id: lonuserstate.pm,v 1.124 2007/08/29 00:50:50 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -56,6 +56,7 @@
 my $retfurl; # first URL
 my %randompick; # randomly picked resources
 my %randompickseed; # optional seed for randomly picking resources
+my %randomorder; # maps to order contents randomly
 my %encurl; # URLs in this folder are supposed to be encrypted
 my %hiddenurl; # this URL (or complete folder) is supposed to be hidden
 
@@ -106,7 +107,7 @@
 # --------------------------------------------------------- Loads map from disk
 
 sub loadmap { 
-    my $uri=shift;
+    my ($uri,$parent_rid)=@_;
     if ($hash{'map_pc_'.$uri}) { 
 	$errtext.='<p class="LC_error">'.
 	    &mt('Multiple use of sequence/page [_1]! The course will not function properly.','<tt>'.$uri.'</tt>').
@@ -131,193 +132,82 @@
 
     my $instr=&Apache::lonnet::getfile($fn);
 
-    unless ($instr eq -1) {
+    if ($instr eq -1) {
+        $errtext.=&mt('<br />Map not loaded: The file <tt>[_1]</tt> does not exist.',$fn);
+	return;
+    }
 
 # Successfully got file, parse it
 
-        my $parser = HTML::TokeParser->new(\$instr);
-	$parser->attr_encoded(1);
-        my $token;
-
-        my $linkpc=0;
-
-        $fn=~/\.(\w+)$/;
-
-        $hash{'map_type_'.$lpc}=$1;
-
-        while ($token = $parser->get_token) {
-	    if ($token->[0] eq 'S') {
-                if ($token->[1] eq 'resource') {
-# -------------------------------------------------------------------- Resource
-                    if ($token->[2]->{'type'} eq 'zombie') { next; }
-                    my $rid=$lpc.'.'.$token->[2]->{'id'};
-
-                    $hash{'kind_'.$rid}='res';
-                    $hash{'title_'.$rid}=$token->[2]->{'title'};
-                    my $turi=&versiontrack($token->[2]->{'src'});
-                    if ($token->[2]->{'version'}) {
-			unless ($hash{'version_'.$turi}) {
-			    $hash{'version_'.$turi}=$1;
-			}
-		    }
-		    my $title=$token->[2]->{'title'};
-		    $title=~s/\&colon\;/\:/gs;
-#		    my $symb=&Apache::lonnet::encode_symb($uri,
-#							  $token->[2]->{'id'},
-#							  $turi);
-#		    &Apache::lonnet::do_cache_new('title',$symb,$title);
-                    unless ($ispage) {
-                        $turi=~/\.(\w+)$/;
-                        my $embstyle=&Apache::loncommon::fileembstyle($1);
-                        if ($token->[2]->{'external'} eq 'true') { # external
-                            $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;
-                        } elsif ($turi=~/^\/*uploaded\//) { # uploaded
-			    if (($embstyle eq 'img') 
-				|| ($embstyle eq 'emb')
-				|| ($embstyle eq 'wrp')) {
-                                $turi='/adm/wrapper'.$turi;
-			    } elsif ($embstyle eq 'ssi') {
-				#do nothing with these
-			    } elsif ($turi!~/\.(sequence|page)$/) {
-				$turi='/adm/coursedocs/showdoc'.$turi;
-                            }
-                        } elsif ($turi=~/\S/) { # normal non-empty internal resource
-			    my $mapdir=$uri;
-			    $mapdir=~s/[^\/]+$//;
-			    $turi=&Apache::lonnet::hreflocation($mapdir,$turi);
-			    if (($embstyle eq 'img') 
-				|| ($embstyle eq 'emb')
-				|| ($embstyle eq 'wrp')) {
-				$turi='/adm/wrapper'.$turi;
-			    }
-                        }
-		    }
-# Store reverse lookup, remove query string
-		    my $idsuri=$turi;
-		    $idsuri=~s/\?.+$//;
-                    if (defined($hash{'ids_'.$idsuri})) {
-                        $hash{'ids_'.$idsuri}.=','.$rid;
-                    } else {
-                        $hash{'ids_'.$idsuri}=''.$rid;
-                    }
-               
-                    if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard)$/) {
-			$turi.='?register=1';
-		    }
+    my $parser = HTML::TokeParser->new(\$instr);
+    $parser->attr_encoded(1);
+    # first get all parameters
+    while (my $token = $parser->get_token) {
+	next if ($token->[0] ne 'S');
+	if ($token->[1] eq 'param') {
+	    &parse_param($token,$lpc);
+	} 
+    }
+    #reset parser
+    $parser = HTML::TokeParser->new(\$instr);
+    $parser->attr_encoded(1);
 
-                    $hash{'src_'.$rid}=$turi;
+    my $linkpc=0;
 
-                    if ($token->[2]->{'external'} eq 'true') {
-                        $hash{'ext_'.$rid}='true:';
-                    } else {
-                        $hash{'ext_'.$rid}='false:';
-                    }
-                    if ($token->[2]->{'type'}) {
-			$hash{'type_'.$rid}=$token->[2]->{'type'};
-                        if ($token->[2]->{'type'} eq 'start') {
-			    $hash{'map_start_'.$uri}="$rid";
-                        }
-                        if ($token->[2]->{'type'} eq 'finish') {
-			    $hash{'map_finish_'.$uri}="$rid";
-                        }
-                    }  else {
-                        $hash{'type_'.$rid}='normal';
-                    }
-
-                    if (($turi=~/\.sequence$/) ||
-                        ($turi=~/\.page$/)) {
-                        $hash{'is_map_'.$rid}=1;
-                        &loadmap($turi);
-                    } 
-                    
-                } elsif ($token->[1] eq 'condition') {
-# ------------------------------------------------------------------- Condition
+    $fn=~/\.(\w+)$/;
 
-                    my $rid=$lpc.'.'.$token->[2]->{'id'};
+    $hash{'map_type_'.$lpc}=$1;
 
-                    $hash{'kind_'.$rid}='cond';
-		    my $condition = $token->[2]->{'value'};
-		    $condition =~ s/[\n\r]+/ /gs; 
-                    push(@cond, $condition);
-                    $hash{'condid_'.$rid}=$#cond;
-                    if ($token->[2]->{'type'}) {
-                        $cond[$#cond].=':'.$token->[2]->{'type'};
-                    }  else {
-                        $cond[$#cond].=':normal';
-                    }
+    my $randomize = ($randomorder{$parent_rid} =~ /^yes$/i);
 
-                } elsif ($token->[1] eq 'link') {
+    my @map_ids;
+    while (my $token = $parser->get_token) {
+	next if ($token->[0] ne 'S');
+	if ($token->[1] eq 'resource') {
+	    push(@map_ids,&parse_resource($token,$lpc,$ispage,$uri));
+	} elsif ($token->[1] eq 'link' && !$randomize) {
 # ----------------------------------------------------------------------- Links
+	    &make_link(++$linkpc,$lpc,$token->[2]->{'to'},
+		       $token->[2]->{'from'},
+		       $token->[2]->{'condition'});
+	} elsif ($token->[1] eq 'condition' && !$randomize) {
+	    &parse_condition($token,$lpc);
+	}
+    }
 
-                    $linkpc++;
-                    my $linkid=$lpc.'.'.$linkpc;
-
-                    my $goesto=$lpc.'.'.$token->[2]->{'to'};
-                    my $comesfrom=$lpc.'.'.$token->[2]->{'from'};
-                    my $undercond=0;
-
-                    if ($token->[2]->{'condition'}) {
-			$undercond=$lpc.'.'.$token->[2]->{'condition'};
-                    }
-
-                    $hash{'goesto_'.$linkid}=$goesto;
-                    $hash{'comesfrom_'.$linkid}=$comesfrom;
-                    $hash{'undercond_'.$linkid}=$undercond;
-
-                    if (defined($hash{'to_'.$comesfrom})) {
-                        $hash{'to_'.$comesfrom}.=','.$linkid;
-                    } else {
-                        $hash{'to_'.$comesfrom}=''.$linkid;
-                    }
-                    if (defined($hash{'from_'.$goesto})) {
-                        $hash{'from_'.$goesto}.=','.$linkid;
-                    } else {
-                        $hash{'from_'.$goesto}=''.$linkid;
-                    }
-                } elsif ($token->[1] eq 'param') {
-# ------------------------------------------------------------------- Parameter
-
-                    my $referid=$lpc.'.'.$token->[2]->{'to'};
-		    my $name=$token->[2]->{'name'};
-		    my $part;
-		    if ($name=~/^parameter_(.*)_/) {
-			$part=$1;
-		    } else {
-			$part=0;
-		    }
-		    $name=~s/^.*_([^_]*)$/$1/;
-                    my $newparam=
-			&escape($token->[2]->{'type'}).':'.
-			&escape($part.'.'.$name).'='.
-			&escape($token->[2]->{'value'});
-                    if (defined($hash{'param_'.$referid})) {
-                        $hash{'param_'.$referid}.='&'.$newparam;
-                    } else {
-                        $hash{'param_'.$referid}=''.$newparam;
-                    }
-                    if ($token->[2]->{'name'}=~/^parameter_(0_)*randompick$/) {
-			$randompick{$referid}=$token->[2]->{'value'};
-                    }
-                    if ($token->[2]->{'name'}=~/^parameter_(0_)*randompickseed$/) {
-			$randompickseed{$referid}=$token->[2]->{'value'};
-                    }
-                    if ($token->[2]->{'name'}=~/^parameter_(0_)*encrypturl$/) {
-			if ($token->[2]->{'value'}=~/^yes$/i) {
-			    $encurl{$referid}=1;
-			}
-                    }
-                    if ($token->[2]->{'name'}=~/^parameter_(0_)*hiddenresource$/) {
-			if ($token->[2]->{'value'}=~/^yes$/i) {
-			    $hiddenurl{$referid}=1;
-			}
-                    }
-                } 
+    if ($randomize) {
+	if (!$env{'request.role.adv'}) {
+	    my $seed;
+	    if (defined($randompickseed{$parent_rid})) {
+		$seed = $randompickseed{$parent_rid};
+	    } else {
+		my ($mapid,$resid)=split(/\./,$parent_rid);
+		my $symb=
+		    &Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},
+						 $resid,$hash{'src_'.$parent_rid});
 		
-            }
-        }
+		$seed = $symb;
+	    }
+	
+	    my $rndseed=&Apache::lonnet::rndseed($seed);
+	    &Apache::lonnet::setup_random_from_rndseed($rndseed);
+	    @map_ids=&Math::Random::random_permutation(@map_ids);
+	}
+	my $from = shift(@map_ids);
+	my $from_rid = $lpc.'.'.$from;
+	$hash{'map_start_'.$uri} = $from_rid;
+	$hash{'type_'.$from_rid}='start';
+
+	while (my $to = shift(@map_ids)) {
+	    &make_link(++$linkpc,$lpc,$to,$from);
+	    my $to_rid =  $lpc.'.'.$to;
+	    $hash{'type_'.$to_rid}='normal';
+	    $from = $to;
+	    $from_rid = $to_rid;
+	}
 
-    } else {
-        $errtext.=&mt('<br />Map not loaded: The file <tt>[_1]</tt> does not exist.',$fn);
+	$hash{'map_finish_'.$uri}= $from_rid;
+	$hash{'type_'.$from_rid}='finish';
     }
 
     my $parser = HTML::TokeParser->new(\$instr);
@@ -332,6 +222,182 @@
     }
 }
 
+
+# -------------------------------------------------------------------- Resource
+sub parse_resource {
+    my ($token,$lpc,$ispage,$uri) = @_;
+    if ($token->[2]->{'type'} eq 'zombie') { next; }
+    my $rid=$lpc.'.'.$token->[2]->{'id'};
+	    
+    $hash{'kind_'.$rid}='res';
+    $hash{'title_'.$rid}=$token->[2]->{'title'};
+    my $turi=&versiontrack($token->[2]->{'src'});
+    if ($token->[2]->{'version'}) {
+	unless ($hash{'version_'.$turi}) {
+	    $hash{'version_'.$turi}=$1;
+	}
+    }
+    my $title=$token->[2]->{'title'};
+    $title=~s/\&colon\;/\:/gs;
+#   my $symb=&Apache::lonnet::encode_symb($uri,
+#					  $token->[2]->{'id'},
+#					  $turi);
+#   &Apache::lonnet::do_cache_new('title',$symb,$title);
+    unless ($ispage) {
+	$turi=~/\.(\w+)$/;
+	my $embstyle=&Apache::loncommon::fileembstyle($1);
+	if ($token->[2]->{'external'} eq 'true') { # external
+	    $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;
+	} elsif ($turi=~/^\/*uploaded\//) { # uploaded
+	    if (($embstyle eq 'img') 
+		|| ($embstyle eq 'emb')
+		|| ($embstyle eq 'wrp')) {
+		$turi='/adm/wrapper'.$turi;
+	    } elsif ($embstyle eq 'ssi') {
+		#do nothing with these
+	    } elsif ($turi!~/\.(sequence|page)$/) {
+		$turi='/adm/coursedocs/showdoc'.$turi;
+	    }
+	} elsif ($turi=~/\S/) { # normal non-empty internal resource
+	    my $mapdir=$uri;
+	    $mapdir=~s/[^\/]+$//;
+	    $turi=&Apache::lonnet::hreflocation($mapdir,$turi);
+	    if (($embstyle eq 'img') 
+		|| ($embstyle eq 'emb')
+		|| ($embstyle eq 'wrp')) {
+		$turi='/adm/wrapper'.$turi;
+	    }
+	}
+    }
+# Store reverse lookup, remove query string
+    my $idsuri=$turi;
+    $idsuri=~s/\?.+$//;
+    if (defined($hash{'ids_'.$idsuri})) {
+	$hash{'ids_'.$idsuri}.=','.$rid;
+    } else {
+	$hash{'ids_'.$idsuri}=''.$rid;
+    }
+    
+    if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard)$/) {
+	$turi.='?register=1';
+    }
+    
+    $hash{'src_'.$rid}=$turi;
+    
+    if ($token->[2]->{'external'} eq 'true') {
+	$hash{'ext_'.$rid}='true:';
+    } else {
+	$hash{'ext_'.$rid}='false:';
+    }
+    if ($token->[2]->{'type'}) {
+	$hash{'type_'.$rid}=$token->[2]->{'type'};
+	if ($token->[2]->{'type'} eq 'start') {
+	    $hash{'map_start_'.$uri}="$rid";
+	}
+	if ($token->[2]->{'type'} eq 'finish') {
+	    $hash{'map_finish_'.$uri}="$rid";
+	}
+    }  else {
+	$hash{'type_'.$rid}='normal';
+    }
+    
+    if (($turi=~/\.sequence$/) ||
+	($turi=~/\.page$/)) {
+	$hash{'is_map_'.$rid}=1;
+	&loadmap($turi,$rid);
+    } 
+    return $token->[2]->{'id'};
+}
+
+sub make_link {
+    my ($linkpc,$lpc,$to,$from,$condition) = @_;
+    
+    my $linkid=$lpc.'.'.$linkpc;
+    my $goesto=$lpc.'.'.$to;
+    my $comesfrom=$lpc.'.'.$from;
+    my $undercond=0;
+
+    if ($condition) {
+	$undercond=$lpc.'.'.$condition;
+    }
+
+    $hash{'goesto_'.$linkid}=$goesto;
+    $hash{'comesfrom_'.$linkid}=$comesfrom;
+    $hash{'undercond_'.$linkid}=$undercond;
+
+    if (defined($hash{'to_'.$comesfrom})) {
+	$hash{'to_'.$comesfrom}.=','.$linkid;
+    } else {
+	$hash{'to_'.$comesfrom}=''.$linkid;
+    }
+    if (defined($hash{'from_'.$goesto})) {
+	$hash{'from_'.$goesto}.=','.$linkid;
+    } else {
+	$hash{'from_'.$goesto}=''.$linkid;
+    }
+}
+
+# ------------------------------------------------------------------- Condition
+sub parse_condition {
+    my ($token,$lpc) = @_;
+    my $rid=$lpc.'.'.$token->[2]->{'id'};
+    
+    $hash{'kind_'.$rid}='cond';
+
+    my $condition = $token->[2]->{'value'};
+    $condition =~ s/[\n\r]+/ /gs;
+    push(@cond, $condition);
+    $hash{'condid_'.$rid}=$#cond;
+    if ($token->[2]->{'type'}) {
+	$cond[$#cond].=':'.$token->[2]->{'type'};
+    }  else {
+	$cond[$#cond].=':normal';
+    }
+}
+
+# ------------------------------------------------------------------- Parameter
+
+sub parse_param {
+    my ($token,$lpc) = @_;
+    my $referid=$lpc.'.'.$token->[2]->{'to'};
+    my $name=$token->[2]->{'name'};
+    my $part;
+    if ($name=~/^parameter_(.*)_/) {
+	$part=$1;
+    } else {
+	$part=0;
+    }
+    $name=~s/^.*_([^_]*)$/$1/;
+    my $newparam=
+	&escape($token->[2]->{'type'}).':'.
+	&escape($part.'.'.$name).'='.
+	&escape($token->[2]->{'value'});
+    if (defined($hash{'param_'.$referid})) {
+	$hash{'param_'.$referid}.='&'.$newparam;
+    } else {
+	$hash{'param_'.$referid}=''.$newparam;
+    }
+    if ($token->[2]->{'name'}=~/^parameter_(0_)*randompick$/) {
+	$randompick{$referid}=$token->[2]->{'value'};
+    }
+    if ($token->[2]->{'name'}=~/^parameter_(0_)*randompickseed$/) {
+	$randompickseed{$referid}=$token->[2]->{'value'};
+    }
+    if ($token->[2]->{'name'}=~/^parameter_(0_)*randomorder$/) {
+	$randomorder{$referid}=$token->[2]->{'value'};
+    }
+    if ($token->[2]->{'name'}=~/^parameter_(0_)*encrypturl$/) {
+	if ($token->[2]->{'value'}=~/^yes$/i) {
+	    $encurl{$referid}=1;
+	}
+    }
+    if ($token->[2]->{'name'}=~/^parameter_(0_)*hiddenresource$/) {
+	if ($token->[2]->{'value'}=~/^yes$/i) {
+	    $hiddenurl{$referid}=1;
+	}
+    }
+}
+
 sub parse_mapalias_param {
     my ($token,$lpc) = @_;
     my $referid=$lpc.'.'.$token->[2]->{'to'};
@@ -609,7 +675,7 @@
 	$hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title');
 	$hash{'ids_'.$furi}='0.0';
 	$hash{'is_map_0.0'}=1;
-	loadmap($uri);
+	loadmap($uri,'0.0');
 	if (defined($hash{'map_start_'.$uri})) {
 	    &Apache::lonnet::appenv("request.course.id"  => $short,
 				    "request.course.fn"  => $fn,

--albertel1188348652--