Diff for /rat/lonuserstate.pm between versions 1.55 and 1.94

version 1.55, 2003/03/02 01:43:01 version 1.94, 2005/07/14 21:30:24
Line 25 Line 25
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
 # (Server for RAT Maps  
 #  
 # (Edit Handler for RAT Maps  
 # (TeX Content Handler  
 #  
 # YEAR=2000  
 # 05/29/00,05/30 Gerd Kortemeyer)  
 # 7/1 Gerd Kortemeyer)  
 # 7/1,7/3,7/4,7/7,7/8,7/10 Gerd Kortemeyer)  
 #  
 # 7/15,7/17,7/18,8/1,8/2,8/4,8/5,8/21,8/22,8/23,8/30,  
 # 9/2,9/4,9/29,9/30,10/2,10/11,10/30,10/31,  
 # 11/1,11/2,11/14,11/16,11/22,12/28,  
 # YEAR=2001  
 # 07/05/01,08/30,08/31 Gerd Kortemeyer  
 #  
 ###  ###
   
 package Apache::lonuserstate;  package Apache::lonuserstate;
Line 48  package Apache::lonuserstate; Line 32  package Apache::lonuserstate;
 # ------------------------------------------------- modules used by this module  # ------------------------------------------------- modules used by this module
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::File;  
 use HTML::TokeParser;  use HTML::TokeParser;
 use Apache::lonnet();  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use GDBM_File;  use GDBM_File;
 use Apache::lonmsg;  use Apache::lonmsg;
 use Safe;  use Safe;
 use Safe::Hole;  use Safe::Hole;
 use Opcode;  use Opcode;
   use Apache::lonenc;
   
 # ---------------------------------------------------- Globals for this package  # ---------------------------------------------------- Globals for this package
   
Line 68  my $errtext; # variable with all errors Line 52  my $errtext; # variable with all errors
 my $retfurl; # variable with the very first URL in the course  my $retfurl; # variable with the very first URL in the course
 my %randompick; # randomly picked resources  my %randompick; # randomly picked resources
 my %randompickseed; # optional seed for randomly picking resources  my %randompickseed; # optional seed for randomly picking resources
 my %actualversion; # version of resource as loaded now  my %encurl; # URLs in this folder are supposed to be encrypted
 my %setversion; # forced version of resource  my %hiddenurl; # this URL (or complete folder) is supposed to be hidden
 my %lastversion; # version when CC came in last  
 my $versionmode; # how versioning is handled in this course  # ----------------------------------- Remove version from URL and store in hash
   
   sub versiontrack {
       my $uri=shift;
       if ($uri=~/\.(\d+)\.\w+$/) {
    my $version=$1;
    $uri=~s/\.\d+\.(\w+)$/\.$1/;
           unless ($hash{'version_'.$uri}) {
       $hash{'version_'.$uri}=$version;
    }
       }
       return $uri;
   }
   
   # -------------------------------------------------------------- Put in version
   
   sub putinversion {
       my $uri=shift;
       my $key=$env{'request.course.id'}.'_'.&Apache::lonnet::clutter($uri);
       if ($hash{'version_'.$uri}) {
    my $version=$hash{'version_'.$uri};
    if ($version eq 'mostrecent') { return $uri; }
    if ($version eq &Apache::lonnet::getversion(
    &Apache::lonnet::filelocation('',$uri))) 
                { return $uri; }
    $uri=~s/\.(\w+)$/\.$version\.$1/;
       }
       &Apache::lonnet::do_cache_new('courseresversion',$key,&Apache::lonnet::declutter($uri),600);
       return $uri;
   }
   
   # ----------------------------------------- Processing versions file for course
   
   sub processversionfile {
       my %cenv=@_;
       my %versions=&Apache::lonnet::dump('resourceversions',
          $cenv{'domain'},
          $cenv{'num'});
       foreach (keys %versions) {
    if ($_=~/^error\:/) { return; }
    $hash{'version_'.$_}=$versions{$_};
       }
   }
   
 # --------------------------------------------------------- Loads map from disk  # --------------------------------------------------------- Loads map from disk
   
Line 85  sub loadmap { Line 111  sub loadmap {
     $hash{'map_id_'.$lpc}=$uri;      $hash{'map_id_'.$lpc}=$uri;
   
 # Determine and check filename  # Determine and check filename
     my $fn=&Apache::lonnet::filelocation('',$uri);      my $fn=&Apache::lonnet::filelocation('',&putinversion($uri));
   
     my $ispage=($fn=~/\.page$/);      my $ispage=($fn=~/\.page$/);
   
     unless (($fn=~/\.sequence$/) ||      unless (($fn=~/\.sequence$/) ||
             ($fn=~/\.page$/)) {               ($fn=~/\.page$/)) { 
        $errtext.="Invalid map: $fn\n";   $errtext.="Invalid map: $fn\n";
        return OK;    return OK; 
     }      }
   
     my $instr=&Apache::lonnet::getfile($fn);      my $instr=&Apache::lonnet::getfile($fn);
   
     unless ($instr == -1) {      unless ($instr eq -1) {
   
 # Successfully got file, parse it  # Successfully got file, parse it
   
         my $parser = HTML::TokeParser->new(\$instr);          my $parser = HTML::TokeParser->new(\$instr);
    #$parser->attr_encoded(1);
         my $token;          my $token;
   
         my $linkpc=0;          my $linkpc=0;
Line 114  sub loadmap { Line 141  sub loadmap {
     if ($token->[0] eq 'S') {      if ($token->[0] eq 'S') {
                 if ($token->[1] eq 'resource') {                  if ($token->[1] eq 'resource') {
 # -------------------------------------------------------------------- Resource  # -------------------------------------------------------------------- Resource
                       if ($token->[2]->{'type'} eq 'zombie') { next; }
                     my $rid=$lpc.'.'.$token->[2]->{'id'};                      my $rid=$lpc.'.'.$token->[2]->{'id'};
   
                     $hash{'kind_'.$rid}='res';                      $hash{'kind_'.$rid}='res';
                     $hash{'title_'.$rid}=$token->[2]->{'title'};                      $hash{'title_'.$rid}=$token->[2]->{'title'};
                     my $turi=$token->[2]->{'src'};                      my $turi=&versiontrack($token->[2]->{'src'});
                     $Apache::lonnet::titlecache{                      if ($token->[2]->{'version'}) {
      &Apache::lonnet::symbclean(   unless ($hash{'version_'.$turi}) {
                       &Apache::lonnet::declutter($uri).'___'.      $hash{'version_'.$turi}=$1;
                       $token->[2]->{'id'}.'___'.   }
       &Apache::lonnet::declutter($turi))}=      }
                           $token->[2]->{'title'};      my $title=$token->[2]->{'title'};
       $title=~s/\&colon\;/\:/gs;
   #    my $symb=&Apache::lonnet::encode_symb($uri,
   #  $token->[2]->{'id'},
   #  $turi);
   #    &Apache::lonnet::do_cache_new('title',$symb,$title);
                     unless ($ispage) {                      unless ($ispage) {
                         $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/^http\:\/\//\/adm\/wrapper\/ext\//;                              $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;
                         } elsif ($turi=~/^\/*uploaded\//) { # uploaded                          } elsif ($turi=~/^\/*uploaded\//) { # uploaded
     if (($embstyle eq 'img') || ($embstyle eq 'emb')      if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
                              || ($embstyle eq 'ssi')) {  
                                 $turi='/adm/wrapper'.$turi;                                  $turi='/adm/wrapper'.$turi;
                             } elsif ($turi!~/\.(sequence|page)$/) {      } elsif ($embstyle eq 'ssi') {
    #do nothing with these
       } elsif ($turi!~/\.(sequence|page)$/) {
  $turi='/adm/coursedocs/showdoc'.$turi;   $turi='/adm/coursedocs/showdoc'.$turi;
                             }                              }
                         } else { # normal internal resource                          } elsif ($turi=~/\S/) { # normal non-empty internal resource
                            if (($embstyle eq 'img') || ($embstyle eq 'emb')) {      my $mapdir=$uri;
        $turi='/adm/wrapper'.$turi;      $mapdir=~s/[^\/]+$//;
                            }      $turi=&Apache::lonnet::hreflocation($mapdir,$turi);
       if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
    $turi='/adm/wrapper'.$turi;
       }
                         }                          }
     }      }
   # Store reverse lookup, remove query string
                     if (defined($hash{'ids_'.$turi})) {      my $idsuri=$turi;
                         $hash{'ids_'.$turi}.=','.$rid;      $idsuri=~s/\?.+$//;
                       if (defined($hash{'ids_'.$idsuri})) {
                           $hash{'ids_'.$idsuri}.=','.$rid;
                     } else {                      } else {
                         $hash{'ids_'.$turi}=''.$rid;                          $hash{'ids_'.$idsuri}=''.$rid;
                     }                      }
                                 
                     if                      if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard)$/) {
         ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard)$/) {  
  $turi.='?register=1';   $turi.='?register=1';
     }      }
   
Line 227  sub loadmap { Line 264  sub loadmap {
 # ------------------------------------------------------------------- Parameter  # ------------------------------------------------------------------- Parameter
   
                     my $referid=$lpc.'.'.$token->[2]->{'to'};                      my $referid=$lpc.'.'.$token->[2]->{'to'};
                     my $part=$token->[2]->{'part'};      my $name=$token->[2]->{'name'};
                     unless ($part) { $part=0; }      my $part;
       if ($name=~/^parameter_(.*)_/) {
    $part=$1;
       } else {
    $part=0;
       }
       $name=~s/^.*_([^_]*)$/$1/;
                     my $newparam=                      my $newparam=
  &Apache::lonnet::escape($token->[2]->{'type'}).':'.   &Apache::lonnet::escape($token->[2]->{'type'}).':'.
  &Apache::lonnet::escape($part.'.'.   &Apache::lonnet::escape($part.'.'.$name).'='.
                          $token->[2]->{'name'}).'='.  
  &Apache::lonnet::escape($token->[2]->{'value'});   &Apache::lonnet::escape($token->[2]->{'value'});
                     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'} eq 'parameter_mapalias') {                      if ($token->[2]->{'name'}=~/^parameter_(0_)*mapalias$/) {
  $hash{'mapalias_'.$token->[2]->{'value'}}=$referid;   $hash{'mapalias_'.$token->[2]->{'value'}}=$referid;
                     }                      }
                     if ($token->[2]->{'name'} eq 'parameter_randompick') {                      if ($token->[2]->{'name'}=~/^parameter_(0_)*randompick$/) {
  $randompick{$referid}=$token->[2]->{'value'};   $randompick{$referid}=$token->[2]->{'value'};
                     }                      }
                     if ($token->[2]->{'name'} eq 'parameter_randompickseed') {                      if ($token->[2]->{'name'}=~/^parameter_(0_)*randompickseed$/) {
  $randompick{$referid}=$token->[2]->{'value'};   $randompick{$referid}=$token->[2]->{'value'};
                     }                      }
                       if ($token->[2]->{'name'}=~/^parameter_(0_)*encrypturl$/) {
    if ($token->[2]->{'value'}=~/^yes$/i) {
       $encurl{$referid}=1;
    }
                       }
                       if ($token->[2]->{'name'}=~/^parameter_(0_)*hiddenresource$/) {
    if ($token->[2]->{'value'}=~/^yes$/i) {
       $hiddenurl{$referid}=1;
    }
                       }
                 }                   } 
   
             }              }
         }          }
   
     } else {      } else {
         $errtext.='Map not loaded: The file does not exist. ';          $errtext.='Map not loaded: The file ('.$fn.') does not exist. ';
     }      }
 }  }
   
 # --------------------------------------------------------- Simplify expression  # --------------------------------------------------------- Simplify expression
   
 sub simplify {  sub simplify {
    my $expression=shift;      my $expression=shift;
 # (8)=8  # (8)=8
    $expression=~s/\((\d+)\)/$1/g;      $expression=~s/\((\d+)\)/$1/g;
 # 8&8=8  # 8&8=8
    $expression=~s/(\D)(\d+)\&\2(\D)/$1$2$3/g;      $expression=~s/(\D)(\d+)\&\2(\D)/$1$2$3/g;
 # 8|8=8  # 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  # (5&3)&4=5&3&4
    $expression=~s/\((\d+)((?:\&\d+)+)\)\&(\d+\D)/$1$2\&$3/g;      $expression=~s/\((\d+)((?:\&\d+)+)\)\&(\d+\D)/$1$2\&$3/g;
 # (((5&3)|(4&6)))=((5&3)|(4&6))  # (((5&3)|(4&6)))=((5&3)|(4&6))
    $expression=~      $expression=~
        s/\((\(\(\d+(?:\&\d+)*\)(?:\|\(\d+(?:\&\d+)*\))+\))\)/$1/g;   s/\((\(\(\d+(?:\&\d+)*\)(?:\|\(\d+(?:\&\d+)*\))+\))\)/$1/g;
 # ((5&3)|(4&6))|(1&2)=(5&3)|(4&6)|(1&2)  # ((5&3)|(4&6))|(1&2)=(5&3)|(4&6)|(1&2)
    $expression=~      $expression=~
        s/\((\(\d+(?:\&\d+)*\))((?:\|\(\d+(?:\&\d+)*\))+)\)\|(\(\d+(?:\&\d+)*\))/\($1$2\|$3\)/g;   s/\((\(\d+(?:\&\d+)*\))((?:\|\(\d+(?:\&\d+)*\))+)\)\|(\(\d+(?:\&\d+)*\))/\($1$2\|$3\)/g;
    return $expression;      return $expression;
 }  }
   
 # -------------------------------------------------------- Build condition hash  # -------------------------------------------------------- Build condition hash
   
 sub traceroute {  sub traceroute {
     my ($sofar,$rid,$beenhere)=@_;      my ($sofar,$rid,$beenhere,$encflag,$hdnflag)=@_;
     $sofar=simplify($sofar);      my $newsofar=$sofar=simplify($sofar);
     unless ($beenhere=~/\&$rid\&/) {      unless ($beenhere=~/\&$rid\&/) {
        $beenhere.=$rid.'&';     $beenhere.=$rid.'&';  
        if (($retfurl eq '') && ($hash{'src_'.$rid})   my ($mapid,$resid)=split(/\./,$rid);
         && ($hash{'src_'.$rid}!~/\.sequence$/)) {   my $symb=&Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,$hash{'src_'.$rid});
            my ($mapid,$resid)=split(/\./,$rid);   my $hidden=&Apache::lonnet::EXT('resource.0.hiddenresource',$symb);
            $retfurl=$hash{'src_'.$rid}.  
            (($hash{'src_'.$rid}=~/\?/)?'&':'?').'symb='.   if ($hdnflag || lc($hidden) eq 'yes') {
            &Apache::lonnet::symbclean(      $hiddenurl{$rid}=1;
                            &Apache::lonnet::declutter($hash{'map_id_'.$mapid}).   }
                            '___'.$resid.'___'.   if (!$hdnflag && lc($hidden) eq 'no') {
                            &Apache::lonnet::declutter($hash{'src_'.$rid}));      delete($hiddenurl{$rid});
        }   }
        if (defined($hash{'conditions_'.$rid})) {  
    $hash{'conditions_'.$rid}=simplify(   my $encrypt=&Apache::lonnet::EXT('resource.0.encrypturl',$symb);
    if ($encflag || lc($encrypt) eq 'yes') { $encurl{$rid}=1; }
    if (($retfurl eq '') && ($hash{'src_'.$rid})
       && ($hash{'src_'.$rid}!~/\.sequence$/)) {
       $retfurl=$hash{'src_'.$rid}.(($hash{'src_'.$rid}=~/\?/)?'&':'?').
    'symb='.$symb;
    }
    if (defined($hash{'conditions_'.$rid})) {
       $hash{'conditions_'.$rid}=simplify(
            '('.$hash{'conditions_'.$rid}.')|('.$sofar.')');             '('.$hash{'conditions_'.$rid}.')|('.$sofar.')');
        } else {   } else {
            $hash{'conditions_'.$rid}=$sofar;      $hash{'conditions_'.$rid}=$sofar;
        }   }
        if (defined($hash{'is_map_'.$rid})) {   $newsofar=$hash{'conditions_'.$rid};
            if (defined($hash{'map_start_'.$hash{'src_'.$rid}})) {   if (defined($hash{'is_map_'.$rid})) {
        &traceroute($sofar,$hash{'map_start_'.$hash{'src_'.$rid}},'&');      if (defined($hash{'map_start_'.$hash{'src_'.$rid}})) {
                if (defined($hash{'map_finish_'.$hash{'src_'.$rid}})) {   $sofar=$newsofar=
    $sofar=      &traceroute($sofar,
                   $hash{'conditions_'.$hash{'map_finish_'.$hash{'src_'.$rid}}};   $hash{'map_start_'.$hash{'src_'.$rid}},'&',
                }   $encflag || $encurl{$rid},
            }   $hdnflag || $hiddenurl{$rid});
        }      }
        if (defined($hash{'to_'.$rid})) {   }
           foreach (split(/\,/,$hash{'to_'.$rid})) {   if (defined($hash{'to_'.$rid})) {
       foreach (split(/\,/,$hash{'to_'.$rid})) {
  my $further=$sofar;   my $further=$sofar;
                 if ($hash{'undercond_'.$_}) {                  if ($hash{'undercond_'.$_}) {
    if (defined($hash{'condid_'.$hash{'undercond_'.$_}})) {      if (defined($hash{'condid_'.$hash{'undercond_'.$_}})) {
         $further=simplify('('.$further.')&('.   $further=simplify('('.$further.')&('.
                               $hash{'condid_'.$hash{'undercond_'.$_}}.')');    $hash{'condid_'.$hash{'undercond_'.$_}}.')');
    } else {      } else {
                        $errtext.='Undefined condition ID: '   $errtext.='Undefined condition ID: '
                                  .$hash{'undercond_'.$_}.'. ';      .$hash{'undercond_'.$_}.'. ';
                    }      }
                 }                  }
                 &traceroute($further,$hash{'goesto_'.$_},$beenhere);                  $newsofar=&traceroute($further,$hash{'goesto_'.$_},$beenhere,
           }        $encflag,$hdnflag);
        }      }
    }
     }      }
       return $newsofar;
 }  }
   
 # ------------------------------ Cascading conditions, quick access, parameters  # ------------------------------ Cascading conditions, quick access, parameters
Line 338  sub accinit { Line 401  sub accinit {
     my $condcounter=0;      my $condcounter=0;
     $acchash{'acc.cond.'.$short.'.0'}=0;      $acchash{'acc.cond.'.$short.'.0'}=0;
     foreach (keys %hash) {      foreach (keys %hash) {
        if ($_=~/^conditions/) {   if ($_=~/^conditions/) {
   my $expr=$hash{$_};      my $expr=$hash{$_};
          foreach ($expr=~m/(\(\(\d+(?:\&\d+)+\)(?:\|\(\d+(?:\&\d+)+\))+\))/g) {      foreach ($expr=~m/(\(\(\d+(?:\&\d+)+\)(?:\|\(\d+(?:\&\d+)+\))+\))/g) {
              my $sub=$_;   my $sub=$_;
              my $orig=$_;   my $orig=$_;
       $sub=~/\(\((\d+\&(:?\d+\&)*)(?:\d+\&*)+\)(?:\|\(\1(?:\d+\&*)+\))+\)/;   $sub=~/\(\((\d+\&(:?\d+\&)*)(?:\d+\&*)+\)(?:\|\(\1(?:\d+\&*)+\))+\)/;
              my $factor=$1;   my $factor=$1;
              $sub=~s/$factor//g;   $sub=~s/$factor//g;
              $sub=~s/^\(/\($factor\(/;   $sub=~s/^\(/\($factor\(/;
      $sub.=')';   $sub.=')';
              $sub=simplify($sub);   $sub=simplify($sub);
              $orig=~s/(\W)/\\$1/g;   $orig=~s/(\W)/\\$1/g;
       $expr=~s/$orig/$sub/;   $expr=~s/$orig/$sub/;
   }      }
           $hash{$_}=$expr;      $hash{$_}=$expr;
           unless (defined($captured{$expr})) {      unless (defined($captured{$expr})) {
       $condcounter++;   $condcounter++;
               $captured{$expr}=$condcounter;   $captured{$expr}=$condcounter;
               $acchash{'acc.cond.'.$short.'.'.$condcounter}=$expr;   $acchash{'acc.cond.'.$short.'.'.$condcounter}=$expr;
           }       } 
        } elsif ($_=~/^param_(\d+)\.(\d+)/) {   } elsif ($_=~/^param_(\d+)\.(\d+)/) {
           my $prefix=&Apache::lonnet::declutter($hash{'map_id_'.$1}).      my $prefix=&Apache::lonnet::encode_symb($hash{'map_id_'.$1},$2,
       '___'.$2.'___'.&Apache::lonnet::declutter($hash{'src_'.$1.'.'.$2});      $hash{'src_'.$1.'.'.$2});
           foreach (split(/\&/,$hash{$_})) {      foreach (split(/\&/,$hash{$_})) {
      my ($typename,$value)=split(/\=/,$_);   my ($typename,$value)=split(/\=/,$_);
              my ($type,$name)=split(/\:/,$typename);   my ($type,$name)=split(/\:/,$typename);
              $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name)}=   $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name)}=
                                    &Apache::lonnet::unescape($value);      &Apache::lonnet::unescape($value);
      $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name).'.type'}=   $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name).'.type'}=
                                    &Apache::lonnet::unescape($type);      &Apache::lonnet::unescape($type);
           }      }
        }   }
     }      }
     foreach (keys %hash) {      foreach (keys %hash) {
  if ($_=~/^ids/) {   if ($_=~/^ids/) {
   foreach (split(/\,/,$hash{$_})) {      foreach (split(/\,/,$hash{$_})) {
     my $resid=$_;   my $resid=$_;
             my $uri=$hash{'src_'.$resid};   my $uri=$hash{'src_'.$resid};
             $uri=~s/^\/adm\/wrapper//;   $uri=~s/^\/adm\/wrapper//;
             $uri=&Apache::lonnet::declutter($uri);   $uri=&Apache::lonnet::declutter($uri);
             my @uriparts=split(/\//,$uri);   my @uriparts=split(/\//,$uri);
             my $urifile=$uriparts[$#uriparts];   my $urifile=$uriparts[$#uriparts];
             $#uriparts--;   $#uriparts--;
             my $uripath=join('/',@uriparts);   my $uripath=join('/',@uriparts);
            if ($uripath) {   if ($uripath) {
             my $uricond='0';      my $uricond='0';
             if (defined($hash{'conditions_'.$resid})) {      if (defined($hash{'conditions_'.$resid})) {
   $uricond=$captured{$hash{'conditions_'.$resid}};   $uricond=$captured{$hash{'conditions_'.$resid}};
             }      }
             if (defined($acchash{'acc.res.'.$short.'.'.$uripath})) {      if (defined($acchash{'acc.res.'.$short.'.'.$uripath})) {
                 if ($acchash{'acc.res.'.$short.'.'.$uripath}=~   if ($acchash{'acc.res.'.$short.'.'.$uripath}=~
                    /(\&$urifile\:[^\&]*)/) {      /(\&\Q$urifile\E\:[^\&]*)/) {
     my $replace=$1;      my $replace=$1;
                     my $regexp=$replace;      my $regexp=$replace;
                     $regexp=~s/\|/\\\|/g;      #$regexp=~s/\|/\\\|/g;
                     $acchash{'acc.res.'.$short.'.'.$uripath}      $acchash{'acc.res.'.$short.'.'.$uripath}
                      =~s/$regexp/$replace\|$uricond/;      =~s/\Q$regexp\E/$replace\|$uricond/;
                 } else {   } else {
    $acchash{'acc.res.'.$short.'.'.$uripath}.=      $acchash{'acc.res.'.$short.'.'.$uripath}.=
                      $urifile.':'.$uricond.'&';   $urifile.':'.$uricond.'&';
         }   }
             } else {      } else {
                 $acchash{'acc.res.'.$short.'.'.$uripath}=   $acchash{'acc.res.'.$short.'.'.$uripath}=
                  '&'.$urifile.':'.$uricond.'&';      '&'.$urifile.':'.$uricond.'&';
             }      }
            }    } 
          }      }
       }   }
     }      }
     $acchash{'acc.res.'.$short.'.'}='&:0&';      $acchash{'acc.res.'.$short.'.'}='&:0&';
     my $courseuri=$uri;      my $courseuri=$uri;
     $courseuri=~s/^\/res\///;      $courseuri=~s/^\/res\///;
     &Apache::lonnet::delenv('(acc\.|httpref\.)');      &Apache::lonnet::delenv('(acc\.|httpref\.)');
     &Apache::lonnet::appenv(%acchash,      &Apache::lonnet::appenv(%acchash);
                             "request.course.id"  => $short,  
                             "request.course.fn"  => $fn,  
                             "request.course.uri" => $courseuri);   
 }  }
   
 # ------------------------------------- Selectively delete from randompick maps  # ---------------- Selectively delete from randompick maps and hidden url parms
   
 sub pickrandom {  sub hiddenurls {
     my $randomoutentry='';      my $randomoutentry='';
     foreach my $rid (keys %randompick) {      foreach my $rid (keys %randompick) {
         my $rndpick=$randompick{$rid};          my $rndpick=$randompick{$rid};
Line 443  sub pickrandom { Line 503  sub pickrandom {
  my (undef,$id)=split(/\./,$rid);   my (undef,$id)=split(/\./,$rid);
         if ($randompickseed{$rid}) { $id=$randompickseed{$rid}; }          if ($randompickseed{$rid}) { $id=$randompickseed{$rid}; }
  my $rndseed=&Apache::lonnet::rndseed($id); # use id instead of symb   my $rndseed=&Apache::lonnet::rndseed($id); # use id instead of symb
  &Math::Random::random_set_seed_from_phrase($rndseed);   &Apache::lonnet::setup_random_from_rndseed($rndseed);
  my @whichids=&Math::Random::random_permuted_index($#currentrids+1);   my @whichids=&Math::Random::random_permuted_index($#currentrids+1);
         for (my $i=1;$i<=$rndpick;$i++) { $currentrids[$whichids[$i]]=''; }          for (my $i=1;$i<=$rndpick;$i++) { $currentrids[$whichids[$i]]=''; }
  #&Apache::lonnet::logthis("$id,$rndseed,".join(':',@whichids));   #&Apache::lonnet::logthis("$id,$rndseed,".join(':',@whichids));
Line 453  sub pickrandom { Line 513  sub pickrandom {
  $hash{'randomout_'.$currentrids[$k]}=1;   $hash{'randomout_'.$currentrids[$k]}=1;
                 my ($mapid,$resid)=split(/\./,$currentrids[$k]);                  my ($mapid,$resid)=split(/\./,$currentrids[$k]);
                 $randomoutentry.='&'.                  $randomoutentry.='&'.
                  &Apache::lonnet::symbclean(      &Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},
     &Apache::lonnet::declutter($hash{'map_id_'.$mapid}).   $resid,
                     '___'.$resid.'___'.   $hash{'src_'.$currentrids[$k]}
     &Apache::lonnet::declutter($hash{'src_'.$currentrids[$k]})   ).'&';
                  ).'&';  
             }              }
         }          }
     }      }
   # ------------------------------ take care of explicitly hidden urls or folders
       foreach my $rid (keys %hiddenurl) {
    $hash{'randomout_'.$rid}=1;
    my ($mapid,$resid)=split(/\./,$rid);
    $randomoutentry.='&'.
       &Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,
    $hash{'src_'.$rid}).'&';
       }
   # --------------------------------------- append randomout entry to environment
     if ($randomoutentry) {      if ($randomoutentry) {
  &Apache::lonnet::appenv('acc.randomout' => $randomoutentry);   &Apache::lonnet::appenv('acc.randomout' => $randomoutentry);
     }      }
Line 469  sub pickrandom { Line 537  sub pickrandom {
 # ---------------------------------------------------- Read map and all submaps  # ---------------------------------------------------- Read map and all submaps
   
 sub readmap {  sub readmap {
    my $short=shift;      my $short=shift;
    $short=~s/^\///;      $short=~s/^\///;
    my %cenv=&Apache::lonnet::coursedescription($short);      my %cenv=&Apache::lonnet::coursedescription($short);
    my $fn=$cenv{'fn'};      my $fn=$cenv{'fn'};
    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 'No course data available.';   return 'No course data available.';
    }      }
    @cond=('true:normal');      @cond=('true:normal');
    unlink($fn.'.db');      #unlink($fn.'.db');
    unlink($fn.'_symb.db');      #unlink($fn.'_symb.db');
    unlink($fn.'.state');      unlink($fn.'.state');
    unlink($fn.'parms.db');      unlink($fn.'parms.db');
    undef %randompick;      undef %randompick;
    $retfurl='';      undef %hiddenurl;
    if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) &&      undef %encurl;
        (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640))) {      $retfurl='';
     %hash=();      if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) &&
     %parmhash=();   (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640))) {
     $errtext='';   %hash=();
     $pc=0;   %parmhash=();
     my $furi=&Apache::lonnet::clutter($uri);   $errtext='';
     $hash{'src_0.0'}=$furi;   $pc=0;
     $hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title');   &processversionfile(%cenv);
     $hash{'ids_'.$furi}='0.0';   my $furi=&Apache::lonnet::clutter($uri);
     $hash{'is_map_0.0'}=1;   $hash{'src_0.0'}=&versiontrack($furi);
     loadmap($uri);   $hash{'title_0.0'}=&Apache::lonnet::metadata($uri,'title');
     if (defined($hash{'map_start_'.$uri})) {   $hash{'ids_'.$furi}='0.0';
         &traceroute('0',$hash{'map_start_'.$uri},'&');   $hash{'is_map_0.0'}=1;
         &accinit($uri,$short,$fn);   loadmap($uri);
         &pickrandom();   if (defined($hash{'map_start_'.$uri})) {
     }      &Apache::lonnet::appenv("request.course.id"  => $short,
 # ------------------------------------------------------------ Version tracking      "request.course.fn"  => $fn,
 #    if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {      "request.course.uri" => $uri);
 # &Apache::lonnet::logthis('Will be version tracking');      &traceroute('0',$hash{'map_start_'.$uri},'&');
 #    }      &accinit($uri,$short,$fn);
     unless ((untie(%hash)) && (untie(%parmhash))) {      &hiddenurls();
       &Apache::lonnet::logthis("<font color=blue>WARNING: ".   }
                        "Could not untie coursemap $fn for $uri.</font>");   # ------------------------------------------------------- Put versions into src
     }   foreach (keys %hash) {
     {      if ($_=~/^src\_/) {
      my $cfh;   $hash{$_}=&putinversion($hash{$_});
      if ($cfh=Apache::File->new(">$fn.state")) {      }
         print $cfh join("\n",@cond);   }
      } else {  # ---------------------------------------------------------------- Encrypt URLs
       &Apache::lonnet::logthis("<font color=blue>WARNING: ".   foreach (keys %encurl) {
                        "Could not write statemap $fn for $uri.</font>");   #    $hash{'src_'.$_}=&Apache::lonenc::encrypted($hash{'src_'.$_});
      }      $hash{'encrypted_'.$_}=1;
     }     }
    } else {  # ----------------------------------------------- Close hashes to finally store
       &Apache::lonnet::logthis("<font color=blue>WARNING: ".  # --------------------------------- Routine must pass this point, no early outs
                        "Could not tie coursemap $fn for $uri.</font>");    $hash{'first_url'}=$retfurl;
    }   unless ((untie(%hash)) && (untie(%parmhash))) {
    &Apache::lonmsg::author_res_msg($ENV{'request.course.uri'},$errtext);      &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>"); 
       }
    }  
       } else {
    # if we are here it is likely because we are already trying to 
    # initialize the course in another child, busy wait trying to 
    # 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 
    # course screen
    untie(%hash);
    untie(%parmhash);
    &Apache::lonnet::logthis("<font color=blue>WARNING: ".
    "Could not tie coursemap $fn for $uri.</font>"); 
    my $i=0;
    while($i<90) {
       $i++;
       sleep(1);
       if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640))) {
    if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_READER(),0640)) {
       $retfurl='/adm/navmaps';
       &Apache::lonnet::appenv("request.course.id"  => $short,
       "request.course.fn"  => $fn,
       "request.course.uri" => $uri);
       untie(%hash);
       untie(%parmhash);
       last;
    }
       }
       untie(%hash);
       untie(%parmhash);
    }
       }
       &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'},
                                               $ENV{'user.name'});     $env{'user.name'});
     if ($what[0]) {      if ($what[0]) {
  if (($what[0] ne 'con_lost') && ($what[0]!~/^error\:/)) {   if (($what[0] ne 'con_lost') && ($what[0]!~/^error\:/)) {
     $retfurl='/adm/email?critical=display';      $retfurl='/adm/email?critical=display';
         }          }
     }      }
    return ($retfurl,$errtext);      return ($retfurl,$errtext);
 }  }
   
 # ------------------------------------------------------- Evaluate state string  # ------------------------------------------------------- Evaluate state string
   
 sub evalstate {  sub evalstate {
       my $fn=$env{'request.course.fn'}.'.state';
     my $fn=$ENV{'request.course.fn'}.'.state';      my $state='';
     my $state='2';  
     if (-e $fn) {      if (-e $fn) {
        my @conditions=();   my @conditions=();
        {   {
         my $fh=Apache::File->new($fn);      my $fh=Apache::File->new($fn);
         @conditions=<$fh>;      @conditions=<$fh>;
        }     }  
        my $safeeval = new Safe;   my $safeeval = new Safe;
        my $safehole = new Safe::Hole;   my $safehole = new Safe::Hole;
        $safeeval->permit("entereval");   $safeeval->permit("entereval");
        $safeeval->permit(":base_math");   $safeeval->permit(":base_math");
        $safeeval->deny(":base_io");   $safeeval->deny(":base_io");
        $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');   $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');
        foreach (@conditions) {   foreach my $line (@conditions) {
    my $line=$_;      chomp($line);
            chomp($line);      my ($condition,$weight)=split(/\:/,$line);
    my ($condition,$weight)=split(/\:/,$_);      if ($safeeval->reval($condition)) {
            if ($safeeval->reval($condition)) {   if ($weight eq 'force') {
        if ($weight eq 'force') {      $state.='3';
    $state.='3';   } else {
                } else {      $state.='2';
                    $state.='2';   }
                }      } else {
            } else {   if ($weight eq 'stop') {
                if ($weight eq 'stop') {      $state.='0';
    $state.='0';   } else {
                } else {      $state.='1';
                    $state.='1';   }
                }      }
            }   }
        }  
     }      }
     &Apache::lonnet::appenv('user.state.'.$ENV{'request.course.id'} => $state);      &Apache::lonnet::appenv('user.state.'.$env{'request.course.id'} => $state);
     return $state;      return $state;
 }  }
   

Removed from v.1.55  
changed lines
  Added in v.1.94


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.