Diff for /rat/lonuserstate.pm between versions 1.33 and 1.90

version 1.33, 2002/07/07 17:52:20 version 1.90, 2005/05/05 20:43:28
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  
 # 12/16 Scott Harrison  
 #  
 ###  ###
   
 package Apache::lonuserstate;  package Apache::lonuserstate;
Line 49  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 @cond;    # Array with all of the con Line 51  my @cond;    # Array with all of the con
 my $errtext; # variable with all errors  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 %encurl; # URLs in this folder are supposed to be encrypted
   my %hiddenurl; # this URL (or complete folder) is supposed to be hidden
   
   # ----------------------------------- 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;
       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/;
       }
       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
   
 sub loadmap {   sub loadmap { 
Line 79  sub loadmap { Line 108  sub loadmap {
     $hash{'map_pc_'.$uri}=$lpc;      $hash{'map_pc_'.$uri}=$lpc;
     $hash{'map_id_'.$lpc}=$uri;      $hash{'map_id_'.$lpc}=$uri;
   
     my $fn='/home/httpd/html'.$uri;  # Determine and check filename
       my $fn=&Apache::lonnet::filelocation('',&putinversion($uri));
   
       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 $ispage=($fn=~/\.page$/);      my $instr=&Apache::lonnet::getfile($fn);
   
     unless (-e $fn) {      unless ($instr eq -1) {
  my $returned=Apache::lonnet::repcopy($fn);  
         unless ($returned eq OK) {  # Successfully got file, parse it
            $errtext.="Could not import: $fn - ";  
            if ($returned eq HTTP_SERVICE_UNAVAILABLE) {  
       $errtext.="Server unavailable\n";  
            }  
            if ($returned eq HTTP_NOT_FOUND) {  
       $errtext.="File not found\n";  
            }  
            if ($returned eq FORBIDDEN) {  
       $errtext.="Access forbidden\n";  
            }  
            return OK;  
        }  
     }  
   
     if (-e $fn) {  
         my @content;  
         {  
     my $fh=Apache::File->new($fn);  
             @content=<$fh>;  
         }  
         my $instr=join('',@content);  
         my $parser = HTML::TokeParser->new(\$instr);          my $parser = HTML::TokeParser->new(\$instr);
         my $token;          my $token;
   
Line 131  sub loadmap { Line 143  sub loadmap {
   
                     $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'});
                       if ($token->[2]->{'version'}) {
    unless ($hash{'version_'.$turi}) {
       $hash{'version_'.$turi}=$1;
    }
       }
       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') {                          if ($token->[2]->{'external'} eq 'true') { # external
                             $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;                              $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;
                         } else {                          } elsif ($turi=~/^\/*uploaded\//) { # uploaded
                            my $embstyle=&Apache::loncommon::fileembstyle($1);      if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
                            if (($embstyle eq 'img') || ($embstyle eq 'emb')) {                                  $turi='/adm/wrapper'.$turi;
        $turi='/adm/wrapper'.$turi;      } elsif ($embstyle eq 'ssi') {
                            }   #do nothing with these
       } elsif ($turi!~/\.(sequence|page)$/) {
    $turi='/adm/coursedocs/showdoc'.$turi;
                               }
                           } elsif ($turi=~/\S/) { # normal non-empty internal resource
       my $mapdir=$uri;
       $mapdir=~s/[^\/]+$//;
       $turi=&Apache::lonnet::hreflocation($mapdir,$turi);
       if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
    $turi='/adm/wrapper'.$turi;
       }
                         }                          }
     }      }
                     $hash{'src_'.$rid}=$turi;  # Store reverse lookup, remove query string
       my $idsuri=$turi;
                     if (defined($hash{'ids_'.$turi})) {      $idsuri=~s/\?.+$//;
                         $hash{'ids_'.$turi}.=','.$rid;                      if (defined($hash{'ids_'.$idsuri})) {
                           $hash{'ids_'.$idsuri}.=','.$rid;
                     } else {                      } else {
                         $hash{'ids_'.$turi}=''.$rid;                          $hash{'ids_'.$idsuri}=''.$rid;
                     }                      }
                  
                       if ($turi=~/\/(syllabus|aboutme|navmaps|smppg|bulletinboard)$/) {
    $turi.='?register=1';
       }
   
                       $hash{'src_'.$rid}=$turi;
   
                     if ($token->[2]->{'external'} eq 'true') {                      if ($token->[2]->{'external'} eq 'true') {
                         $hash{'ext_'.$rid}='true:';                          $hash{'ext_'.$rid}='true:';
Line 221  sub loadmap { Line 261  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'}=~/^parameter_(0_)*randompickseed$/) {
    $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 '') {   my ($mapid,$resid)=split(/\./,$rid);
            my ($mapid,$resid)=split(/\./,$rid);   my $symb=&Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,$hash{'src_'.$rid});
            $retfurl=$hash{'src_'.$rid}.'?symb='.   my $hidden=&Apache::lonnet::EXT('resource.0.hiddenresource',$symb);
            &Apache::lonnet::symbclean(   if ($hdnflag || lc($hidden) eq 'yes') {
                            &Apache::lonnet::declutter($hash{'map_id_'.$mapid}).      $hiddenurl{$rid}=1;
                            '___'.$resid.'___'.   } else {
                            &Apache::lonnet::declutter($hash{'src_'.$rid}));      # shouldn't be hidden, but might have had a parm set on it
        }              # saying to
        if (defined($hash{'conditions_'.$rid})) {      delete($hiddenurl{$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 327  sub accinit { Line 397  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//;
             my @uriparts=split(/\//,$uri);   $uri=&Apache::lonnet::declutter($uri);
             my $urifile=$uriparts[$#uriparts];   my @uriparts=split(/\//,$uri);
             $#uriparts--;   my $urifile=$uriparts[$#uriparts];
             my $uripath=join('/',@uriparts);   $#uriparts--;
             $uripath=~s/^\/res\///;   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};
         my $mpc=$hash{'map_pc_'.$hash{'src_'.$rid}};          my $mpc=$hash{'map_pc_'.$hash{'src_'.$rid}};
 # ------------------------------------------- put existing resources into array  # ------------------------------------------- put existing resources into array
         my @currentrids=();          my @currentrids=();
         foreach (keys %hash) {          foreach (sort(keys(%hash))) {
     if ($_=~/^src_($mpc\.\d+)/) {      if ($_=~/^src_($mpc\.\d+)/) {
  if ($hash{'src_'.$1}) { push @currentrids, $1; }   if ($hash{'src_'.$1}) { push @currentrids, $1; }
             }              }
         }          }
    # rids are number.number and we want to numercially sort on 
           # the second number
    @currentrids=sort {
       my (undef,$aid)=split(/\./,$a);
       my (undef,$bid)=split(/\./,$b);
       $aid <=> $bid;
    } @currentrids;
         next if ($#currentrids<$rndpick);          next if ($#currentrids<$rndpick);
 # -------------------------------- randomly eliminate the ones that should stay  # -------------------------------- randomly eliminate the ones that should stay
  srand(&Apache::lonnet::rndseed($rid)); # use rid instead of symb   my (undef,$id)=split(/\./,$rid);
         for (my $i=1;$i<=$rndpick;$i++) {          if ($randompickseed{$rid}) { $id=$randompickseed{$rid}; }
             while (1) {   my $rndseed=&Apache::lonnet::rndseed($id); # use id instead of symb
  my $randomidx=int(rand($#currentrids+1));   &Apache::lonnet::setup_random_from_rndseed($rndseed);
                 if ($currentrids[$randomidx]) {   my @whichids=&Math::Random::random_permuted_index($#currentrids+1);
     $currentrids[$randomidx]='';          for (my $i=1;$i<=$rndpick;$i++) { $currentrids[$whichids[$i]]=''; }
                     last;   #&Apache::lonnet::logthis("$id,$rndseed,".join(':',@whichids));
                 }  
             }  
         }  
 # -------------------------------------------------------- delete the leftovers  # -------------------------------------------------------- delete the leftovers
         for (my $k=0; $k<=$#currentrids; $k++) {          for (my $k=0; $k<=$#currentrids; $k++) {
             if ($currentrids[$k]) {              if ($currentrids[$k]) {
  $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 454  sub pickrandom { Line 533  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='/res/'.&Apache::lonnet::declutter($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,
     unless ((untie(%hash)) && (untie(%parmhash))) {      "request.course.fn"  => $fn,
       &Apache::lonnet::logthis("<font color=blue>WARNING: ".      "request.course.uri" => $uri);
                        "Could not untie coursemap $fn for $uri.</font>");       &traceroute('0',$hash{'map_start_'.$uri},'&');
     }      &accinit($uri,$short,$fn);
     {      &hiddenurls();
      my $cfh;   }
      if ($cfh=Apache::File->new(">$fn.state")) {  # ------------------------------------------------------- Put versions into src
         print $cfh join("\n",@cond);   foreach (keys %hash) {
      } else {      if ($_=~/^src\_/) {
       &Apache::lonnet::logthis("<font color=blue>WARNING: ".   $hash{$_}=&putinversion($hash{$_});
                        "Could not write statemap $fn for $uri.</font>");       }
      }   }
     }    # ---------------------------------------------------------------- Encrypt URLs
    } else {   foreach (keys %encurl) {
       &Apache::lonnet::logthis("<font color=blue>WARNING: ".  #    $hash{'src_'.$_}=&Apache::lonenc::encrypted($hash{'src_'.$_});
                        "Could not tie coursemap $fn for $uri.</font>");       $hash{'encrypted_'.$_}=1;
    }   }
    &Apache::lonmsg::author_res_msg($ENV{'request.course.uri'},$errtext);  # ----------------------------------------------- Close hashes to finally store
    return ($retfurl,$errtext);  # --------------------------------- Routine must pass this point, no early outs
    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>"); 
       }
    }  
       } 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
   
       my @what=&Apache::lonnet::dump('critical',$env{'user.domain'},
      $env{'user.name'});
       if ($what[0]) {
    if (($what[0] ne 'con_lost') && ($what[0]!~/^error\:/)) {
       $retfurl='/adm/email?critical=display';
           }
       }
       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.33  
changed lines
  Added in v.1.90


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.