version 1.128.2.2, 2009/03/21 06:12:05
|
version 1.135, 2010/03/25 17:38:52
|
Line 62 my %hiddenurl; # this URL (or complete f
|
Line 62 my %hiddenurl; # this URL (or complete f
|
|
|
# ----------------------------------- Remove version from URL and store in hash |
# ----------------------------------- Remove version from URL and store in hash |
|
|
|
sub versionerror { |
|
my ($uri,$usedversion,$unusedversion)=@_; |
|
return '<br />'.&mt('Version discrepancy: resource [_1] included in both version [_2] and version [_3]. Using version [_2].', |
|
$uri,$usedversion,$unusedversion).'<br />'; |
|
} |
|
|
sub versiontrack { |
sub versiontrack { |
my $uri=shift; |
my $uri=shift; |
if ($uri=~/\.(\d+)\.\w+$/) { |
if ($uri=~/\.(\d+)\.\w+$/) { |
Line 69 sub versiontrack {
|
Line 75 sub versiontrack {
|
$uri=~s/\.\d+\.(\w+)$/\.$1/; |
$uri=~s/\.\d+\.(\w+)$/\.$1/; |
unless ($hash{'version_'.$uri}) { |
unless ($hash{'version_'.$uri}) { |
$hash{'version_'.$uri}=$version; |
$hash{'version_'.$uri}=$version; |
} |
} elsif ($version!=$hash{'version_'.$uri}) { |
|
$errtext.=&versionerror($uri,$hash{'version_'.$uri},$version); |
|
} |
} |
} |
return $uri; |
return $uri; |
} |
} |
Line 278 sub parse_resource {
|
Line 286 sub parse_resource {
|
$hash{'ids_'.$idsuri}=''.$rid; |
$hash{'ids_'.$idsuri}=''.$rid; |
} |
} |
|
|
if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard)$/) { |
if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard|viewclasslist)$/) { |
$turi.='?register=1'; |
$turi.='?register=1'; |
} |
} |
|
|
Line 645 sub readmap {
|
Line 653 sub readmap {
|
my $uri; |
my $uri; |
$short=~s/\//\_/g; |
$short=~s/\//\_/g; |
unless ($uri=$cenv{'url'}) { |
unless ($uri=$cenv{'url'}) { |
&Apache::lonnet::logthis("<font color=blue>WARNING: ". |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
"Could not load course $short.</font>"); |
"Could not load course $short.</font>"); |
return ('',&mt('No course data available.'));; |
return ('',&mt('No course data available.'));; |
} |
} |
@cond=('true:normal'); |
@cond=('true:normal'); |
|
|
open(LOCKFILE,">$fn.db.lock"); |
unless (open(LOCKFILE,">$fn.db.lock")) { |
|
$errtext.='<br />'.&mt('Map not loaded - Lock file could not be opened when reading map:').' <tt>'.$fn.'</tt>.'; |
|
$retfurl = ''; |
|
return ($retfurl,$errtext); |
|
} |
my $lock=0; |
my $lock=0; |
|
my $gotstate=0; |
if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { |
if (flock(LOCKFILE,LOCK_EX|LOCK_NB)) { |
$lock=1; |
$lock=1; |
unlink($fn.'.db'); |
&unlink_tmpfiles($fn); |
unlink($fn.'_symb.db'); |
|
unlink($fn.'.state'); |
|
unlink($fn.'parms.db'); |
|
} |
} |
undef %randompick; |
undef %randompick; |
undef %hiddenurl; |
undef %hiddenurl; |
undef %encurl; |
undef %encurl; |
$retfrid=''; |
$retfrid=''; |
if ($lock && (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) && |
my ($untiedhash,$untiedparmhash,$tiedhash,$tiedparmhash); |
(tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640))) { |
if ($lock) { |
%hash=(); |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) { |
%parmhash=(); |
$tiedhash = 1; |
$errtext=''; |
if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) { |
$pc=0; |
$tiedparmhash = 1; |
&clear_mapalias_count(); |
$gotstate = &build_tmp_hashes($uri,$fn,$short,\%cenv); |
&processversionfile(%cenv); |
unless ($gotstate) { |
my $furi=&Apache::lonnet::clutter($uri); |
&Apache::lonnet::logthis('Failed to write statemap at first attempt '.$fn.' for '.$uri.'.</font>'); |
$hash{'src_0.0'}=&versiontrack($furi); |
} |
$hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title'); |
$untiedparmhash = untie(%parmhash); |
$hash{'ids_'.$furi}='0.0'; |
unless ($untiedparmhash) { |
$hash{'is_map_0.0'}=1; |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
loadmap($uri,'0.0'); |
'Could not untie coursemap parmhash '.$fn.' for '.$uri.'.</font>'); |
if (defined($hash{'map_start_'.$uri})) { |
} |
&Apache::lonnet::appenv({"request.course.id" => $short, |
} |
"request.course.fn" => $fn, |
$untiedhash = untie(%hash); |
"request.course.uri" => $uri}); |
unless ($untiedhash) { |
$env{'request.course.id'}=$short; |
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
&traceroute('0',$hash{'map_start_'.$uri},'&'); |
'Could not untie coursemap hash '.$fn.' for '.$uri.'.</font>'); |
&accinit($uri,$short,$fn); |
} |
&hiddenurls(); |
} |
} |
|
$errtext .= &get_mapalias_errors(); |
|
# ------------------------------------------------------- Put versions into src |
|
foreach my $key (keys(%hash)) { |
|
if ($key=~/^src_/) { |
|
$hash{$key}=&putinversion($hash{$key}); |
|
} elsif ($key =~ /^(map_(?:start|finish|pc)_)(.*)/) { |
|
my ($type, $url) = ($1,$2); |
|
my $value = $hash{$key}; |
|
$hash{$type.&putinversion($url)}=$value; |
|
} |
|
} |
|
# ---------------------------------------------------------------- Encrypt URLs |
|
foreach my $id (keys(%encurl)) { |
|
# $hash{'src_'.$id}=&Apache::lonenc::encrypted($hash{'src_'.$id}); |
|
$hash{'encrypted_'.$id}=1; |
|
} |
|
# ----------------------------------------------- Close hashes to finally store |
|
# --------------------------------- Routine must pass this point, no early outs |
|
$hash{'first_rid'}=$retfrid; |
|
my ($mapid,$resid)=split(/\./,$retfrid); |
|
$hash{'first_mapurl'}=$hash{'map_id_'.$mapid}; |
|
my $symb=&Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,$hash{'src_'.$retfrid}); |
|
$retfurl=&add_get_param($hash{'src_'.$retfrid},{ 'symb' => $symb }); |
|
if ($hash{'encrypted_'.$retfrid}) { |
|
$retfurl=&Apache::lonenc::encrypted($retfurl,(&Apache::lonnet::allowed('adv') ne 'F')); |
|
} |
|
$hash{'first_url'}=$retfurl; |
|
unless ((untie(%hash)) && (untie(%parmhash))) { |
|
&Apache::lonnet::logthis("<font color=blue>WARNING: ". |
|
"Could not untie coursemap $fn for $uri.</font>"); |
|
} |
|
# ---------------------------------------------------- Store away initial state |
|
{ |
|
my $cfh; |
|
if (open($cfh,">$fn.state")) { |
|
print $cfh join("\n",@cond); |
|
} else { |
|
&Apache::lonnet::logthis("<font color=blue>WARNING: ". |
|
"Could not write statemap $fn for $uri.</font>"); |
|
} |
|
} |
|
flock(LOCKFILE,LOCK_UN); |
flock(LOCKFILE,LOCK_UN); |
close(LOCKFILE); |
} |
} else { |
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 |
# initialize the course in another child, busy wait trying to |
# initialize the course in another child, busy wait trying to |
# tie the hashes for the next 90 seconds, if we succeed forward |
# tie the hashes for the next 90 seconds, if we succeed forward |
Line 739 sub readmap {
|
Line 707 sub readmap {
|
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); |
|
$lock = 0; |
} |
} |
untie(%hash); |
if ($tiedhash) { |
untie(%parmhash); |
unless($untiedhash) { |
&Apache::lonnet::logthis("<font color=blue>WARNING: ". |
untie(%hash); |
"Could not tie coursemap $fn for $uri.</font>"); |
} |
|
} |
|
if ($tiedparmhash) { |
|
unless($untiedparmhash) { |
|
untie(%parmhash); |
|
} |
|
} |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
"Could not tie coursemap $fn for $uri.</font>"); |
|
$tiedhash = ''; |
|
$tiedparmhash = ''; |
my $i=0; |
my $i=0; |
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)) { |
(tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640))) { |
$lock = 1; |
if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_READER(),0640)) { |
if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640)) { |
$retfurl='/adm/navmaps'; |
$tiedhash = 1; |
&Apache::lonnet::appenv({"request.course.id" => $short, |
if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_READER(),0640)) { |
"request.course.fn" => $fn, |
$tiedparmhash = 1; |
"request.course.uri" => $uri}); |
if (-e "$fn.state") { |
untie(%hash); |
$retfurl='/adm/navmaps'; |
untie(%parmhash); |
&Apache::lonnet::appenv({"request.course.id" => $short, |
last; |
"request.course.fn" => $fn, |
} |
"request.course.uri" => $uri}); |
} |
$untiedhash = untie(%hash); |
untie(%hash); |
$untiedparmhash = untie(%parmhash); |
untie(%parmhash); |
$gotstate = 1; |
|
last; |
|
} |
|
$untiedparmhash = untie(%parmhash); |
|
} |
|
$untiedhash = untie(%hash); |
|
} |
|
} |
} |
} |
flock(LOCKFILE,LOCK_UN); |
if ($lock) { |
close(LOCKFILE); |
flock(LOCKFILE,LOCK_UN); |
|
$lock = 0; |
|
if ($tiedparmhash) { |
|
unless ($untiedparmhash) { |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not untie coursemap parmhash '.$fn.' for '.$uri.'.</font>'); |
|
} |
|
} |
|
if ($tiedparmhash) { |
|
unless ($untiedhash) { |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not untie coursemap hash '.$fn.' for '.$uri.'.</font>'); |
|
} |
|
} |
|
} |
|
} |
|
unless ($gotstate) { |
|
$lock = 0; |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not read statemap '.$fn.' for '.$uri.'.</font>'); |
|
&unlink_tmpfiles($fn); |
|
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('<font color="blue">WARNING: '. |
|
'Failed to write statemap at second attempt '.$fn.' for '.$uri.'.</font>'); |
|
} |
|
unless (untie(%parmhash)) { |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not untie coursemap parmhash '.$fn.'.db for '.$uri.'.</font>'); |
|
} |
|
} else { |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not tie coursemap '.$fn.'__parms.db for '.$uri.'.</font>'); |
|
} |
|
unless (untie(%hash)) { |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not untie coursemap hash '.$fn.'.db for '.$uri.'.</font>'); |
|
} |
|
} else { |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not tie coursemap '.$fn.'.db for '.$uri.'.</font>'); |
|
} |
|
flock(LOCKFILE,LOCK_UN); |
|
$lock = 0; |
|
} else { |
|
&Apache::lonnet::logthis('<font color="blue">WARNING: '. |
|
'Could not obtain lock to tie coursemap hash '.$fn.'.db for '.$uri.'.</font>'); |
|
} |
|
} |
|
close(LOCKFILE); |
|
unless (($errtext eq '') || ($env{'request.course.uri'} =~ m{^/uploaded/})) { |
|
&Apache::lonmsg::author_res_msg($env{'request.course.uri'}, |
|
$errtext); |
} |
} |
&Apache::lonmsg::author_res_msg($env{'request.course.uri'},$errtext); |
|
# ------------------------------------------------- Check for critical messages |
# ------------------------------------------------- Check for critical messages |
|
|
my @what=&Apache::lonnet::dump('critical',$env{'user.domain'}, |
my @what=&Apache::lonnet::dump('critical',$env{'user.domain'}, |
Line 779 sub readmap {
|
Line 826 sub readmap {
|
return ($retfurl,$errtext); |
return ($retfurl,$errtext); |
} |
} |
|
|
|
sub build_tmp_hashes { |
|
my ($uri,$fn,$short,$cenvref) = @_; |
|
unless(ref($cenvref) eq 'HASH') { |
|
return; |
|
} |
|
my %cenv = %{$cenvref}; |
|
my $gotstate = 0; |
|
%hash=(); |
|
%parmhash=(); |
|
$errtext=''; |
|
$pc=0; |
|
&clear_mapalias_count(); |
|
&processversionfile(%cenv); |
|
my $furi=&Apache::lonnet::clutter($uri); |
|
$hash{'src_0.0'}=&versiontrack($furi); |
|
$hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title'); |
|
$hash{'ids_'.$furi}='0.0'; |
|
$hash{'is_map_0.0'}=1; |
|
&loadmap($uri,'0.0'); |
|
if (defined($hash{'map_start_'.$uri})) { |
|
&Apache::lonnet::appenv({"request.course.id" => $short, |
|
"request.course.fn" => $fn, |
|
"request.course.uri" => $uri}); |
|
$env{'request.course.id'}=$short; |
|
&traceroute('0',$hash{'map_start_'.$uri},'&'); |
|
&accinit($uri,$short,$fn); |
|
&hiddenurls(); |
|
} |
|
$errtext .= &get_mapalias_errors(); |
|
# ------------------------------------------------------- Put versions into src |
|
foreach my $key (keys(%hash)) { |
|
if ($key=~/^src_/) { |
|
$hash{$key}=&putinversion($hash{$key}); |
|
} elsif ($key =~ /^(map_(?:start|finish|pc)_)(.*)/) { |
|
my ($type, $url) = ($1,$2); |
|
my $value = $hash{$key}; |
|
$hash{$type.&putinversion($url)}=$value; |
|
} |
|
} |
|
# ---------------------------------------------------------------- Encrypt URLs |
|
foreach my $id (keys(%encurl)) { |
|
# $hash{'src_'.$id}=&Apache::lonenc::encrypted($hash{'src_'.$id}); |
|
$hash{'encrypted_'.$id}=1; |
|
} |
|
# ----------------------------------------------- Close hashes to finally store |
|
# --------------------------------- Routine must pass this point, no early outs |
|
$hash{'first_rid'}=$retfrid; |
|
my ($mapid,$resid)=split(/\./,$retfrid); |
|
$hash{'first_mapurl'}=$hash{'map_id_'.$mapid}; |
|
my $symb=&Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,$hash{'src_'.$retfrid}); |
|
$retfurl=&add_get_param($hash{'src_'.$retfrid},{ 'symb' => $symb }); |
|
if ($hash{'encrypted_'.$retfrid}) { |
|
$retfurl=&Apache::lonenc::encrypted($retfurl,(&Apache::lonnet::allowed('adv') ne 'F')); |
|
} |
|
$hash{'first_url'}=$retfurl; |
|
# ---------------------------------------------------- Store away initial state |
|
{ |
|
my $cfh; |
|
if (open($cfh,">$fn.state")) { |
|
print $cfh join("\n",@cond); |
|
$gotstate = 1; |
|
} else { |
|
&Apache::lonnet::logthis("<font color=blue>WARNING: ". |
|
"Could not write statemap $fn for $uri.</font>"); |
|
} |
|
} |
|
return $gotstate; |
|
} |
|
|
|
sub unlink_tmpfiles { |
|
my ($fn) = @_; |
|
if ($fn =~ m{^\Q$Apache::lonnet::perlvar{'lonUsersDir'}\E/tmp/}) { |
|
my @files = qw (.db _symb.db .state _parms.db); |
|
foreach my $file (@files) { |
|
if (-e $fn.$file) { |
|
unless (unlink($fn.$file)) { |
|
&Apache::lonnet::logthis("<font color=blue>WARNING: ". |
|
"Could not unlink ".$fn.$file."</font>"); |
|
} |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
# ------------------------------------------------------- Evaluate state string |
# ------------------------------------------------------- Evaluate state string |
|
|
sub evalstate { |
sub evalstate { |
Line 878 of course for user.
|
Line 1010 of course for user.
|
This is part of the LearningOnline Network with CAPA project |
This is part of the LearningOnline Network with CAPA project |
described at http://www.lon-capa.org. |
described at http://www.lon-capa.org. |
|
|
=head1 HANDLER SUBROUTINE |
=head1 SUBROUTINES |
|
|
There is no handler subroutine. |
|
|
|
=head1 OTHER SUBROUTINES |
|
|
|
=over 4 |
=over |
|
|
=item * |
=item loadmap() |
|
|
loadmap() : Loads map from disk |
Loads map from disk |
|
|
=item * |
=item simplify() |
|
|
simplify() : Simplify expression |
Simplify expression |
|
|
=item * |
=item traceroute() |
|
|
traceroute() : Build condition hash |
Build condition hash |
|
|
=item * |
=item accinit() |
|
|
accinit() : Cascading conditions, quick access, parameters |
Cascading conditions, quick access, parameters |
|
|
=item * |
=item readmap() |
|
|
readmap() : Read map and all submaps |
Read map and all submaps |
|
|
=item * |
=item evalstate() |
|
|
evalstate() : Evaluate state string |
Evaluate state string |
|
|
=back |
=back |
|
|