Diff for /loncom/interface/loncoursedata.pm between versions 1.35 and 1.55

version 1.35, 2002/10/14 19:06:21 version 1.55, 2003/03/03 21:52:24
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # (Publication Handler  
 #  #
 # $Id$  # $Id$
 #  #
Line 120  sub DownloadClasslist { Line 119  sub DownloadClasslist {
     my ($courseDomain,$courseNumber)=split(/\_/,$courseID);      my ($courseDomain,$courseNumber)=split(/\_/,$courseID);
     my %classlist;      my %classlist;
   
     my $modifiedTime = &Apache::lonnet::GetFileTimestamp($courseDomain, $courseNumber,      my $modifiedTime = &Apache::lonnet::GetFileTimestamp($courseDomain, 
                                                            $courseNumber,
                                                          'classlist.db',                                                            'classlist.db', 
                                                          $Apache::lonnet::perlvar{'lonUsersDir'});                                   $Apache::lonnet::perlvar{'lonUsersDir'});
   
     # Always download the information if lastDownloadTime is set to      # Always download the information if lastDownloadTime is set to
     # Not downloaded, otherwise it is only downloaded if the file      # Not downloaded, otherwise it is only downloaded if the file
Line 218  sub DownloadCourseInformation { Line 218  sub DownloadCourseInformation {
                                       $courseID.'.db',                                         $courseID.'.db', 
                                       $Apache::lonnet::perlvar{'lonUsersDir'});                                        $Apache::lonnet::perlvar{'lonUsersDir'});
   
     if($lastDownloadTime >= $modifiedTime && $modifiedTime >= 0) {      if($lastDownloadTime ne 'Not downloaded' && 
          $lastDownloadTime >= $modifiedTime && $modifiedTime >= 0) {
         # Data is not gathered so return UpToDate as true.  This          # Data is not gathered so return UpToDate as true.  This
         # will be interpreted in ProcessClasslist          # will be interpreted in ProcessClasslist
         $courseData{$namedata.':lastDownloadTime'}=time;          $courseData{$namedata.':lastDownloadTime'}=time;
Line 260  with stopping downloading then can not t Line 261  with stopping downloading then can not t
   
 # ----- PROCESSING FUNCTIONS ---------------------------------------  # ----- PROCESSING FUNCTIONS ---------------------------------------
   
   ####################################################
   ####################################################
   
   =pod
   
   =item &get_sequence_assessment_data()
   
   AT THIS TIME THE USE OF THIS FUNCTION IS *NOT* RECOMMENDED
   
   Use lonnavmaps to build a data structure describing the order and 
   assessment contents of each sequence in the current course.
   
   The returned structure is a hash reference. 
   
   { title  => 'title',
     symb   => 'symb',
     source => '/s/o/u/r/c/e',
     type  => (container|assessment),
     num_assess   => 2,               # only for container
     parts        => [11,13,15],      # only for assessment
     response_ids => [12,14,16],      # only for assessment
     contents     => [........]       # only for container
   }
   
   $hash->{'contents'} is a reference to an array of hashes of the same structure.
   
   Also returned are array references to the sequences and assessments contained
   in the course.
   
   
   =cut
   
   ####################################################
   ####################################################
   sub get_sequence_assessment_data {
       my $fn=$ENV{'request.course.fn'};
       ##
       ## use navmaps
       my $navmap = Apache::lonnavmaps::navmap->new($fn.".db",$fn."_parms.db",
                                                    1,0);
       if (!defined($navmap)) {
           return 'Can not open Coursemap';
       }
       my $iterator = $navmap->getIterator(undef, undef, undef, 1);
       ##
       ## Prime the pump 
       ## 
       ## We are going to loop until we run out of sequences/pages to explore for
       ## resources.  This means we have to start out with something to look
       ## at.
       my $title = $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
       my $symb  = 'top';
       my $src   = 'not applicable';
       #
       my @Sequences; 
       my @Assessments;
       my @Nested_Sequences = ();   # Stack of sequences, keeps track of depth
       my $top = { title    => $title,
                   src      => $src,
                   symb     => $symb,
                   type     => 'container',
                   num_assess => 0,
                   num_assess_parts => 0,
                   contents   => [], };
       push (@Sequences,$top);
       push (@Nested_Sequences, $top);
       #
       # We need to keep track of which sequences contain homework problems
       # 
       my $previous;
       my $curRes = $iterator->next(); # BEGIN_MAP
       $curRes = $iterator->next(); # The first item in the top level map.
       while (scalar(@Nested_Sequences)) {
           $previous = $curRes;
           $curRes = $iterator->next();
           my $currentmap = $Nested_Sequences[-1]; # Last one on the stack
           if ($curRes == $iterator->BEGIN_MAP()) {
               # get the map itself, instead of BEGIN_MAP
               $title = $previous->title();
               $symb  = $previous->symb();
               $src   = $previous->src();
               my $newmap = { title    => $title,
                              src      => $src,
                              symb     => $symb,
                              type     => 'container',
                              num_assess => 0,
                              contents   => [],
                          };
               push (@{$currentmap->{'contents'}},$newmap); # this is permanent
               push (@Sequences,$newmap);
               push (@Nested_Sequences, $newmap); # this is a stack
               next;
           }
           if ($curRes == $iterator->END_MAP()) {
               pop(@Nested_Sequences);
               next;
           }
           next if (! ref($curRes));
           next if (! $curRes->is_problem());# && !$curRes->randomout);
           # Okay, from here on out we only deal with assessments
           $title = $curRes->title();
           $symb  = $curRes->symb();
           $src   = $curRes->src();
           my $parts = $curRes->parts();
           my $assessment = { title => $title,
                              src   => $src,
                              symb  => $symb,
                              type  => 'assessment',
                              parts => $parts,
                              num_parts => scalar(@$parts),
                          };
           push(@Assessments,$assessment);
           push(@{$currentmap->{'contents'}},$assessment);
           $currentmap->{'num_assess'}++;
           $currentmap->{'num_assess_parts'}+= scalar(@$parts);
       }
       return ($top,\@Sequences,\@Assessments);
   }
   
   #################################################
   #################################################
   
 =pod  =pod
   
 =item &ProcessTopResourceMap()  =item &ProcessTopResourceMap()
Line 310  sub ProcessTopResourceMap { Line 433  sub ProcessTopResourceMap {
     }      }
   
     my $oldkeys;      my $oldkeys;
       delete $cache->{'OptionResponses'};
     if(defined($cache->{'ResourceKeys'})) {      if(defined($cache->{'ResourceKeys'})) {
         $oldkeys = $cache->{'ResourceKeys'};          $oldkeys = $cache->{'ResourceKeys'};
         foreach (split(':::', $cache->{'ResourceKeys'})) {          foreach (split(':::', $cache->{'ResourceKeys'})) {
Line 487  sub ProcessTopResourceMap { Line 611  sub ProcessTopResourceMap {
                 }                  }
  my @titleLength=split(//,$cache->{$currentSequence.   my @titleLength=split(//,$cache->{$currentSequence.
                                                     ':title'});                                                      ':title'});
                 # $extra is 3 for problems correct and 3 for space                  # $extra is 5 for problems correct and 3 for space
                 # between problems correct and problem output                  # between problems correct and problem output
                 my $extra = 6;                  my $extra = 8;
  if(($totalProblems + $extra) > (scalar @titleLength)) {   if(($totalProblems + $extra) > (scalar @titleLength)) {
     $cache->{$currentSequence.':columnWidth'}=      $cache->{$currentSequence.':columnWidth'}=
                         $totalProblems + $extra;                          $totalProblems + $extra;
Line 518  sub ProcessTopResourceMap { Line 642  sub ProcessTopResourceMap {
     # big problem, need to handle.  Next is probably wrong      # big problem, need to handle.  Next is probably wrong
             my $errorMessage = 'Big problem in ';              my $errorMessage = 'Big problem in ';
             $errorMessage .= 'loncoursedata::ProcessTopLevelMap.';              $errorMessage .= 'loncoursedata::ProcessTopLevelMap.';
             $errorMessage .= '  bighash to_$currentResourceID not defined!';              $errorMessage .= "  bighash to_$currentResourceID not defined!";
             &Apache::lonnet::logthis($errorMessage);              &Apache::lonnet::logthis($errorMessage);
     last;      if (!defined($currentResourceID)) {last;}
  }   }
  my @nextResources=();   my @nextResources=();
  foreach (split(/\,/,$hash{'to_'.$currentResourceID})) {   foreach (split(/\,/,$hash{'to_'.$currentResourceID})) {
Line 1179  sub DownloadStudentCourseData { Line 1303  sub DownloadStudentCourseData {
     my $WhatIWant;      my $WhatIWant;
     $WhatIWant = '(^version:|';      $WhatIWant = '(^version:|';
     $WhatIWant .= '^\d+:.+?:(resource\.\d+\.';      $WhatIWant .= '^\d+:.+?:(resource\.\d+\.';
     $WhatIWant .= '(solved|tries|previous|awarded|(\d+\.submission))\s*$';      $WhatIWant .= '(solved|tries|previous|awarded|(\d+\.submission))\s*$';#'
     $WhatIWant .= '|timestamp)';      $WhatIWant .= '|timestamp)';
     $WhatIWant .= ')';      $WhatIWant .= ')';
 #    $WhatIWant = '.';  #    $WhatIWant = '.';
   
       my %prog_state;
     if($status eq 'true') {      if($status eq 'true') {
         &Apache::lonhtmlcommon::Create_PrgWin($r, $title, $heading);          %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r, $title,
          $heading,($#$students)+1);
     }      }
   
     my $displayString;  
     my $count=0;  
     foreach (@$students) {      foreach (@$students) {
         my %cache;          my %cache;
   
         if($c->aborted()) { return 'Aborted'; }          if($c->aborted()) { return 'Aborted'; }
   
         if($status eq 'true') {          if($status eq 'true') {
             $count++;              &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
             my $displayString = $count.'/'.$studentCount.': '.$_;    'last student '.$_);
             &Apache::lonhtmlcommon::Update_PrgWin($displayString, $r);  
         }          }
   
         my $downloadTime='Not downloaded';          my $downloadTime='Not downloaded';
Line 1235  sub DownloadStudentCourseData { Line 1358  sub DownloadStudentCourseData {
     next;      next;
  }   }
     }      }
     if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r); }      if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); }
   
     return 'OK';      return 'OK';
 }  }
   
 sub DownloadStudentCourseDataSeparate {  sub DownloadStudentCourseDataSeparate {
     my ($students,$checkDate,$cacheDB,$extract,$status,$courseID,$r,$c)=@_;      my ($students,$checkDate,$cacheDB,$extract,$status,$courseID,$r,$c)=@_;
     my $residualFile = '/home/httpd/perl/tmp/'.$courseID.'DownloadFile.db';      my $residualFile = $Apache::lonnet::tmpdir.$courseID.'DownloadFile.db';
     my $title = 'LON-CAPA Statistics';      my $title = 'LON-CAPA Statistics';
     my $heading = 'Download Course Data';      my $heading = 'Download Course Data';
   
     my $WhatIWant;      my $WhatIWant;
     $WhatIWant = '(^version:|';      $WhatIWant = '(^version:|';
     $WhatIWant .= '^\d+:.+?:(resource\.\d+\.';      $WhatIWant .= '^\d+:.+?:(resource\.\d+\.';
     $WhatIWant .= '(solved|tries|previous|awarded|(\d+\.submission))\s*$';      $WhatIWant .= '(solved|tries|previous|awarded|(\d+\.submission))\s*$';#'
     $WhatIWant .= '|timestamp)';      $WhatIWant .= '|timestamp)';
     $WhatIWant .= ')';      $WhatIWant .= ')';
   
     &CheckForResidualDownload($cacheDB, 'true', 'true', $courseID, $r, $c);      &CheckForResidualDownload($cacheDB, 'true', 'true', $courseID, $r, $c);
   
     my $studentCount = scalar(@$students);      my $studentCount = scalar(@$students);
       my %prog_state;
     if($status eq 'true') {      if($status eq 'true') {
         &Apache::lonhtmlcommon::Create_PrgWin($r, $title, $heading);          %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r, $title,
        $heading,($#$students)+1);
     }      }
     my $count=0;  
     my $displayString='';      my $displayString='';
     foreach (@$students) {      foreach (@$students) {
         if($c->aborted()) {          if($c->aborted()) {
Line 1267  sub DownloadStudentCourseDataSeparate { Line 1391  sub DownloadStudentCourseDataSeparate {
         }          }
   
         if($status eq 'true') {          if($status eq 'true') {
             $count++;              &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
             $displayString = $count.'/'.$studentCount.': '.$_;    'last student '.$_);
             &Apache::lonhtmlcommon::Update_PrgWin($displayString, $r);  
         }          }
   
         my %cache;          my %cache;
Line 1314  sub DownloadStudentCourseDataSeparate { Line 1437  sub DownloadStudentCourseDataSeparate {
         }          }
         untie(%downloadData);          untie(%downloadData);
     }      }
     if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r); }      if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r,
     \%prog_state); }
   
     return &CheckForResidualDownload($cacheDB, 'true', 'true',       return &CheckForResidualDownload($cacheDB, 'true', 'true', 
                                      $courseID, $r, $c);                                       $courseID, $r, $c);
Line 1323  sub DownloadStudentCourseDataSeparate { Line 1447  sub DownloadStudentCourseDataSeparate {
 sub CheckForResidualDownload {  sub CheckForResidualDownload {
     my ($cacheDB,$extract,$status,$courseID,$r,$c)=@_;      my ($cacheDB,$extract,$status,$courseID,$r,$c)=@_;
   
     my $residualFile = '/home/httpd/perl/tmp/'.$courseID.'DownloadFile.db';      my $residualFile = $Apache::lonnet::tmpdir.$courseID.'DownloadFile.db';
     if(!-e $residualFile) {      if(!-e $residualFile) {
         return 'OK';          return 'OK';
     }      }
Line 1353  sub CheckForResidualDownload { Line 1477  sub CheckForResidualDownload {
     my $heading = 'Process Course Data';      my $heading = 'Process Course Data';
     my $title = 'LON-CAPA Statistics';      my $title = 'LON-CAPA Statistics';
     my $studentCount = scalar(@students);      my $studentCount = scalar(@students);
       my %prog_state;
     if($status eq 'true') {      if($status eq 'true') {
         &Apache::lonhtmlcommon::Create_PrgWin($r, $title, $heading);          %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r, $title,
         $heading,$#students+1);
     }      }
   
     my $count=1;      my $count=1;
Line 1362  sub CheckForResidualDownload { Line 1488  sub CheckForResidualDownload {
         last if($c->aborted());          last if($c->aborted());
   
         if($status eq 'true') {          if($status eq 'true') {
             my $displayString = $count.'/'.$studentCount.': '.$name;      &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
             &Apache::lonhtmlcommon::Update_PrgWin($displayString, $r);       'last student '.$name);
         }          }
   
         if($extract eq 'true') {          if($extract eq 'true') {
Line 1374  sub CheckForResidualDownload { Line 1500  sub CheckForResidualDownload {
         $count++;          $count++;
     }      }
   
     if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r); }      if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r,
      \%prog_state); }
   
     untie(%cache);      untie(%cache);
     untie(%downloadData);      untie(%downloadData);
Line 1387  sub CheckForResidualDownload { Line 1514  sub CheckForResidualDownload {
     return 'OK';      return 'OK';
 }  }
   
   
   ################################################
   ################################################
   
   =pod
   
   =item &make_into_hash($values);
   
   Returns a reference to a hash as described by $values.  $values is
   assumed to be the result of 
       join(':',map {&Apache::lonnet::escape($_)} %orighash;
   
   This is a helper function for get_current_state.
   
   =cut
   
   ################################################
   ################################################
   sub make_into_hash {
       my $values = shift;
       my %tmp = map { &Apache::lonnet::unescape($_); }
                                              split(':',$values);
       return \%tmp;
   }
   
   
   ################################################
   ################################################
   
   =pod
   
   =item &get_current_state($sname,$sdom,$symb,$courseid);
   
   Retrieve the current status of a students performance.  $sname and
   $sdom are the only required parameters.  If $symb is undef the results
   of an &Apache::lonnet::currentdump() will be returned.  
   If $courseid is undef it will be retrieved from the environment.
   
   The return structure is based on &Apache::lonnet::currentdump.  If
   $symb is unspecified, all the students data is returned in a hash of
   the form:
   ( 
     symb1 => { param1 => value1, param2 => value2 ... },
     symb2 => { param1 => value1, param2 => value2 ... },
   )
   
   If $symb is specified, a hash of 
   (
     param1 => value1, 
     param2 => value2,
   )
   is returned.
   
   If no data is found for $symb, or if the student has not performance data,
   an empty list is returned.
   
   =cut
   
   ################################################
   ################################################
   sub get_current_state {
       my ($sname,$sdom,$symb,$courseid,$forcedownload)=@_;
       return () if (! defined($sname) || ! defined($sdom));
       #
       $courseid = $ENV{'request.course.id'} if (! defined($courseid));
       #
       my $cachefilename = $Apache::lonnet::tmpdir.$ENV{'user.name'}.'_'.
                                                   $ENV{'user.domain'}.'_'.
                                                   $courseid.'_student_data.db';
       my %cache;
       #
       my %student_data; # return values go here
       #
       my $updatetime = 0;
       my $key = &Apache::lonnet::escape($sname).':'.
                 &Apache::lonnet::escape($sdom).':';
       # Open the cache file
       if (tie(%cache,'GDBM_File',$cachefilename,&GDBM_READER(),0640)) {
           if (exists($cache{$key.'time'})) {
               $updatetime = $cache{$key.'time'};
   #            &Apache::lonnet::logthis('got updatetime of '.$updatetime);
           }
           untie(%cache);
       }
       # timestamp/devalidation 
       my $modifiedtime = 1;
       # Take whatever steps are neccessary at this point to give $modifiedtime a
       # new value
       #
       if (($updatetime < $modifiedtime) || 
           (defined($forcedownload) && $forcedownload)) {
   #        &Apache::lonnet::logthis("loading data");
           # Get all the students current data
           my $time_of_retrieval = time;
           my @tmp = &Apache::lonnet::currentdump($courseid,$sdom,$sname);
           if ((scalar(@tmp) > 0) && ($tmp[0] =~ /^error:/)) {
               &Apache::lonnet::logthis('error getting data for '.
                                        $sname.':'.$sdom.' in course '.$courseid.
                                        ':'.$tmp[0]);
               return ();
           }
           %student_data = @tmp;
           #
           # Store away the data
           #
           # The cache structure is colon deliminated.  
           # $uname:$udom:time  => timestamp
           # $uname:$udom:$symb => $parm1:$val1:$parm2:$val2 ...
           #
           # BEWARE: The colons are NOT escaped so can search with escaped 
           #         keys instead of unescaping every key.
           #
           if (tie(%cache,'GDBM_File',$cachefilename,&GDBM_WRCREAT(),0640)) {
   #            &Apache::lonnet::logthis("writing data");
               while (my ($current_symb,$param_hash) = each(%student_data)) {
                   my @Parameters = %{$param_hash};
                   my $value = join(':',map { &Apache::lonnet::escape($_); } 
                                    @Parameters);
                   # Store away the values
                   $cache{$key.&Apache::lonnet::escape($current_symb)}=$value;
               }
               $cache{$key.'time'}=$time_of_retrieval;
               untie(%cache);
           }
       } else {
           &Apache::lonnet::logthis('retrieving cached data ');
           if (tie(%cache,'GDBM_File',$cachefilename,&GDBM_READER(),0640)) {
               if (defined($symb)) {
                   my  $searchkey = $key.&Apache::lonnet::escape($symb);
                   if (exists($cache{$searchkey})) {
                       $student_data{$symb} = &make_into_hash($cache{$searchkey});
                   }
               } else {
                   my $searchkey = '^'.$key.'(.*)$';#'
                   while (my ($testkey,$params)=each(%cache)) {
                       if ($testkey =~ /$searchkey/) { # \Q \E?  May be necc.
                           my $tmpsymb = $1;
                           next if ($tmpsymb =~ 'time');
   #                        &Apache::lonnet::logthis('found '.$tmpsymb.':');
                           $student_data{&Apache::lonnet::unescape($tmpsymb)} = 
                               &make_into_hash($params);
                       }
                   }
               }
               untie(%cache);
           }
       }
       if (! defined($symb)) {
   #        &Apache::lonnet::logthis("returning all data");
           return %student_data;
       } elsif (exists($student_data{$symb})) {
   #        &Apache::lonnet::logthis("returning data for symb=".$symb);
           return %{$student_data{$symb}};
       } else {
           return ();
       }
   }
   
 ################################################  ################################################
 ################################################  ################################################
   
Line 1405  $ENV{'course.'.$cid.'.domain'}, and $ENV Line 1690  $ENV{'course.'.$cid.'.domain'}, and $ENV
   
 Returns a reference to a hash which contains:  Returns a reference to a hash which contains:
  keys    '$sname:$sdom'   keys    '$sname:$sdom'
  values  [$end,$start,$id,$section,$fullname]   values  [$sdom,$sname,$end,$start,$id,$section,$fullname,$status]
   
   The constant values CL_SDOM, CL_SNAME, CL_END, etc. can be used
   as indices into the returned list to future-proof clients against
   changes in the list order.
   
 =cut  =cut
   
 ################################################  ################################################
 ################################################  ################################################
   
   sub CL_SDOM     { return 0; }
   sub CL_SNAME    { return 1; }
   sub CL_END      { return 2; }
   sub CL_START    { return 3; }
   sub CL_ID       { return 4; }
   sub CL_SECTION  { return 5; }
   sub CL_FULLNAME { return 6; }
   sub CL_STATUS   { return 7; }
   
 sub get_classlist {  sub get_classlist {
     my ($cid,$cdom,$cnum) = @_;      my ($cid,$cdom,$cnum) = @_;
     $cid = $cid || $ENV{'request.course.id'};      $cid = $cid || $ENV{'request.course.id'};
Line 1429  sub get_classlist { Line 1727  sub get_classlist {
             ($end,$start,$id,$section,$fullname) = @Values;              ($end,$start,$id,$section,$fullname) = @Values;
         } else { # We have to get the data ourselves          } else { # We have to get the data ourselves
             ($end,$start) = @Values;              ($end,$start) = @Values;
             $section = &Apache::lonnet::usection($sdom,$sname,$cid);              $section = &Apache::lonnet::getsection($sdom,$sname,$cid);
             my %info=&Apache::lonnet::get('environment',              my %info=&Apache::lonnet::get('environment',
                                           ['firstname','middlename',                                            ['firstname','middlename',
                                            'lastname','generation','id'],                                             'lastname','generation','id'],
Line 1438  sub get_classlist { Line 1736  sub get_classlist {
             if ($tmp =~/^(con_lost|error|no_such_host)/i) {              if ($tmp =~/^(con_lost|error|no_such_host)/i) {
                 $fullname = 'not available';                  $fullname = 'not available';
                 $id = 'not available';                  $id = 'not available';
                   &Apache::lonnet::logthis('unable to retrieve environment '.
                                            'for '.$sname.':'.$sdom);
             } else {              } else {
                 $fullname = &ProcessFullName(@info{qw/lastname generation                   $fullname = &ProcessFullName(@info{qw/lastname generation 
                                                        firstname middlename/});                                                         firstname middlename/});
                 $id = $info{'id'};                  $id = $info{'id'};
             }              }
             # At this point, if we have the data (check for 'not available's              # Update the classlist with this students information
             # we could put it back into the classlist.db file.               if ($fullname ne 'not available') {
             # We have not decided to do that yet.                  my $enrolldata = join(':',$end,$start,$id,$section,$fullname);
                   my $reply=&Apache::lonnet::cput('classlist',
                                                   {$student => $enrolldata},
                                                   $cdom,$cnum);
                   if ($reply !~ /^(ok|delayed)/) {
                       &Apache::lonnet::logthis('Unable to update classlist for '.
                                                'student '.$sname.':'.$sdom.
                                                ' error:'.$reply);
                   }
               }
         }          }
         my $status='Expired';          my $status='Expired';
         if(((!$end) || $now < $end) && ((!$start) || ($now > $start))) {          if(((!$end) || $now < $end) && ((!$start) || ($now > $start))) {
Line 1467  sub get_classlist { Line 1776  sub get_classlist {
 1;  1;
 __END__  __END__
   
   

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


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