--- loncom/lonmap.pm 2011/09/13 10:27:52 1.2 +++ loncom/lonmap.pm 2011/10/06 10:56:49 1.3 @@ -2,7 +2,7 @@ # # Read maps into a 'big hash'. # -# $Id: lonmap.pm,v 1.2 2011/09/13 10:27:52 foxr Exp $ +# $Id: lonmap.pm,v 1.3 2011/10/06 10:56:49 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -28,7 +28,7 @@ # ### -package lonmap; +package Apache::lonmap; use strict; #------------- Required external modules. @@ -40,10 +40,12 @@ use HTML::TokeParser; use LONCAPA; use Apache::lonnet; +use Data::Dumper; + #------------- File scoped variables: -my $map_number = 1; # keep track of maps within the course. +my $map_number = 0; # keep track of maps within the course. my $course_id; # Will be the id of the course being read in. # @@ -67,6 +69,7 @@ my $retfrid; my $username; # User for whom the map is being read. my $userdomain; # Domain the user lives in. my %mapalias_cache; # Keeps track of map aliases -> resources detects duplicates. +my %cenv; # Course environment. #------------- Executable code: @@ -149,8 +152,12 @@ sub merge_conditions { sub merge_hash { my ($parent, $key, $child) = @_; + if ($key ne '') { + $key .= '.'; # If we are prefixing, prefix then . + } + foreach my $childkey (keys (%$child)) { - $parent->{$key . '.' . $childkey} = $child->{$childkey}; + $parent->{$key . $childkey} = $child->{$childkey}; } } @@ -308,7 +315,7 @@ sub versionerror { # Returns: # URI with the version cut out. # -sub vesiontrack { +sub versiontrack { my ($uri, $hash) = @_; @@ -371,6 +378,10 @@ sub append_version { sub hiddenurls { my $hash = shift; + my $uname = $hash->{'context.username'}; + my $udom = $hash->{'context.userdom'}; + my $courseid = $hash->{'context.courseid'}; + my $randomoutentry=''; foreach my $rid (keys %randompick) { my $rndpick=$randompick{$rid}; @@ -393,15 +404,16 @@ sub hiddenurls { # -------------------------------- randomly eliminate the ones that should stay my (undef,$id)=split(/\./,$rid); if ($randompickseed{$rid}) { $id=$randompickseed{$rid}; } - my $rndseed=&Apache::lonnet::rndseed($id); # use id instead of symb + my $rndseed=&Apache::lonnet::rndseed($id, $courseid, $udom, $uname, \%cenv); # use id instead of symb + &Apache::lonnet::logthis("lonmap random seed: $rndseed"); &Apache::lonnet::setup_random_from_rndseed($rndseed); my @whichids=&Math::Random::random_permuted_index($#currentrids+1); for (my $i=1;$i<=$rndpick;$i++) { $currentrids[$whichids[$i]]=''; } - #&Apache::lonnet::logthis("$id,$rndseed,".join(':',@whichids)); + # -------------------------------------------------------- delete the leftovers for (my $k=0; $k<=$#currentrids; $k++) { if ($currentrids[$k]) { - $hash->{'randomout_'.$currentrids[$k]}=1; + $hash->{'randomout_'.$currentrids[$k]}='1'; my ($mapid,$resid)=split(/\./,$currentrids[$k]); $randomoutentry.='&'. &Apache::lonnet::encode_symb($hash->{'map_id_'.$mapid}, @@ -413,7 +425,7 @@ sub hiddenurls { } # ------------------------------ take care of explicitly hidden urls or folders foreach my $rid (keys %hiddenurl) { - $hash->{'randomout_'.$rid}=1; + $hash->{'randomout_'.$rid}='1'; my ($mapid,$resid)=split(/\./,$rid); $randomoutentry.='&'. &Apache::lonnet::encode_symb($hash->{'map_id_'.$mapid},$resid, @@ -437,7 +449,7 @@ sub hiddenurls { # sub accinit { - my ($uri, $short, $fn, $hash)=@_; + my ($uri, $short, $hash)=@_; my %acchash=(); my %captured=(); my $condcounter=0; @@ -615,7 +627,7 @@ sub traceroute { $hash->{'map_start_'.$hash->{'src_'.$rid}}, $beenhere, $encflag || $encurl{$rid}, - $hdnflag || $hiddenurl{$rid}); + $hdnflag || $hiddenurl{$rid}, $hash); } } @@ -641,7 +653,7 @@ sub traceroute { } # Recurse to resoruces that have to's to us. $newsofar=&traceroute($further,$hash->{'goesto_'.$id},$beenhere, - $encflag,$hdnflag); + $encflag,$hdnflag, $hash); } } } @@ -931,7 +943,7 @@ sub parse_resource { if (($turi=~/\.sequence$/) || ($turi=~/\.page$/)) { - $hash->{'is_map_'.$rid}=1; + $hash->{'is_map_'.$rid}='1'; # String in lonuserstate. &read_map($turi,$rid, $hash); } return $token->[2]->{'id'}; @@ -969,7 +981,7 @@ sub make_link { my $linkid=$lpc.'.'.$linkpc; my $goesto=$lpc.'.'.$to; my $comesfrom=$lpc.'.'.$from; - my $undercond=0; + my $undercond='0'; # If there is a condition, qualify it with the level counter. @@ -1152,6 +1164,7 @@ sub parse_mapalias_param { sub read_map { my ($uri, $parent_rid, $hash) = @_; + # Check for duplication: A map may only be included once. if($hash->{'map_pc_' . $uri}) { @@ -1167,8 +1180,8 @@ sub read_map { # map_pc_uri is the map number of the map with that URI. # map_id_$lmap_no is the URI for this map level. # - $hash->{'map_pc_' . $uri} = $lmap_no; - $hash->{'map_id_' . $lmap_no} = $uri; + $hash->{'map_pc_' . $uri} = "$lmap_no"; # string form in lonuserstate. + $hash->{'map_id_' . $lmap_no} = "$uri"; # Create the path up to the top of the course. # this is in 'map_hierarchy_mapno' that's a comma separated path down to us @@ -1191,6 +1204,8 @@ sub read_map { # sorts of files that make sense for this sub my $filename = &Apache::lonnet::filelocation('', &append_version($uri, $hash)); + + my $ispage = ($filename =~/\.page$/); unless ($ispage || ($filename =~ /\.sequence$/)) { throw Error::Simple(&mt("
Invalid map: [_1]", $filename)); @@ -1202,7 +1217,7 @@ sub read_map { # Repcopy the file and get its contents...report errors if we can't - my $contents = &Apache::lonet::getfile($filename); + my $contents = &Apache::lonnet::getfile($filename); if($contents eq -1) { throw Error::Simple(&mt('
Map not loaded: The file [_1] does not exist.', $filename)); @@ -1315,7 +1330,7 @@ sub read_map { # if randomorder was set. This means that for an instructor to choose while (my $to = shift(@map_ids)) { - &make_link(++$linkpc,$lmap_no,$to,$from); + &make_link(++$linkpc,$lmap_no,$to,$from, 0, $hash); my $to_rid = $lmap_no.'.'.$to; $hash->{'type_'.$to_rid}='normal'; $from = $to; @@ -1360,7 +1375,9 @@ sub read_map { # # sub loadmap { - my ($cnum, $cdom, $uname, $udom, $filepath, $target_hash) = @_; + my ($cnum, $cdom, $uname, $udom, $target_hash) = @_; + + # Clear the auxillary hashes and the cond array. @@ -1372,6 +1389,10 @@ sub loadmap { %parmhash = (); @cond = (); $retfrid = ''; + $username = ''; + $userdomain = ''; + %mapalias_cache = (); + %cenv = (); # @@ -1379,7 +1400,8 @@ sub loadmap { $username = $uname; $userdomain = $udom; - my $short_name = $cdom . $cnum; + my $short_name = $cdom .'/' . $cnum; + my $retfurl; try { @@ -1387,14 +1409,17 @@ sub loadmap { # Get the information we need about the course. # Return without filling in anything if we can't get any info: - my %cenv = &Apache::lonnet::coursedescription($short_name, + %cenv = &Apache::lonnet::coursedescription($short_name, {'freshen_cache' => 1, 'user' => $uname}); + unless ($cenv{'url'}) { &Apache::lonnet::logthis("lonmap::loadmap failed: $cnum/$cdom - did not get url"); return; } - $course_id = $cdom . '.' . $cnum; # Long course id. + &Apache::lonnet::logthis("Course environment: \n" . Dumper(\%cenv)); + + $course_id = $cdom . '_' . $cnum; # Long course id. # Load the version information into the hash @@ -1409,16 +1434,27 @@ sub loadmap { $target_hash->{'src_0.0'} = &versiontrack($map_uri, $target_hash); $target_hash->{'title_0.0'} = &Apache::lonnet::metadata($course_uri, 'title'); + if(!defined $target_hash->{'title_0.0'}) { + $target_hash->{'title_0.0'} = ''; + } $target_hash->{'ids_'.$map_uri} = '0.0'; - $target_hash->{'is_map_0.0'} = 1; - &read_map($course_uri, '0.0', &hash); + $target_hash->{'is_map_0.0'} = '1'; + + # In some places we need a username a domain and the courseid...store that + # in the target hash in the context.xxxx keys: + + $target_hash->{'context.username'} = $username; + $target_hash->{'context.userdom'} = $userdomain; + $target_hash->{'context.courseid'} = $course_id; + + &read_map($course_uri, '0.0', $target_hash); # if (defined($target_hash->{'map_start_'.$map_uri})) { - &traceroute('0',$target_hash->{'map_start_'.$course_uri},'&', $target_hash); - &accinit($course_uri, $short_name, $filepath, $target_hash); + &traceroute('0',$target_hash->{'map_start_'.$course_uri},'&', 0, 0, $target_hash); + &accinit($course_uri, $short_name, $target_hash); &hiddenurls($target_hash); } my $errors = &get_mapalias_errors($target_hash); @@ -1438,6 +1474,26 @@ sub loadmap { $target_hash->{$type.&putinversion($url, $target_hash, $short_name)}=$value; } } + # Mark necrypted URLS. + + foreach my $id (keys(%encurl)) { + $target_hash->{'encrypted_'.$id}=1; + } + + # Store first keys. + + $target_hash->{'first_rid'}=$retfrid; + my ($mapid,$resid)=split(/\./,$retfrid); + $target_hash->{'first_mapurl'}=$target_hash->{'map_id_'.$mapid}; + my $symb=&Apache::lonnet::encode_symb($target_hash->{'map_id_'.$mapid}, + $resid, + $target_hash->{'src_'.$retfrid}); + $retfurl=&add_get_param($target_hash->{'src_'.$retfrid},{ 'symb' => $symb }); + if ($target_hash->{'encrypted_'.$retfrid}) { + $retfurl=&Apache::lonenc::encrypted($retfurl, + (&Apache::lonnet::allowed('adv') ne 'F')); + } + $target_hash->{'first_url'}=$retfurl; # Merge in the child hashes in case the caller wants that information as well. @@ -1462,7 +1518,7 @@ sub loadmap { # # Module initialization code: -# +# TODO: Fix the pod docs below. 1; __END__