Diff for /loncom/lonnet/perl/lonnet.pm between versions 1.1301 and 1.1324

version 1.1301, 2016/03/02 14:14:14 version 1.1324, 2016/09/21 05:15:40
Line 229  sub get_server_distarch { Line 229  sub get_server_distarch {
     return;      return;
 }  }
   
   sub get_servercerts_info {
       my ($lonhost,$context) = @_;
       my ($rep,$uselocal);
       if (grep { $_ eq $lonhost } &current_machine_ids()) {
           $uselocal = 1;
       }
       if (($context ne 'cgi') && ($uselocal)) {
           my $distro = (split(/\:/,&get_server_distarch($lonhost)))[0];
           if ($distro eq '') {
               $uselocal = 0;
           } elsif ($distro =~ /^(?:centos|redhat|scientific)(\d+)$/) {
               if ($1 < 6) {
                   $uselocal = 0;
               }
           }
       }
       if ($uselocal) {
           $rep = LONCAPA::Lond::server_certs(\%perlvar);
       } else {
           $rep=&reply('servercerts',$lonhost);
       }
       my ($result,%returnhash);
       if (defined($lonhost)) {
           if (!defined(&hostname($lonhost))) {
               return;
           }
       }
       if (($rep=~/^(refused|rejected|error)/) || ($rep eq 'con_lost') ||
           ($rep eq 'unknown_cmd')) {
           $result = $rep;
       } else {
           $result = 'ok';
           my @pairs=split(/\&/,$rep);
           foreach my $item (@pairs) {
               my ($key,$value)=split(/=/,$item,2);
               my $what = &unescape($key);
               $returnhash{$what}=&thaw_unescape($value);
           }
       }
       return ($result,\%returnhash);
   }
   
 sub get_server_loncaparev {  sub get_server_loncaparev {
     my ($dom,$lonhost,$ignore_cache,$caller) = @_;      my ($dom,$lonhost,$ignore_cache,$caller) = @_;
     if (defined($lonhost)) {      if (defined($lonhost)) {
Line 1288  sub check_loadbalancing { Line 1330  sub check_loadbalancing {
     my $uintdom = &Apache::lonnet::internet_dom($uprimary_id);      my $uintdom = &Apache::lonnet::internet_dom($uprimary_id);
     my $intdom = &Apache::lonnet::internet_dom($lonhost);      my $intdom = &Apache::lonnet::internet_dom($lonhost);
     my $serverhomedom = &host_domain($lonhost);      my $serverhomedom = &host_domain($lonhost);
       my $domneedscache;
     my $cachetime = 60*60*24;      my $cachetime = 60*60*24;
   
     if (($uintdom ne '') && ($uintdom eq $intdom)) {      if (($uintdom ne '') && ($uintdom eq $intdom)) {
Line 1303  sub check_loadbalancing { Line 1345  sub check_loadbalancing {
             &Apache::lonnet::get_dom('configuration',['loadbalancing'],$dom_in_use);              &Apache::lonnet::get_dom('configuration',['loadbalancing'],$dom_in_use);
         if (ref($domconfig{'loadbalancing'}) eq 'HASH') {          if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
             $result = &do_cache_new('loadbalancing',$dom_in_use,$domconfig{'loadbalancing'},$cachetime);              $result = &do_cache_new('loadbalancing',$dom_in_use,$domconfig{'loadbalancing'},$cachetime);
           } else {
               $domneedscache = $dom_in_use;
         }          }
     }      }
     if (ref($result) eq 'HASH') {      if (ref($result) eq 'HASH') {
Line 1361  sub check_loadbalancing { Line 1405  sub check_loadbalancing {
             my %domconfig =              my %domconfig =
                 &Apache::lonnet::get_dom('configuration',['loadbalancing'],$serverhomedom);                  &Apache::lonnet::get_dom('configuration',['loadbalancing'],$serverhomedom);
             if (ref($domconfig{'loadbalancing'}) eq 'HASH') {              if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
                 $result = &do_cache_new('loadbalancing',$dom_in_use,$domconfig{'loadbalancing'},$cachetime);                  $result = &do_cache_new('loadbalancing',$serverhomedom,$domconfig{'loadbalancing'},$cachetime);
               } else {
                   $domneedscache = $serverhomedom;
             }              }
         }          }
         if (ref($result) eq 'HASH') {          if (ref($result) eq 'HASH') {
Line 1381  sub check_loadbalancing { Line 1427  sub check_loadbalancing {
                 $is_balancer = 1;                  $is_balancer = 1;
                 $offloadto = &this_host_spares($dom_in_use);                  $offloadto = &this_host_spares($dom_in_use);
             }              }
               unless (defined($cached)) {
                   $domneedscache = $serverhomedom;
               }
         }          }
     } else {      } else {
         if ($perlvar{'lonBalancer'} eq 'yes') {          if ($perlvar{'lonBalancer'} eq 'yes') {
             $is_balancer = 1;              $is_balancer = 1;
             $offloadto = &this_host_spares($dom_in_use);              $offloadto = &this_host_spares($dom_in_use);
         }          }
           unless (defined($cached)) {
               $domneedscache = $serverhomedom;
           }
       }
       if ($domneedscache) {
           &do_cache_new('loadbalancing',$domneedscache,$is_balancer,$cachetime);
     }      }
     if ($is_balancer) {      if ($is_balancer) {
         my $lowest_load = 30000;          my $lowest_load = 30000;
Line 1895  sub retrieve_inst_usertypes { Line 1950  sub retrieve_inst_usertypes {
   
 sub is_domainimage {  sub is_domainimage {
     my ($url) = @_;      my ($url) = @_;
     if ($url=~m-^/+res/+($match_domain)/+\1\-domainconfig/+(img|logo|domlogo)/+-) {      if ($url=~m-^/+res/+($match_domain)/+\1\-domainconfig/+(img|logo|domlogo)/+[^/]-) {
         if (&domain($1) ne '') {          if (&domain($1) ne '') {
             return '1';              return '1';
         }          }
Line 2189  sub get_domain_defaults { Line 2244  sub get_domain_defaults {
                                   'requestcourses','inststatus',                                    'requestcourses','inststatus',
                                   'coursedefaults','usersessions',                                    'coursedefaults','usersessions',
                                   'requestauthor','selfenrollment',                                    'requestauthor','selfenrollment',
                                   'coursecategories'],$domain);                                    'coursecategories','ssl','autoenroll',
     my @coursetypes = ('official','unofficial','community','textbook');                                    'trust'],$domain);
       my @coursetypes = ('official','unofficial','community','textbook','placement');
     if (ref($domconfig{'defaults'}) eq 'HASH') {      if (ref($domconfig{'defaults'}) eq 'HASH') {
         $domdefaults{'lang_def'} = $domconfig{'defaults'}{'lang_def'};           $domdefaults{'lang_def'} = $domconfig{'defaults'}{'lang_def'}; 
         $domdefaults{'auth_def'} = $domconfig{'defaults'}{'auth_def'};          $domdefaults{'auth_def'} = $domconfig{'defaults'}{'auth_def'};
Line 2220  sub get_domain_defaults { Line 2276  sub get_domain_defaults {
         }          }
     }      }
     if (ref($domconfig{'requestcourses'}) eq 'HASH') {      if (ref($domconfig{'requestcourses'}) eq 'HASH') {
         foreach my $item ('official','unofficial','community','textbook') {          foreach my $item ('official','unofficial','community','textbook','placement') {
             $domdefaults{$item} = $domconfig{'requestcourses'}{$item};              $domdefaults{$item} = $domconfig{'requestcourses'}{$item};
         }          }
     }      }
Line 2315  sub get_domain_defaults { Line 2371  sub get_domain_defaults {
             $domdefaults{'catunauth'} = $domconfig{'coursecategories'}{'unauth'};              $domdefaults{'catunauth'} = $domconfig{'coursecategories'}{'unauth'};
         }          }
     }      }
       if (ref($domconfig{'ssl'}) eq 'HASH') {
           if (ref($domconfig{'ssl'}{'replication'}) eq 'HASH') {
               $domdefaults{'replication'} = $domconfig{'ssl'}{'replication'};
           }
           if (ref($domconfig{'ssl'}{'connect'}) eq 'HASH') {
               $domdefaults{'connect'} = $domconfig{'ssl'}{'connect'};
           }
       }
       if (ref($domconfig{'trust'}) eq 'HASH') {
           my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg);
           foreach my $prefix (@prefixes) {
               if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') {
                   $domdefaults{'trust'.$prefix} = $domconfig{'trust'}{$prefix};
               }
           }
       }
       if (ref($domconfig{'autoenroll'}) eq 'HASH') {
           $domdefaults{'autofailsafe'} = $domconfig{'autoenroll'}{'autofailsafe'};
       }
     &do_cache_new('domdefaults',$domain,\%domdefaults,$cachetime);      &do_cache_new('domdefaults',$domain,\%domdefaults,$cachetime);
     return %domdefaults;      return %domdefaults;
 }  }
   
   sub course_portal_url {
       my ($cnum,$cdom) = @_;
       my $chome = &homeserver($cnum,$cdom);
       my $hostname = &hostname($chome);
       my $protocol = $protocol{$chome};
       $protocol = 'http' if ($protocol ne 'https');
       my %domdefaults = &get_domain_defaults($cdom);
       my $firsturl;
       if ($domdefaults{'portal_def'}) {
           $firsturl = $domdefaults{'portal_def'};
       } else {
           $firsturl = $protocol.'://'.$hostname;
       }
       return $firsturl;
   }
   
 # --------------------------------------------------- Assign a key to a student  # --------------------------------------------------- Assign a key to a student
   
 sub assign_access_key {  sub assign_access_key {
Line 2555  sub make_key { Line 2646  sub make_key {
 sub devalidate_cache_new {  sub devalidate_cache_new {
     my ($name,$id,$debug) = @_;      my ($name,$id,$debug) = @_;
     if ($debug) { &Apache::lonnet::logthis("deleting $name:$id"); }      if ($debug) { &Apache::lonnet::logthis("deleting $name:$id"); }
       my $remembered_id=$name.':'.$id;
     $id=&make_key($name,$id);      $id=&make_key($name,$id);
     $memcache->delete($id);      $memcache->delete($id);
     delete($remembered{$id});      delete($remembered{$remembered_id});
     delete($accessed{$id});      delete($accessed{$remembered_id});
 }  }
   
 sub is_cached_new {  sub is_cached_new {
     my ($name,$id,$debug) = @_;      my ($name,$id,$debug) = @_;
     $id=&make_key($name,$id);      my $remembered_id=$name.':'.$id; # this is to avoid make_key (which is slow) whenever possible
     if (exists($remembered{$id})) {      if (exists($remembered{$remembered_id})) {
  if ($debug) { &Apache::lonnet::logthis("Early return $id of $remembered{$id} "); }   if ($debug) { &Apache::lonnet::logthis("Early return $remembered_id of $remembered{$remembered_id} "); }
  $accessed{$id}=[&gettimeofday()];   $accessed{$remembered_id}=[&gettimeofday()];
  $hits++;   $hits++;
  return ($remembered{$id},1);   return ($remembered{$remembered_id},1);
     }      }
       $id=&make_key($name,$id);
     my $value = $memcache->get($id);      my $value = $memcache->get($id);
     if (!(defined($value))) {      if (!(defined($value))) {
  if ($debug) { &Apache::lonnet::logthis("getting $id is not defined"); }   if ($debug) { &Apache::lonnet::logthis("getting $id is not defined"); }
Line 2579  sub is_cached_new { Line 2672  sub is_cached_new {
  if ($debug) { &Apache::lonnet::logthis("getting $id is __undef__"); }   if ($debug) { &Apache::lonnet::logthis("getting $id is __undef__"); }
  $value=undef;   $value=undef;
     }      }
     &make_room($id,$value,$debug);      &make_room($remembered_id,$value,$debug);
     if ($debug) { &Apache::lonnet::logthis("getting $id is $value"); }      if ($debug) { &Apache::lonnet::logthis("getting $id is $value"); }
     return ($value,1);      return ($value,1);
 }  }
   
 sub do_cache_new {  sub do_cache_new {
     my ($name,$id,$value,$time,$debug) = @_;      my ($name,$id,$value,$time,$debug) = @_;
       my $remembered_id=$name.':'.$id;
     $id=&make_key($name,$id);      $id=&make_key($name,$id);
     my $setvalue=$value;      my $setvalue=$value;
     if (!defined($setvalue)) {      if (!defined($setvalue)) {
Line 2601  sub do_cache_new { Line 2695  sub do_cache_new {
  $memcache->disconnect_all();   $memcache->disconnect_all();
     }      }
     # need to make a copy of $value      # need to make a copy of $value
     &make_room($id,$value,$debug);      &make_room($remembered_id,$value,$debug);
     return $value;      return $value;
 }  }
   
 sub make_room {  sub make_room {
     my ($id,$value,$debug)=@_;      my ($remembered_id,$value,$debug)=@_;
   
     $remembered{$id}= (ref($value)) ? &Storable::dclone($value)      $remembered{$remembered_id}= (ref($value)) ? &Storable::dclone($value)
                                     : $value;                                      : $value;
     if ($to_remember<0) { return; }      if ($to_remember<0) { return; }
     $accessed{$id}=[&gettimeofday()];      $accessed{$remembered_id}=[&gettimeofday()];
     if (scalar(keys(%remembered)) <= $to_remember) { return; }      if (scalar(keys(%remembered)) <= $to_remember) { return; }
     my $to_kick;      my $to_kick;
     my $max_time=0;      my $max_time=0;
Line 4029  sub flushcourselogs { Line 4123  sub flushcourselogs {
         delete $domainrolehash{$entry};          delete $domainrolehash{$entry};
     }      }
     foreach my $dom (keys(%domrolebuffer)) {      foreach my $dom (keys(%domrolebuffer)) {
  my %servers = &get_servers($dom,'library');   my %servers;
    if (defined(&domain($dom,'primary'))) {
       my $primary=&domain($dom,'primary');
       my $hostname=&hostname($primary);
       $servers{$primary} = $hostname;
    } else { 
       %servers = &get_servers($dom,'library');
    }
  foreach my $tryserver (keys(%servers)) {   foreach my $tryserver (keys(%servers)) {
     unless (&reply('domroleput:'.$dom.':'.      if (&reply('domroleput:'.$dom.':'.
    $domrolebuffer{$dom},$tryserver) eq 'ok') {         $domrolebuffer{$dom},$tryserver) eq 'ok') {
    last;
       } else {  
  &logthis('Put of domain roles failed for '.$dom.' and  '.$tryserver);   &logthis('Put of domain roles failed for '.$dom.' and  '.$tryserver);
     }      }
         }          }
Line 4633  my %cachedtimes=(); Line 4736  my %cachedtimes=();
 my $cachedtime='';  my $cachedtime='';
   
 sub load_all_first_access {  sub load_all_first_access {
     my ($uname,$udom)=@_;      my ($uname,$udom,$ignorecache)=@_;
     if (($cachedkey eq $uname.':'.$udom) &&      if (($cachedkey eq $uname.':'.$udom) &&
         (abs($cachedtime-time)<5) && (!$env{'form.markaccess'})) {          (abs($cachedtime-time)<5) && (!$env{'form.markaccess'}) &&
           (!$ignorecache)) {
         return;          return;
     }      }
     $cachedtime=time;      $cachedtime=time;
Line 4644  sub load_all_first_access { Line 4748  sub load_all_first_access {
 }  }
   
 sub get_first_access {  sub get_first_access {
     my ($type,$argsymb,$argmap)=@_;      my ($type,$argsymb,$argmap,$ignorecache)=@_;
     my ($symb,$courseid,$udom,$uname)=&whichuser();      my ($symb,$courseid,$udom,$uname)=&whichuser();
     if ($argsymb) { $symb=$argsymb; }      if ($argsymb) { $symb=$argsymb; }
     my ($map,$id,$res)=&decode_symb($symb);      my ($map,$id,$res)=&decode_symb($symb);
Line 4656  sub get_first_access { Line 4760  sub get_first_access {
     } else {      } else {
  $res=$symb;   $res=$symb;
     }      }
     &load_all_first_access($uname,$udom);      &load_all_first_access($uname,$udom,$ignorecache);
     return $cachedtimes{"$courseid\0$res"};      return $cachedtimes{"$courseid\0$res"};
 }  }
   
Line 6530  sub usertools_access { Line 6634  sub usertools_access {
                       unofficial => 1,                        unofficial => 1,
                       community  => 1,                        community  => 1,
                       textbook   => 1,                        textbook   => 1,
                         placement  => 1,
                  );                   );
     } elsif ($context eq 'requestauthor') {      } elsif ($context eq 'requestauthor') {
         %tools = (          %tools = (
Line 7263  sub allowed { Line 7368  sub allowed {
        my $unamedom=$env{'user.name'}.':'.$env{'user.domain'};         my $unamedom=$env{'user.name'}.':'.$env{'user.domain'};
        if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.roles.denied'}         if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.roles.denied'}
    =~/\Q$rolecode\E/) {     =~/\Q$rolecode\E/) {
    if (($priv ne 'pch') && ($priv ne 'plc')) {      if (($priv ne 'pch') && ($priv ne 'plc') && ($priv ne 'pac')) {
        &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'.         &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'.
  'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '.   'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '.
  $env{'request.course.id'});   $env{'request.course.id'});
Line 7273  sub allowed { Line 7378  sub allowed {
   
        if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.users.denied'}         if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.users.denied'}
    =~/\Q$unamedom\E/) {     =~/\Q$unamedom\E/) {
    if (($priv ne 'pch') && ($priv ne 'plc')) {      if (($priv ne 'pch') && ($priv ne 'plc') && ($priv ne 'pac')) {
        &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.         &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.
  'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '.   'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '.
  $env{'request.course.id'});   $env{'request.course.id'});
Line 7352  sub constructaccess { Line 7457  sub constructaccess {
             $ownerhome = &homeserver($ownername,$ownerdomain);              $ownerhome = &homeserver($ownername,$ownerdomain);
             return ($ownername,$ownerdomain,$ownerhome);              return ($ownername,$ownerdomain,$ownerhome);
         }          }
           if ($env{'request.course.id'}) {
               if (($ownername eq $env{'course.'.$env{'request.course.id'}.'.num'}) &&
                   ($ownerdomain eq $env{'course.'.$env{'request.course.id'}.'.domain'})) {
                   if (&allowed('mdc',$env{'request.course.id'})) {
                       $ownerhome = $env{'course.'.$env{'request.course.id'}.'.home'};
                       return ($ownername,$ownerdomain,$ownerhome);
                   }
               }
           }
     }      }
   
 # We don't have any access right now. If we are not possibly going to do anything about this,  # We don't have any access right now. If we are not possibly going to do anything about this,
Line 7504  sub get_commblock_resources { Line 7618  sub get_commblock_resources {
                             }                              }
                         }                          }
                     }                      }
                     if ($interval[0] =~ /^\d+/) {                      if ($interval[0] =~ /^(\d+)/) {
                         my ($timelimit) = split(/_/,$interval[0]);                          my $timelimit = $1; 
                         my $first_access;                          my $first_access;
                         if ($type eq 'resource') {                          if ($type eq 'resource') {
                             $first_access=&get_first_access($interval[1],$item);                              $first_access=&get_first_access($interval[1],$item);
Line 7784  sub update_allusers_table { Line 7898  sub update_allusers_table {
   
 sub fetch_enrollment_query {  sub fetch_enrollment_query {
     my ($context,$affiliatesref,$replyref,$dom,$cnum) = @_;      my ($context,$affiliatesref,$replyref,$dom,$cnum) = @_;
     my $homeserver;      my ($homeserver,$sleep,$loopmax);
     my $maxtries = 1;      my $maxtries = 1;
     if ($context eq 'automated') {      if ($context eq 'automated') {
         $homeserver = $perlvar{'lonHostID'};          $homeserver = $perlvar{'lonHostID'};
           $sleep = 2;
           $loopmax = 100;
         $maxtries = 10; # will wait for up to 2000s for retrieval of classlist data before timeout          $maxtries = 10; # will wait for up to 2000s for retrieval of classlist data before timeout
     } else {      } else {
         $homeserver = &homeserver($cnum,$dom);          $homeserver = &homeserver($cnum,$dom);
Line 7805  sub fetch_enrollment_query { Line 7921  sub fetch_enrollment_query {
         &logthis('fetch_enrollment_query: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' context: '.$context.' '.$cnum);           &logthis('fetch_enrollment_query: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' context: '.$context.' '.$cnum); 
         return 'error: '.$queryid;          return 'error: '.$queryid;
     }      }
     my $reply = &get_query_reply($queryid);      my $reply = &get_query_reply($queryid,$sleep,$loopmax);
     my $tries = 1;      my $tries = 1;
     while (($reply=~/^timeout/) && ($tries < $maxtries)) {      while (($reply=~/^timeout/) && ($tries < $maxtries)) {
         $reply = &get_query_reply($queryid);          $reply = &get_query_reply($queryid,$sleep,$loopmax);
         $tries ++;          $tries ++;
     }      }
     if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) {      if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) {
         &logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$env{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries);          &logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$env{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries);
     } else {      } else {
         my @responses = split(/:/,$reply);          my @responses = split(/:/,$reply);
         if ($homeserver eq $perlvar{'lonHostID'}) {          if (grep { $_ eq $homeserver } &current_machine_ids()) {
             foreach my $line (@responses) {              foreach my $line (@responses) {
                 my ($key,$value) = split(/=/,$line,2);                  my ($key,$value) = split(/=/,$line,2);
                 $$replyref{$key} = $value;                  $$replyref{$key} = $value;
Line 7850  sub fetch_enrollment_query { Line 7966  sub fetch_enrollment_query {
 }  }
   
 sub get_query_reply {  sub get_query_reply {
     my $queryid=shift;      my ($queryid,$sleep,$loopmax) = @_;;
       if (($sleep eq '') || ($sleep !~ /^\d+\.?\d*$/)) {
           $sleep = 0.2;
       }
       if (($loopmax eq '') || ($loopmax =~ /\D/)) {
           $loopmax = 100;
       }
     my $replyfile=LONCAPA::tempdir().$queryid;      my $replyfile=LONCAPA::tempdir().$queryid;
     my $reply='';      my $reply='';
     for (1..100) {      for (1..$loopmax) {
  sleep(0.2);   sleep($sleep);
         if (-e $replyfile.'.end') {          if (-e $replyfile.'.end') {
     if (open(my $fh,$replyfile)) {      if (open(my $fh,$replyfile)) {
  $reply = join('',<$fh>);   $reply = join('',<$fh>);
Line 8277  sub auto_crsreq_update { Line 8399  sub auto_crsreq_update {
     return \%crsreqresponse;      return \%crsreqresponse;
 }  }
   
   sub auto_export_grades {
       my ($cdom,$cnum,$inforef,$gradesref) = @_;
       my ($homeserver,%exportresponse);
       if ($cdom =~ /^$match_domain$/) {
           $homeserver = &domain($cdom,'primary');
       }
       unless (($homeserver eq 'no_host') || ($homeserver eq '')) {
           my $info;
           if (ref($inforef) eq 'HASH') {
               $info = &freeze_escape($inforef);
           }
           if (ref($gradesref) eq 'HASH') {
               my $grades = &freeze_escape($gradesref);
               my $response=&reply('encrypt:autoexportgrades:'.$cdom.':'.$cnum.':'.
                                   $info.':'.$grades,$homeserver);
               unless ($response =~ /(con_lost|error|no_such_host|refused|unknown_command)/) {
                   my @items = split(/&/,$response);
                   foreach my $item (@items) {
                       my ($key,$value) = split('=',$item);
                       $exportresponse{&unescape($key)} = &thaw_unescape($value);
                   }
               }
           }
       }
       return \%exportresponse;
   }
   
 sub check_instcode_cloning {  sub check_instcode_cloning {
     my ($codedefaults,$code_order,$cloner,$clonefromcode,$clonetocode) = @_;      my ($codedefaults,$code_order,$cloner,$clonefromcode,$clonetocode) = @_;
     unless ((ref($codedefaults) eq 'HASH') && (ref($code_order) eq 'ARRAY')) {      unless ((ref($codedefaults) eq 'HASH') && (ref($code_order) eq 'ARRAY')) {
Line 8498  sub plaintext { Line 8647  sub plaintext {
     my %rolenames = (      my %rolenames = (
                       Course    => 'std',                        Course    => 'std',
                       Community => 'alt1',                        Community => 'alt1',
                         Placement => 'std',
                     );                      );
     if ($cid ne '') {      if ($cid ne '') {
         if ($env{'course.'.$cid.'.'.$short.'.plaintext'} ne '') {          if ($env{'course.'.$cid.'.'.$short.'.plaintext'} ne '') {
Line 9020  sub modifyuser { Line 9170  sub modifyuser {
 sub modifystudent {  sub modifystudent {
     my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec,      my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec,
         $end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid,          $end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid,
         $selfenroll,$context,$inststatus,$credits)=@_;          $selfenroll,$context,$inststatus,$credits,$instsec)=@_;
     if (!$cid) {      if (!$cid) {
  unless ($cid=$env{'request.course.id'}) {   unless ($cid=$env{'request.course.id'}) {
     return 'not_in_class';      return 'not_in_class';
Line 9036  sub modifystudent { Line 9186  sub modifystudent {
     $uid = undef if (!$forceid);      $uid = undef if (!$forceid);
     $reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last,      $reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last,
                                         $gene,$usec,$end,$start,$type,$locktype,                                          $gene,$usec,$end,$start,$type,$locktype,
                                         $cid,$selfenroll,$context,$credits);                                          $cid,$selfenroll,$context,$credits,$instsec);
     return $reply;      return $reply;
 }  }
   
 sub modify_student_enrollment {  sub modify_student_enrollment {
     my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,      my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,
         $locktype,$cid,$selfenroll,$context,$credits) = @_;          $locktype,$cid,$selfenroll,$context,$credits,$instsec) = @_;
     my ($cdom,$cnum,$chome);      my ($cdom,$cnum,$chome);
     if (!$cid) {      if (!$cid) {
  unless ($cid=$env{'request.course.id'}) {   unless ($cid=$env{'request.course.id'}) {
Line 9089  sub modify_student_enrollment { Line 9239  sub modify_student_enrollment {
     my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum);      my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum);
     my $reply=cput('classlist',      my $reply=cput('classlist',
    {$user =>      {$user => 
  join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype,$credits) },   join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype,$credits,$instsec) },
    $cdom,$cnum);     $cdom,$cnum);
     if (($reply eq 'ok') || ($reply eq 'delayed')) {      if (($reply eq 'ok') || ($reply eq 'delayed')) {
         &devalidate_getsection_cache($udom,$uname,$cid);          &devalidate_getsection_cache($udom,$uname,$cid);
Line 10075  sub dirlist { Line 10225  sub dirlist {
             foreach my $user (sort(keys(%allusers))) {              foreach my $user (sort(keys(%allusers))) {
                 push(@alluserslist,$user.'&user');                  push(@alluserslist,$user.'&user');
             }              }
             return (\@alluserslist);  
               if (!%listerror) {
                   # no errors
                   return (\@alluserslist);
               } elsif (scalar(keys(%servers)) == 1) {
                   # one library server, one error 
                   my ($key) = keys(%listerror);
                   return (\@alluserslist, $listerror{$key});
               } elsif ( grep { $_ eq 'con_lost' } values(%listerror) ) {
                   # con_lost indicates that we might miss data from at least one
                   # library server
                   return (\@alluserslist, 'con_lost');
               } else {
                   # multiple library servers and no con_lost -> data should be
                   # complete. 
                   return (\@alluserslist);
               }
   
         } else {          } else {
             return ([],'missing username');              return ([],'missing username');
         }          }
Line 10148  sub stat_file { Line 10315  sub stat_file {
     return ();      return ();
 }  }
   
   # --------------------------------------------------------- recursedirs
   # Recursive function to traverse either a specific user's Authoring Space
   # or corresponding Published Resource Space, and populate the hash ref:
   # $dirhashref with URLs of all directories, and if $filehashref hash
   # ref arg is provided, the URLs of any files, excluding versioned, .meta,
   # or .rights files in resource space, and .meta, .save, .log, and .bak
   # files in Authoring Space.
   #
   # Inputs:
   #
   # $is_home - true if current server is home server for user's space
   # $context - either: priv, or res respectively for Authoring or Resource Space.
   # $docroot - Document root (i.e., /home/httpd/html
   # $toppath - Top level directory (i.e., /res/$dom/$uname or /priv/$dom/$uname
   # $relpath - Current path (relative to top level).
   # $dirhashref - reference to hash to populate with URLs of directories (Required)
   # $filehashref - reference to hash to populate with URLs of files (Optional)
   #
   # Returns: nothing
   #
   # Side Effects: populates $dirhashref, and $filehashref (if provided).
   #
   # Currently used by interface/londocs.pm to create linked select boxes for
   # directory and filename to import a Course "Author" resource into a course, and
   # also to create linked select boxes for Authoring Space and Directory to choose
   # save location for creation of a new "standard" problem from the Course Editor.
   #
   
   sub recursedirs {
       my ($is_home,$context,$docroot,$toppath,$relpath,$dirhashref,$filehashref) = @_;
       return unless (ref($dirhashref) eq 'HASH');
       my $currpath = $docroot.$toppath;
       if ($relpath) {
           $currpath .= "/$relpath";
       }
       my $savefile;
       if (ref($filehashref)) {
           $savefile = 1;
       }
       if ($is_home) {
           if (opendir(my $dirh,$currpath)) {
               foreach my $item (sort { lc($a) cmp lc($b) } grep(!/^\.+$/,readdir($dirh))) {
                   next if ($item eq '');
                   if (-d "$currpath/$item") {
                       my $newpath;
                       if ($relpath) {
                           $newpath = "$relpath/$item";
                       } else {
                           $newpath = $item;
                       }
                       $dirhashref->{&Apache::lonlocal::js_escape($newpath)} = 1;
                       &recursedirs($is_home,$context,$docroot,$toppath,$newpath,$dirhashref,$filehashref);
                   } elsif ($savefile) {
                       if ($context eq 'priv') {
                           unless ($item =~ /\.(meta|save|log|bak|DS_Store)$/) {
                               $filehashref->{&Apache::lonlocal::js_escape($relpath)}{$item} = 1;
                           }
                       } else {
                           unless (($item =~ /\.meta$/) || ($item =~ /\.\d+\.\w+$/) || ($item =~ /\.rights$/)) {
                               $filehashref->{&Apache::lonlocal::js_escape($relpath)}{$item} = 1;
                           }
                       }
                   }
               }
               closedir($dirh);
           }
       } else {
           my ($dirlistref,$listerror) =
               &dirlist($toppath.$relpath);
           my @dir_lines;
           my $dirptr=16384;
           if (ref($dirlistref) eq 'ARRAY') {
               foreach my $dir_line (sort
                                 {
                                     my ($afile)=split('&',$a,2);
                                     my ($bfile)=split('&',$b,2);
                                     return (lc($afile) cmp lc($bfile));
                                 } (@{$dirlistref})) {
                   my ($item,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef) =
                       split(/\&/,$dir_line,16);
                   $item =~ s/\s+$//;
                   next if (($item =~ /^\.\.?$/) || ($obs));
                   if ($dirptr&$testdir) {
                       my $newpath;
                       if ($relpath) {
                           $newpath = "$relpath/$item";
                       } else {
                           $relpath = '/';
                           $newpath = $item;
                       }
                       $dirhashref->{&Apache::lonlocal::js_escape($newpath)} = 1;
                       &recursedirs($is_home,$context,$docroot,$toppath,$newpath,$dirhashref,$filehashref);
                   } elsif ($savefile) {
                       if ($context eq 'priv') {
                           unless ($item =~ /\.(meta|save|log|bak|DS_Store)$/) {
                               $filehashref->{$relpath}{$item} = 1;
                           }
                       } else {
                           unless (($item =~ /\.meta$/) || ($item =~ /\.\d+\.\w+$/)) {
                               $filehashref->{$relpath}{$item} = 1;
                           }
                       }
                   }
               }
           }
       }
       return;
   }
   
 # -------------------------------------------------------- Value of a Condition  # -------------------------------------------------------- Value of a Condition
   
 # gets the value of a specific preevaluated condition  # gets the value of a specific preevaluated condition
Line 10311  sub get_userresdata { Line 10587  sub get_userresdata {
 #  Parameters:  #  Parameters:
 #     $name      - Course/user name.  #     $name      - Course/user name.
 #     $domain    - Name of the domain the user/course is registered on.  #     $domain    - Name of the domain the user/course is registered on.
 #     $type      - Type of thing $name is (must be 'course' or 'user'  #     $type      - Type of thing $name is (must be 'course' or 'user')
 #     $mapp      - decluttered URL of enclosing map    #     $mapp      - decluttered URL of enclosing map  
 #     $recursed  - Ref to scalar -- set to 1, if nested maps have been recursed.  #     $recursed  - Ref to scalar -- set to 1, if nested maps have been recursed.
 #     $recurseup - Ref to array of map URLs, starting with map containing  #     $recurseup - Ref to array of map URLs, starting with map containing
Line 10341  sub resdata { Line 10617  sub resdata {
         if ($item->[1] eq 'course') {          if ($item->[1] eq 'course') {
             if ((ref($recurseup) eq 'ARRAY') && (ref($recursed) eq 'SCALAR')) {              if ((ref($recurseup) eq 'ARRAY') && (ref($recursed) eq 'SCALAR')) {
                 unless ($$recursed) {                  unless ($$recursed) {
                     @{$recurseup} = &get_map_hierarchy($mapp);                      @{$recurseup} = &get_map_hierarchy($mapp,$courseid);
                     $$recursed = 1;                      $$recursed = 1;
                 }                  }
                 foreach my $item (@${recurseup}) {                  foreach my $item (@${recurseup}) {
Line 10402  sub get_numsuppfiles { Line 10678  sub get_numsuppfiles {
 # EXT resource caching routines  # EXT resource caching routines
 #  #
   
   {
   # Cache (5 seconds) of map hierarchy for speedup of navmaps display
   #
   # The course for which we cache
   my $cachedmapkey='';
   # The cached recursive maps for this course
   my %cachedmaps=();
   # When this was last done
   my $cachedmaptime='';
   
 sub clear_EXT_cache_status {  sub clear_EXT_cache_status {
     &delenv('cache.EXT.');      &delenv('cache.EXT.');
 }  }
Line 10592  sub EXT { Line 10878  sub EXT {
 # ----------------------------------------------------- Cascading lookup scheme  # ----------------------------------------------------- Cascading lookup scheme
     my $symbp=$symbparm;      my $symbp=$symbparm;
     $mapp=&deversion((&decode_symb($symbp))[0]);      $mapp=&deversion((&decode_symb($symbp))[0]);
             @recurseup=();  
     my $symbparm=$symbp.'.'.$spacequalifierrest;      my $symbparm=$symbp.'.'.$spacequalifierrest;
             my $recurseparm=$mapp.'___(rec).'.$spacequalifierrest;              my $recurseparm=$mapp.'___(rec).'.$spacequalifierrest;
     my $mapparm=$mapp.'___(all).'.$spacequalifierrest;      my $mapparm=$mapp.'___(all).'.$spacequalifierrest;
Line 10764  sub check_group_parms { Line 11049  sub check_group_parms {
 }  }
   
 sub get_map_hierarchy {  sub get_map_hierarchy {
     my ($mapname) = @_;      my ($mapname,$courseid) = @_;
     my @recurseup = ();       my @recurseup = ();
     if ($mapname) {      if ($mapname) {
           if (($cachedmapkey eq $courseid) &&
               (abs($cachedmaptime-time)<5)) {
               if (ref($cachedmaps{$mapname}) eq 'ARRAY') {
                   return @{$cachedmaps{$mapname}};
               }
           }
         my $navmap = Apache::lonnavmaps::navmap->new();          my $navmap = Apache::lonnavmaps::navmap->new();
         if (ref($navmap)) {          if (ref($navmap)) {
             @recurseup = $navmap->recurseup_maps($mapname);              @recurseup = $navmap->recurseup_maps($mapname);
             undef($navmap);              undef($navmap);
               $cachedmaps{$mapname} = \@recurseup;
               $cachedmaptime=time;
               $cachedmapkey=$courseid;
         }          }
     }      }
     return @recurseup;      return @recurseup;
 }  }
   
   }
   
 sub sort_course_groups { # Sort groups based on defined rankings. Default is sort().  sub sort_course_groups { # Sort groups based on defined rankings. Default is sort().
     my ($courseid,@groups) = @_;      my ($courseid,@groups) = @_;
     @groups = sort(@groups);      @groups = sort(@groups);
Line 13064  BEGIN { Line 13360  BEGIN {
                 my $name = $token->[2]{'name'};                  my $name = $token->[2]{'name'};
                 my $value = $token->[2]{'value'};                  my $value = $token->[2]{'value'};
                 my $valuematch = $token->[2]{'valuematch'};                  my $valuematch = $token->[2]{'valuematch'};
                 if ($item ne '' && $name ne '' && ($value ne '' || $valuematch ne '')) {                  my $namematch = $token->[2]{'namematch'};
                   if ($item eq 'parameter') {
                       if (($namematch ne '') || (($name ne '') && ($value ne '' || $valuematch ne ''))) {
                           my $release = $parser->get_text();
                           $release =~ s/(^\s*|\s*$ )//gx;
                           $needsrelease{$item.':'.$name.':'.$value.':'.$valuematch.':'.$namematch} = $release;
                       }
                   } elsif ($item ne '' && $name ne '') {
                     my $release = $parser->get_text();                      my $release = $parser->get_text();
                     $release =~ s/(^\s*|\s*$ )//gx;                      $release =~ s/(^\s*|\s*$ )//gx;
                     $needsrelease{$item.':'.$name.':'.$value.':'.$valuematch} = $release;                      $needsrelease{$item.':'.$name.':'.$value} = $release;
                 }                  }
             }              }
         }          }
Line 13659  Inputs: Line 13962  Inputs:
   
 =item $credits, number of credits student will earn from this class  =item $credits, number of credits student will earn from this class
   
   =item $instsec, institutional course section code for student
   
 =back  =back
   
   
Line 14127  requestcourses: ability to request cours Line 14432  requestcourses: ability to request cours
 =over  =over
   
 =item  =item
 official, unofficial, community, textbook  official, unofficial, community, textbook, placement
   
 =back  =back
   
Line 14149  for course's uploaded content. Line 14454  for course's uploaded content.
   
 =item  =item
 canuse_pdfforms, officialcredits, unofficialcredits, textbookcredits, officialquota, unofficialquota,   canuse_pdfforms, officialcredits, unofficialcredits, textbookcredits, officialquota, unofficialquota, 
 communityquota, textbookquota  communityquota, textbookquota, placementquota
   
 =back  =back
   

Removed from v.1.1301  
changed lines
  Added in v.1.1324


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