version 1.136, 2010/06/16 23:42:52
|
version 1.138, 2011/07/26 10:40:23
|
Line 43 use Opcode;
|
Line 43 use Opcode;
|
use Apache::lonenc; |
use Apache::lonenc; |
use Fcntl qw(:flock); |
use Fcntl qw(:flock); |
use LONCAPA; |
use LONCAPA; |
|
use File::Basename; |
|
|
|
|
|
|
# ---------------------------------------------------- Globals for this package |
# ---------------------------------------------------- Globals for this package |
|
|
my $pc; # Package counter |
my $pc; # Package counter is this what 'Guts' calls the map counter? |
my %hash; # The big tied hash |
my %hash; # The big tied hash |
my %parmhash;# The hash with the parameters |
my %parmhash;# The hash with the parameters |
my @cond; # Array with all of the conditions |
my @cond; # Array with all of the conditions |
Line 112 sub processversionfile {
|
Line 114 sub processversionfile {
|
} |
} |
} |
} |
|
|
# --------------------------------------------------------- Loads map from disk |
# --------------------------------------------------------- Loads from disk |
|
|
sub loadmap { |
sub loadmap { |
my ($uri,$parent_rid)=@_; |
my ($uri,$parent_rid)=@_; |
|
|
|
# Is the map already included? |
|
|
if ($hash{'map_pc_'.$uri}) { |
if ($hash{'map_pc_'.$uri}) { |
$errtext.='<p class="LC_error">'. |
$errtext.='<p class="LC_error">'. |
&mt('Multiple use of sequence/page [_1]! The course will not function properly.','<tt>'.$uri.'</tt>'). |
&mt('Multiple use of sequence/page [_1]! The course will not function properly.','<tt>'.$uri.'</tt>'). |
'</p>'; |
'</p>'; |
return; |
return; |
} |
} |
|
# Register the resource in it's map_pc_ [for the URL] |
|
# map_id.nnn is the nesting level -> to the URI. |
|
|
$pc++; |
$pc++; |
my $lpc=$pc; |
my $lpc=$pc; |
$hash{'map_pc_'.$uri}=$lpc; |
$hash{'map_pc_'.$uri}=$lpc; |
$hash{'map_id_'.$lpc}=$uri; |
$hash{'map_id_'.$lpc}=$uri; |
|
|
|
# If the parent is of the form n.m hang this map underneath it in the |
|
# map hierarchy. |
|
|
if ($parent_rid =~ /^(\d+)\.\d+$/) { |
if ($parent_rid =~ /^(\d+)\.\d+$/) { |
my $parent_pc = $1; |
my $parent_pc = $1; |
if (defined($hash{'map_hierarchy_'.$parent_pc})) { |
if (defined($hash{'map_hierarchy_'.$parent_pc})) { |
Line 136 sub loadmap {
|
Line 148 sub loadmap {
|
} |
} |
} |
} |
|
|
# Determine and check filename |
# Determine and check filename of the sequence we need to read: |
|
|
my $fn=&Apache::lonnet::filelocation('',&putinversion($uri)); |
my $fn=&Apache::lonnet::filelocation('',&putinversion($uri)); |
|
|
my $ispage=($fn=~/\.page$/); |
my $ispage=($fn=~/\.page$/); |
|
|
unless (($fn=~/\.sequence$/) || |
# We can only nest sequences or pages. Anything else is an illegal nest. |
($fn=~/\.page$/)) { |
|
|
unless (($fn=~/\.sequence$/) || $ispage) { |
$errtext.=&mt("<br />Invalid map: <tt>[_1]</tt>",$fn); |
$errtext.=&mt("<br />Invalid map: <tt>[_1]</tt>",$fn); |
return; |
return; |
} |
} |
|
|
|
# Read the XML that constitutes the file. |
|
|
my $instr=&Apache::lonnet::getfile($fn); |
my $instr=&Apache::lonnet::getfile($fn); |
|
|
if ($instr eq -1) { |
if ($instr eq -1) { |
Line 154 sub loadmap {
|
Line 170 sub loadmap {
|
return; |
return; |
} |
} |
|
|
# Successfully got file, parse it |
# Successfully got file, parse it |
|
|
|
# parse for parameter processing. |
|
# Note that these are <param... / > tags |
|
# so we only care about 'S' (tag start) nodes. |
|
|
|
|
my $parser = HTML::TokeParser->new(\$instr); |
my $parser = HTML::TokeParser->new(\$instr); |
$parser->attr_encoded(1); |
$parser->attr_encoded(1); |
|
|
# first get all parameters |
# first get all parameters |
|
|
|
|
while (my $token = $parser->get_token) { |
while (my $token = $parser->get_token) { |
next if ($token->[0] ne 'S'); |
next if ($token->[0] ne 'S'); |
if ($token->[1] eq 'param') { |
if ($token->[1] eq 'param') { |
&parse_param($token,$lpc); |
&parse_param($token,$lpc); |
} |
} |
} |
} |
#reset parser |
|
|
# Get set to take another pass through the XML: |
|
# for resources and links. |
|
|
$parser = HTML::TokeParser->new(\$instr); |
$parser = HTML::TokeParser->new(\$instr); |
$parser->attr_encoded(1); |
$parser->attr_encoded(1); |
|
|
Line 177 sub loadmap {
|
Line 204 sub loadmap {
|
|
|
my $randomize = ($randomorder{$parent_rid} =~ /^yes$/i); |
my $randomize = ($randomorder{$parent_rid} =~ /^yes$/i); |
|
|
|
# Parse the resources, link and condition tags. |
|
# Note that if randomorder or random select is chosen the links and |
|
# conditions are meaningless but are determined by the randomization. |
|
# This is handled in the next chunk of code. |
|
|
my @map_ids; |
my @map_ids; |
while (my $token = $parser->get_token) { |
while (my $token = $parser->get_token) { |
next if ($token->[0] ne 'S'); |
next if ($token->[0] ne 'S'); |
|
|
|
# Resource |
|
|
if ($token->[1] eq 'resource') { |
if ($token->[1] eq 'resource') { |
push(@map_ids,&parse_resource($token,$lpc,$ispage,$uri)); |
my $resource_id = &parse_resource($token,$lpc,$ispage,$uri); |
|
if (defined $resource_id) { |
|
push(@map_ids, $resource_id); |
|
} |
|
|
|
# Link |
|
|
} elsif ($token->[1] eq 'link' && !$randomize) { |
} elsif ($token->[1] eq 'link' && !$randomize) { |
# ----------------------------------------------------------------------- Links |
|
&make_link(++$linkpc,$lpc,$token->[2]->{'to'}, |
&make_link(++$linkpc,$lpc,$token->[2]->{'to'}, |
$token->[2]->{'from'}, |
$token->[2]->{'from'}, |
$token->[2]->{'condition'}); |
$token->[2]->{'condition'}); |
|
|
|
# condition |
|
|
} elsif ($token->[1] eq 'condition' && !$randomize) { |
} elsif ($token->[1] eq 'condition' && !$randomize) { |
&parse_condition($token,$lpc); |
&parse_condition($token,$lpc); |
} |
} |
} |
} |
|
|
|
|
|
# Handle randomization and random selection |
|
|
if ($randomize) { |
if ($randomize) { |
if (!$env{'request.role.adv'}) { |
if (!$env{'request.role.adv'}) { |
my $seed; |
my $seed; |
Line 205 sub loadmap {
|
Line 251 sub loadmap {
|
|
|
$seed = $symb; |
$seed = $symb; |
} |
} |
|
|
|
# Here for sure we need to pass along the username/domain |
|
# so that we can impersonate users in lonprintout e.g. |
|
|
my $rndseed=&Apache::lonnet::rndseed($seed); |
my $rndseed=&Apache::lonnet::rndseed($seed); |
&Apache::lonnet::setup_random_from_rndseed($rndseed); |
&Apache::lonnet::setup_random_from_rndseed($rndseed); |
@map_ids=&Math::Random::random_permutation(@map_ids); |
@map_ids=&Math::Random::random_permutation(@map_ids); |
Line 241 sub loadmap {
|
Line 290 sub loadmap {
|
|
|
|
|
# -------------------------------------------------------------------- Resource |
# -------------------------------------------------------------------- Resource |
|
# |
|
# Parses a resource tag to produce the value to push into the |
|
# map_ids array. |
|
# |
|
# |
|
# Information about the actual type of resource is provided by the file extension |
|
# of the uri (e.g. .problem, .sequence etc. etc.). |
|
# |
|
# Parameters: |
|
# $token - A token from HTML::TokeParser |
|
# This is an array that describes the most recently parsed HTML item. |
|
# $lpc - Map nesting level (?) |
|
# $ispage - True if this resource is encapsulated in a .page (assembled resourcde). |
|
# $uri - URI of the enclosing resource. |
|
# Returns: |
|
# |
|
# Note: |
|
# The token is an array that contains the following elements: |
|
# [0] => 'S' indicating this is a start token |
|
# [1] => 'resource' indicating this tag is a <resource> tag. |
|
# [2] => Hash of attribute =>value pairs. |
|
# [3] => @(keys [2]). |
|
# [4] => unused. |
|
# |
|
# The attributes of the resourcde tag include: |
|
# |
|
# id - The resource id. |
|
# src - The URI of the resource. |
|
# type - The resource type (e.g. start and finish). |
|
# title - The resource title. |
|
|
|
|
sub parse_resource { |
sub parse_resource { |
my ($token,$lpc,$ispage,$uri) = @_; |
my ($token,$lpc,$ispage,$uri) = @_; |
if ($token->[2]->{'type'} eq 'zombie') { next; } |
|
|
# I refuse to coutenance code like this that has |
|
# such a dirty side effect (and forcing this sub to be called within a loop). |
|
# |
|
# if ($token->[2]->{'type'} eq 'zombie') { next; } |
|
|
|
# Zombie resources don't produce anything useful. |
|
|
|
if ($token->[2]->{'type'} eq 'zombie') { |
|
return undef; |
|
} |
|
|
my $rid=$lpc.'.'.$token->[2]->{'id'}; |
my $rid=$lpc.'.'.$token->[2]->{'id'}; |
|
|
$hash{'kind_'.$rid}='res'; |
$hash{'kind_'.$rid}='res'; |
Line 373 sub parse_condition {
|
Line 465 sub parse_condition {
|
} |
} |
|
|
# ------------------------------------------------------------------- Parameter |
# ------------------------------------------------------------------- Parameter |
|
# Parse a <parameter> tag in the map. |
|
# Parmameters: |
|
# $token Token array for a start tag from HTML::TokeParser |
|
# [0] = 'S' |
|
# [1] = tagname ("param") |
|
# [2] = Hash of {attribute} = values. |
|
# [3] = Array of the keys in [2]. |
|
# [4] = unused. |
|
# $lpc Current map nesting level.a |
|
# |
|
# Typical attributes: |
|
# to=n - Number of the resource the parameter applies to. |
|
# type=xx - Type of parameter value (e.g. string_yesno or int_pos). |
|
# name=xxx - Name ofr parameter (e.g. parameter_randompick or parameter_randomorder). |
|
# value=xxx - value of the parameter. |
|
|
sub parse_param { |
sub parse_param { |
my ($token,$lpc) = @_; |
my ($token,$lpc) = @_; |
my $referid=$lpc.'.'.$token->[2]->{'to'}; |
my $referid=$lpc.'.'.$token->[2]->{'to'}; # Resource param applies to. |
my $name=$token->[2]->{'name'}; |
my $name=$token->[2]->{'name'}; # Name of parameter |
my $part; |
my $part; |
if ($name=~/^parameter_(.*)_/) { |
|
|
|
|
if ($name=~/^parameter_(.*)_/) { |
$part=$1; |
$part=$1; |
} else { |
} else { |
$part=0; |
$part=0; |
} |
} |
|
|
|
# Peel the parameter_ off the parameter name. |
|
|
$name=~s/^.*_([^_]*)$/$1/; |
$name=~s/^.*_([^_]*)$/$1/; |
|
|
|
# The value is: |
|
# type.part.name.value |
|
|
my $newparam= |
my $newparam= |
&escape($token->[2]->{'type'}).':'. |
&escape($token->[2]->{'type'}).':'. |
&escape($part.'.'.$name).'='. |
&escape($part.'.'.$name).'='. |
&escape($token->[2]->{'value'}); |
&escape($token->[2]->{'value'}); |
|
|
|
# The hash key is param_resourceid. |
|
# Multiple parameters for a single resource are & separated in the hash. |
|
|
|
|
if (defined($hash{'param_'.$referid})) { |
if (defined($hash{'param_'.$referid})) { |
$hash{'param_'.$referid}.='&'.$newparam; |
$hash{'param_'.$referid}.='&'.$newparam; |
} else { |
} else { |
$hash{'param_'.$referid}=''.$newparam; |
$hash{'param_'.$referid}=''.$newparam; |
} |
} |
if ($token->[2]->{'name'}=~/^parameter_(0_)*randompick$/) { |
# |
|
# These parameters have to do with randomly selecting |
|
# resources, therefore a separate hash is also created to |
|
# make it easy to locate them when actually computing the resource set later on |
|
# See the code conditionalized by ($randomize) in loadmap(). |
|
|
|
if ($token->[2]->{'name'}=~/^parameter_(0_)*randompick$/) { # Random selection turned on |
$randompick{$referid}=$token->[2]->{'value'}; |
$randompick{$referid}=$token->[2]->{'value'}; |
} |
} |
if ($token->[2]->{'name'}=~/^parameter_(0_)*randompickseed$/) { |
if ($token->[2]->{'name'}=~/^parameter_(0_)*randompickseed$/) { # Randomseed provided. |
$randompickseed{$referid}=$token->[2]->{'value'}; |
$randompickseed{$referid}=$token->[2]->{'value'}; |
} |
} |
if ($token->[2]->{'name'}=~/^parameter_(0_)*randomorder$/) { |
if ($token->[2]->{'name'}=~/^parameter_(0_)*randomorder$/) { # Random order turned on. |
$randomorder{$referid}=$token->[2]->{'value'}; |
$randomorder{$referid}=$token->[2]->{'value'}; |
} |
} |
|
|
|
# These parameters have to do with how the URLs of resources are presented to |
|
# course members(?). encrypturl presents encypted url's while |
|
# hiddenresource hides the URL. |
|
# |
|
|
if ($token->[2]->{'name'}=~/^parameter_(0_)*encrypturl$/) { |
if ($token->[2]->{'name'}=~/^parameter_(0_)*encrypturl$/) { |
if ($token->[2]->{'value'}=~/^yes$/i) { |
if ($token->[2]->{'value'}=~/^yes$/i) { |
$encurl{$referid}=1; |
$encurl{$referid}=1; |
Line 657 sub hiddenurls {
|
Line 790 sub hiddenurls {
|
sub readmap { |
sub readmap { |
my $short=shift; |
my $short=shift; |
$short=~s/^\///; |
$short=~s/^\///; |
my %cenv=&Apache::lonnet::coursedescription($short,{'freshen_cache'=>1}); |
|
|
# TODO: Hidden dependency on current user: |
|
|
|
my %cenv=&Apache::lonnet::coursedescription($short,{'freshen_cache'=>1}); |
|
|
my $fn=$cenv{'fn'}; |
my $fn=$cenv{'fn'}; |
my $uri; |
my $uri; |
$short=~s/\//\_/g; |
$short=~s/\//\_/g; |
Line 669 sub readmap {
|
Line 806 sub readmap {
|
@cond=('true:normal'); |
@cond=('true:normal'); |
|
|
unless (open(LOCKFILE,">$fn.db.lock")) { |
unless (open(LOCKFILE,">$fn.db.lock")) { |
|
# |
|
# Most likely a permissions problem on the lockfile or its directory. |
|
# |
$errtext.='<br />'.&mt('Map not loaded - Lock file could not be opened when reading map:').' <tt>'.$fn.'</tt>.'; |
$errtext.='<br />'.&mt('Map not loaded - Lock file could not be opened when reading map:').' <tt>'.$fn.'</tt>.'; |
$retfurl = ''; |
$retfurl = ''; |
return ($retfurl,$errtext); |
return ($retfurl,$errtext); |
} |
} |
my $lock=0; |
my $lock=0; |
my $gotstate=0; |
my $gotstate=0; |
if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { |
|
$lock=1; |
# If we can get the lock without delay any files there are idle |
|
# and from some prior request. We'll kill them off and regenerate them: |
|
|
|
if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { |
|
$lock=1; # Remember that we hold the lock. |
&unlink_tmpfiles($fn); |
&unlink_tmpfiles($fn); |
} |
} |
undef %randompick; |
undef %randompick; |
undef %hiddenurl; |
undef %hiddenurl; |
undef %encurl; |
undef %encurl; |
$retfrid=''; |
$retfrid=''; |
my ($untiedhash,$untiedparmhash,$tiedhash,$tiedparmhash); |
my ($untiedhash,$untiedparmhash,$tiedhash,$tiedparmhash); # More state flags. |
|
|
|
# if we got the lock, regenerate course regnerate empty files and tie them. |
|
|
if ($lock) { |
if ($lock) { |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) { |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) { |
$tiedhash = 1; |
$tiedhash = 1; |
if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) { |
if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) { |
$tiedparmhash = 1; |
$tiedparmhash = 1; |
$gotstate = &build_tmp_hashes($uri,$fn,$short,\%cenv); |
$gotstate = &build_tmp_hashes($uri, |
|
$fn, |
|
$short, |
|
\%cenv); # TODO: Need to provide requested user@dom |
unless ($gotstate) { |
unless ($gotstate) { |
&Apache::lonnet::logthis('Failed to write statemap at first attempt '.$fn.' for '.$uri.'.</font>'); |
&Apache::lonnet::logthis('Failed to write statemap at first attempt '.$fn.' for '.$uri.'.</font>'); |
} |
} |
Line 705 sub readmap {
|
Line 855 sub readmap {
|
'Could not untie coursemap hash '.$fn.' for '.$uri.'.</font>'); |
'Could not untie coursemap hash '.$fn.' for '.$uri.'.</font>'); |
} |
} |
} |
} |
flock(LOCKFILE,LOCK_UN); |
flock(LOCKFILE,LOCK_UN); # RF: this is what I don't get unless there are other |
|
# unlocked places the remainder happens..seems like if we |
|
# just kept the lock here the rest of the code would have |
|
# been much easier? |
} |
} |
unless ($lock && $tiedhash && $tiedparmhash) { |
unless ($lock && $tiedhash && $tiedparmhash) { |
# if we are here it is likely because we are already trying to |
# if we are here it is likely because we are already trying to |
Line 713 sub readmap {
|
Line 866 sub readmap {
|
# tie the hashes for the next 90 seconds, if we succeed forward |
# tie the hashes for the next 90 seconds, if we succeed forward |
# them on to navmaps, if we fail, throw up the Could not init |
# them on to navmaps, if we fail, throw up the Could not init |
# course screen |
# course screen |
|
# |
|
# RF: I'm not seeing the case where the ties/unties can fail in a way |
|
# that can be remedied by this. Since we owned the lock seems |
|
# Tie/untie failures are a result of something like a permissions problem instead? |
|
# |
|
|
|
# In any vent, undo what we did manage to do above first: |
if ($lock) { |
if ($lock) { |
# Got the lock but not the DB files |
# Got the lock but not the DB files |
flock(LOCKFILE,LOCK_UN); |
flock(LOCKFILE,LOCK_UN); |
Line 728 sub readmap {
|
Line 888 sub readmap {
|
untie(%parmhash); |
untie(%parmhash); |
} |
} |
} |
} |
|
# Log our failure: |
|
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
"Could not tie coursemap $fn for $uri.</font>"); |
"Could not tie coursemap $fn for $uri.</font>"); |
$tiedhash = ''; |
$tiedhash = ''; |
$tiedparmhash = ''; |
$tiedparmhash = ''; |
my $i=0; |
my $i=0; |
|
|
|
# Keep on retrying the lock for 90 sec until we succeed. |
|
|
while($i<90) { |
while($i<90) { |
$i++; |
$i++; |
sleep(1); |
sleep(1); |
if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { |
if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { |
|
|
|
# Got the lock, tie the hashes...the assumption in this code is |
|
# that some other worker thread has created the db files quite recently |
|
# so no load is needed: |
|
|
$lock = 1; |
$lock = 1; |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640)) { |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640)) { |
$tiedhash = 1; |
$tiedhash = 1; |
Line 744 sub readmap {
|
Line 914 sub readmap {
|
$tiedparmhash = 1; |
$tiedparmhash = 1; |
if (-e "$fn.state") { |
if (-e "$fn.state") { |
$retfurl='/adm/navmaps'; |
$retfurl='/adm/navmaps'; |
|
|
|
# BUG BUG: Side effect! |
|
# Should conditionalize on something so that we can use this |
|
# to load maps for courses that are not current? |
|
# |
&Apache::lonnet::appenv({"request.course.id" => $short, |
&Apache::lonnet::appenv({"request.course.id" => $short, |
"request.course.fn" => $fn, |
"request.course.fn" => $fn, |
"request.course.uri" => $uri}); |
"request.course.uri" => $uri}); |
Line 775 sub readmap {
|
Line 950 sub readmap {
|
} |
} |
} |
} |
} |
} |
|
# I think this branch of code is all about what happens if we just did the stuff above, |
|
# but found that the state file did not exist...again if we'd just held the lock |
|
# would that have made this logic simpler..as generating all the files would be |
|
# an atomic operation with respect to the lock. |
|
# |
unless ($gotstate) { |
unless ($gotstate) { |
$lock = 0; |
$lock = 0; |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
Line 787 sub readmap {
|
Line 967 sub readmap {
|
undef %hiddenurl; |
undef %hiddenurl; |
undef %encurl; |
undef %encurl; |
$retfrid=''; |
$retfrid=''; |
|
# |
|
# Once more through the routine of tying and loading and so on. |
|
# |
if ($lock) { |
if ($lock) { |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) { |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) { |
if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) { |
if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) { |
$gotstate = &build_tmp_hashes($uri,$fn,$short,\%cenv); |
$gotstate = &build_tmp_hashes($uri,$fn,$short,\%cenv); # TODO: User dependent? |
unless ($gotstate) { |
unless ($gotstate) { |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
'Failed to write statemap at second attempt '.$fn.' for '.$uri.'.</font>'); |
'Failed to write statemap at second attempt '.$fn.' for '.$uri.'.</font>'); |
Line 814 sub readmap {
|
Line 997 sub readmap {
|
flock(LOCKFILE,LOCK_UN); |
flock(LOCKFILE,LOCK_UN); |
$lock = 0; |
$lock = 0; |
} else { |
} else { |
|
# Failed to get the immediate lock. |
|
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
'Could not obtain lock to tie coursemap hash '.$fn.'.db for '.$uri.'.</font>'); |
'Could not obtain lock to tie coursemap hash '.$fn.'.db for '.$uri.'.</font>'); |
} |
} |
Line 821 sub readmap {
|
Line 1006 sub readmap {
|
close(LOCKFILE); |
close(LOCKFILE); |
unless (($errtext eq '') || ($env{'request.course.uri'} =~ m{^/uploaded/})) { |
unless (($errtext eq '') || ($env{'request.course.uri'} =~ m{^/uploaded/})) { |
&Apache::lonmsg::author_res_msg($env{'request.course.uri'}, |
&Apache::lonmsg::author_res_msg($env{'request.course.uri'}, |
$errtext); |
$errtext); # TODO: User dependent? |
} |
} |
# ------------------------------------------------- Check for critical messages |
# ------------------------------------------------- Check for critical messages |
|
|
|
# Depends on user must parameterize this as well..or separate as this is: |
|
# more part of determining what someone sees on entering a course? |
|
|
my @what=&Apache::lonnet::dump('critical',$env{'user.domain'}, |
my @what=&Apache::lonnet::dump('critical',$env{'user.domain'}, |
$env{'user.name'}); |
$env{'user.name'}); |
if ($what[0]) { |
if ($what[0]) { |
Line 835 sub readmap {
|
Line 1023 sub readmap {
|
return ($retfurl,$errtext); |
return ($retfurl,$errtext); |
} |
} |
|
|
|
# |
|
# This sub is called when the course hash and the param hash have been tied and |
|
# their lock file is held. |
|
# Parameters: |
|
# $uri - URI that identifies the course. |
|
# $fn - The base path/filename of the files that make up the context |
|
# being built. |
|
# $short - Short course name. |
|
# $cenvref - Reference to the course environment hash returned by |
|
# Apache::lonnet::coursedescription |
|
# |
|
# Assumptions: |
|
# The globals |
|
# %hash, %paramhash are tied to their gdbm files and we hold the lock on them. |
|
# |
sub build_tmp_hashes { |
sub build_tmp_hashes { |
my ($uri,$fn,$short,$cenvref) = @_; |
my ($uri,$fn,$short,$cenvref) = @_; |
|
|
unless(ref($cenvref) eq 'HASH') { |
unless(ref($cenvref) eq 'HASH') { |
return; |
return; |
} |
} |
my %cenv = %{$cenvref}; |
my %cenv = %{$cenvref}; |
my $gotstate = 0; |
my $gotstate = 0; |
%hash=(); |
%hash=(); # empty the global course and parameter hashes. |
%parmhash=(); |
%parmhash=(); |
$errtext=''; |
$errtext=''; # No error messages yet. |
$pc=0; |
$pc=0; |
&clear_mapalias_count(); |
&clear_mapalias_count(); |
&processversionfile(%cenv); |
&processversionfile(%cenv); |
my $furi=&Apache::lonnet::clutter($uri); |
my $furi=&Apache::lonnet::clutter($uri); |
|
# |
|
# the map staring points. |
|
# |
$hash{'src_0.0'}=&versiontrack($furi); |
$hash{'src_0.0'}=&versiontrack($furi); |
$hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title'); |
$hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title'); |
$hash{'ids_'.$furi}='0.0'; |
$hash{'ids_'.$furi}='0.0'; |
Line 906 sub build_tmp_hashes {
|
Line 1113 sub build_tmp_hashes {
|
|
|
sub unlink_tmpfiles { |
sub unlink_tmpfiles { |
my ($fn) = @_; |
my ($fn) = @_; |
if ($fn =~ m{^\Q$Apache::lonnet::perlvar{'lonUsersDir'}\E/tmp/}) { |
my $file_dir = dirname($fn); |
|
|
|
if ($fn eq LONCAPA::tempdir()) { |
my @files = qw (.db _symb.db .state _parms.db); |
my @files = qw (.db _symb.db .state _parms.db); |
foreach my $file (@files) { |
foreach my $file (@files) { |
if (-e $fn.$file) { |
if (-e $fn.$file) { |
Line 960 sub evalstate {
|
Line 1169 sub evalstate {
|
return $state; |
return $state; |
} |
} |
|
|
|
# This block seems to have code to manage/detect doubly defined |
|
# aliases in maps. |
|
|
{ |
{ |
my %mapalias_cache; |
my %mapalias_cache; |
sub count_mapalias { |
sub count_mapalias { |