--- rat/lonuserstate.pm 2009/11/15 14:08:53 1.132 +++ rat/lonuserstate.pm 2011/10/06 23:30:06 1.137.2.1 @@ -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.132 2009/11/15 14:08:53 raeburn Exp $ +# $Id: lonuserstate.pm,v 1.137.2.1 2011/10/06 23:30:06 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -62,6 +62,12 @@ my %hiddenurl; # this URL (or complete f # ----------------------------------- Remove version from URL and store in hash +sub versionerror { + my ($uri,$usedversion,$unusedversion)=@_; + return '
'.&mt('Version discrepancy: resource [_1] included in both version [_2] and version [_3]. Using version [_2].', + $uri,$usedversion,$unusedversion).'
'; +} + sub versiontrack { my $uri=shift; if ($uri=~/\.(\d+)\.\w+$/) { @@ -69,7 +75,9 @@ sub versiontrack { $uri=~s/\.\d+\.(\w+)$/\.$1/; unless ($hash{'version_'.$uri}) { $hash{'version_'.$uri}=$version; - } + } elsif ($version!=$hash{'version_'.$uri}) { + $errtext.=&versionerror($uri,$hash{'version_'.$uri},$version); + } } return $uri; } @@ -118,6 +126,15 @@ sub loadmap { my $lpc=$pc; $hash{'map_pc_'.$uri}=$lpc; $hash{'map_id_'.$lpc}=$uri; + if ($parent_rid =~ /^(\d+)\.\d+$/) { + my $parent_pc = $1; + if (defined($hash{'map_hierarchy_'.$parent_pc})) { + $hash{'map_hierarchy_'.$lpc}=$hash{'map_hierarchy_'.$parent_pc}.','. + $parent_pc; + } else { + $hash{'map_hierarchy_'.$lpc}=$parent_pc; + } + } # Determine and check filename my $fn=&Apache::lonnet::filelocation('',&putinversion($uri)); @@ -278,7 +295,7 @@ sub parse_resource { $hash{'ids_'.$idsuri}=''.$rid; } - if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard)$/) { + if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard|viewclasslist)$/) { $turi.='?register=1'; } @@ -420,7 +437,7 @@ sub simplify { # 8&8=8 $expression=~s/([^_\.\d])([_\.\d]+)\&\2([^_\.\d])/$1$2$3/g; # 8|8=8 - $expression=~s/([^_\.\d])([_\.\d]+)\|\2([^_\.\d])/$1$2$3/g; + $expression=~s/([^_\.\d])([_\.\d]+)(?:\|\2)+([^_\.\d])/$1$2$3/g; # (5&3)&4=5&3&4 $expression=~s/\(([_\.\d]+)((?:\&[_\.\d]+)+)\)\&([_\.\d]+[^_\.\d])/$1$2\&$3/g; # (((5&3)|(4&6)))=((5&3)|(4&6)) @@ -645,13 +662,17 @@ sub readmap { my $uri; $short=~s/\//\_/g; unless ($uri=$cenv{'url'}) { - &Apache::lonnet::logthis("WARNING: ". + &Apache::lonnet::logthis('WARNING: '. "Could not load course $short."); return ('',&mt('No course data available.'));; } @cond=('true:normal'); - open(LOCKFILE,">$fn.db.lock"); + unless (open(LOCKFILE,">$fn.db.lock")) { + $errtext.='
'.&mt('Map not loaded - Lock file could not be opened when reading map:').' '.$fn.'.'; + $retfurl = ''; + return ($retfurl,$errtext); + } my $lock=0; my $gotstate=0; if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { @@ -685,7 +706,6 @@ sub readmap { } } flock(LOCKFILE,LOCK_UN); - close(LOCKFILE); } unless ($lock && $tiedhash && $tiedparmhash) { # if we are here it is likely because we are already trying to @@ -708,7 +728,7 @@ sub readmap { untie(%parmhash); } } - &Apache::lonnet::logthis("WARNING: ". + &Apache::lonnet::logthis('WARNING: '. "Could not tie coursemap $fn for $uri."); $tiedhash = ''; $tiedparmhash = ''; @@ -740,6 +760,7 @@ sub readmap { } if ($lock) { flock(LOCKFILE,LOCK_UN); + $lock = 0; if ($tiedparmhash) { unless ($untiedparmhash) { &Apache::lonnet::logthis('WARNING: '. @@ -755,52 +776,49 @@ sub readmap { } } unless ($gotstate) { + $lock = 0; &Apache::lonnet::logthis('WARNING: '. 'Could not read statemap '.$fn.' for '.$uri.'.'); &unlink_tmpfiles($fn); - if (open(LOCKFILE,">$fn.db.lock")) { - my $lock=0; - if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { - $lock=1; - &unlink_tmpfiles($fn); - } - undef %randompick; - undef %hiddenurl; - undef %encurl; - $retfrid=''; - if ($lock) { - if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) { - if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) { - $gotstate = &build_tmp_hashes($uri,$fn,$short,\%cenv); - unless ($gotstate) { - &Apache::lonnet::logthis('WARNING: '. - 'Failed to write statemap at second attempt '.$fn.' for '.$uri.'.'); - } - unless (untie(%parmhash)) { - &Apache::lonnet::logthis('WARNING: '. - 'Could not untie coursemap parmhash '.$fn.'.db for '.$uri.'.'); - } - } else { + if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { + $lock=1; + } + undef %randompick; + undef %hiddenurl; + undef %encurl; + $retfrid=''; + if ($lock) { + if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) { + if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) { + $gotstate = &build_tmp_hashes($uri,$fn,$short,\%cenv); + unless ($gotstate) { &Apache::lonnet::logthis('WARNING: '. - 'Could not tie coursemap '.$fn.'__parms.db for '.$uri.'.'); + 'Failed to write statemap at second attempt '.$fn.' for '.$uri.'.'); } - unless (untie(%hash)) { + unless (untie(%parmhash)) { &Apache::lonnet::logthis('WARNING: '. - 'Could not untie coursemap hash '.$fn.'.db for '.$uri.'.'); + 'Could not untie coursemap parmhash '.$fn.'.db for '.$uri.'.'); } - } else { - &Apache::lonnet::logthis('WARNING: '. - 'Could not tie coursemap '.$fn.'.db for '.$uri.'.'); - } - flock(LOCKFILE,LOCK_UN); - close(LOCKFILE); + } else { + &Apache::lonnet::logthis('WARNING: '. + 'Could not tie coursemap '.$fn.'__parms.db for '.$uri.'.'); + } + unless (untie(%hash)) { + &Apache::lonnet::logthis('WARNING: '. + 'Could not untie coursemap hash '.$fn.'.db for '.$uri.'.'); + } } else { - &Apache::lonnet::logthis('WARNING: '. - 'Could not obtain lock to tie coursemap hash '.$fn.'.db for '.$uri.'.'); + &Apache::lonnet::logthis('WARNING: '. + 'Could not tie coursemap '.$fn.'.db for '.$uri.'.'); } - close(LOCKFILE); + flock(LOCKFILE,LOCK_UN); + $lock = 0; + } else { + &Apache::lonnet::logthis('WARNING: '. + 'Could not obtain lock to tie coursemap hash '.$fn.'.db for '.$uri.'.'); } } + close(LOCKFILE); unless (($errtext eq '') || ($env{'request.course.uri'} =~ m{^/uploaded/})) { &Apache::lonmsg::author_res_msg($env{'request.course.uri'}, $errtext); @@ -888,7 +906,7 @@ sub build_tmp_hashes { sub unlink_tmpfiles { my ($fn) = @_; - if ($fn =~ m{^\Q$Apache::lonnet::perlvar{'lonUsersDir'}\E/tmp/}) { + if ($fn =~ m{^\Q$Apache::lonnet::perlvar{'lonDaemons'}\E/tmp/}) { my @files = qw (.db _symb.db .state _parms.db); foreach my $file (@files) { if (-e $fn.$file) {