Diff for /rat/lonuserstate.pm between versions 1.128.2.3 and 1.129

version 1.128.2.3, 2009/11/16 20:26:04 version 1.129, 2008/11/18 19:13:37
Line 247  sub parse_resource { Line 247  sub parse_resource {
  $turi=~/\.(\w+)$/;   $turi=~/\.(\w+)$/;
  my $embstyle=&Apache::loncommon::fileembstyle($1);   my $embstyle=&Apache::loncommon::fileembstyle($1);
  if ($token->[2]->{'external'} eq 'true') { # external   if ($token->[2]->{'external'} eq 'true') { # external
     $turi=~s/^https?\:\/\//\/adm\/wrapper\/ext\//;      $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;
  } elsif ($turi=~/^\/*uploaded\//) { # uploaded   } elsif ($turi=~/^\/*uploaded\//) { # uploaded
     if (($embstyle eq 'img')       if (($embstyle eq 'img') 
  || ($embstyle eq 'emb')   || ($embstyle eq 'emb')
Line 573  sub accinit { Line 573  sub accinit {
     $acchash{'acc.res.'.$short.'.'}='&:0&';      $acchash{'acc.res.'.$short.'.'}='&:0&';
     my $courseuri=$uri;      my $courseuri=$uri;
     $courseuri=~s/^\/res\///;      $courseuri=~s/^\/res\///;
     my $regexp = 1;      &Apache::lonnet::delenv('(acc\.|httpref\.)');
     &Apache::lonnet::delenv('(acc\.|httpref\.)',$regexp);  
     &Apache::lonnet::appenv(\%acchash);      &Apache::lonnet::appenv(\%acchash);
 }  }
   
Line 645  sub readmap { Line 644  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');
   
     unless (open(LOCKFILE,">$fn.db.lock")) {      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_tmpfiles($fn);   unlink($fn.'.db');
    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='';
     my ($untiedhash,$untiedparmhash,$tiedhash,$tiedparmhash);      if ($lock && (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) &&
     if ($lock) {   (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640))) {
         if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) {   %hash=();
             $tiedhash = 1;   %parmhash=();
             if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640)) {   $errtext='';
                 $tiedparmhash = 1;   $pc=0;
                 $gotstate = &build_tmp_hashes($uri,$fn,$short,\%cenv);   &clear_mapalias_count();
                 unless ($gotstate) {   &processversionfile(%cenv);
                     &Apache::lonnet::logthis('Failed to write statemap at first attempt '.$fn.' for '.$uri.'.</font>');   my $furi=&Apache::lonnet::clutter($uri);
                 }   $hash{'src_0.0'}=&versiontrack($furi);
                 $untiedparmhash = untie(%parmhash);   $hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title');
                 unless ($untiedparmhash) {   $hash{'ids_'.$furi}='0.0';
                     &Apache::lonnet::logthis('<font color="blue">WARNING: '.   $hash{'is_map_0.0'}=1;
                         'Could not untie coursemap parmhash '.$fn.' for '.$uri.'.</font>');   loadmap($uri,'0.0');
                 }   if (defined($hash{'map_start_'.$uri})) {
             }      &Apache::lonnet::appenv({"request.course.id"  => $short,
             $untiedhash = untie(%hash);       "request.course.fn"  => $fn,
             unless ($untiedhash) {       "request.course.uri" => $uri});
                 &Apache::lonnet::logthis('<font color="blue">WARNING: '.      $env{'request.course.id'}=$short;
                     'Could not untie coursemap hash '.$fn.' for '.$uri.'.</font>');      &traceroute('0',$hash{'map_start_'.$uri},'&');
             }      &accinit($uri,$short,$fn);
         }      &hiddenurls();
         flock(LOCKFILE,LOCK_UN);   }
     }   $errtext .= &get_mapalias_errors();
     unless ($lock && $tiedhash && $tiedparmhash) {  # ------------------------------------------------------- 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);
    close(LOCKFILE);
       } else {
  # 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 699  sub readmap { Line 738  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;  
  }   }
         if ($tiedhash) {   untie(%hash);
             unless($untiedhash) {   untie(%parmhash);
                 untie(%hash);   &Apache::lonnet::logthis("<font color=blue>WARNING: ".
             }   "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) &&
                 $lock = 1;   (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640))) {
  if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640)) {   if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_READER(),0640)) {
                     $tiedhash = 1;      $retfurl='/adm/navmaps';
     if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_READER(),0640)) {      &Apache::lonnet::appenv({"request.course.id"  => $short,
                         $tiedparmhash = 1;       "request.course.fn"  => $fn,
                         if (-e "$fn.state") {       "request.course.uri" => $uri});
             $retfurl='/adm/navmaps';      untie(%hash);
             &Apache::lonnet::appenv({"request.course.id"  => $short,      untie(%parmhash);
              "request.course.fn"  => $fn,      last;
              "request.course.uri" => $uri});  
                             $untiedhash = untie(%hash);  
                             $untiedparmhash = untie(%parmhash);  
                             $gotstate = 1;  
             last;  
                         }  
                         $untiedparmhash = untie(%parmhash);  
                     }  
                     $untiedhash = untie(%hash);  
  }   }
     }      }
       untie(%hash);
       untie(%parmhash);
  }   }
         if ($lock) {   flock(LOCKFILE,LOCK_UN);
             flock(LOCKFILE,LOCK_UN);   close(LOCKFILE);
             $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 818  sub readmap { Line 778  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 1002  of course for user. Line 877  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
   

Removed from v.1.128.2.3  
changed lines
  Added in v.1.129


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>