Diff for /loncom/interface/loncoursedata.pm between versions 1.12 and 1.21

version 1.12, 2002/08/05 14:16:19 version 1.21, 2002/08/28 18:29:22
Line 51  package Apache::loncoursedata; Line 51  package Apache::loncoursedata;
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonnet();  use Apache::lonnet();
   use Apache::lonhtmlcommon;
 use HTML::TokeParser;  use HTML::TokeParser;
 use GDBM_File;  use GDBM_File;
   
Line 60  use GDBM_File; Line 61  use GDBM_File;
   
 This section contains all the files that get data from other servers   This section contains all the files that get data from other servers 
 and/or itself.  There is one function that has a call to get remote  and/or itself.  There is one function that has a call to get remote
 information but isn't included here which is ProcessTopLevelMap.  The  information but is not included here which is ProcessTopLevelMap.  The
 usage was small enough to be ignored, but that portion may be moved  usage was small enough to be ignored, but that portion may be moved
 here in the future.  here in the future.
   
Line 78  collecting a classlist for the course th Line 79  collecting a classlist for the course th
   
 =over 4  =over 4
   
 Input: $courseID, $c  Input: $courseID, $lastDownloadTime, $c
   
 $courseID:  The id of the course  $courseID:  The id of the course
   
   $lastDownloadTime: I am not sure.
   
 $c: The connection class that can determine if the browser has aborted.  It  $c: The connection class that can determine if the browser has aborted.  It
 is used to short circuit this function so that it doesn't continue to   is used to short circuit this function so that it does not continue to 
 get information when there is no need.  get information when there is no need.
   
 Output: \%classlist  Output: \%classlist
Line 118  sub DownloadClasslist { Line 121  sub DownloadClasslist {
     }      }
   
     %classlist=&Apache::lonnet::dump('classlist',$courseDomain, $courseNumber);      %classlist=&Apache::lonnet::dump('classlist',$courseDomain, $courseNumber);
     my ($checkForError)=keys (%classlist);      foreach(keys (%classlist)) {
     if($checkForError =~ /^(con_lost|error|no_such_host)/i) {          if(/^(con_lost|error|no_such_host)/i) {
         return \%classlist;              return \%classlist;
           }
     }      }
   
     foreach my $name (keys(%classlist)) {      foreach my $name (keys(%classlist)) {
         if($c->aborted()) {          if((defined($c) && ($c->aborted())) {
             $classlist{'error'}='aborted';              $classlist{'error'}='aborted';
             return \%classlist;              return \%classlist;
         }          }
Line 190  sub DownloadCourseInformation { Line 194  sub DownloadCourseInformation {
                                       $courseID.'.db',                                         $courseID.'.db', 
                                       $Apache::lonnet::perlvar{'lonUsersDir'});                                        $Apache::lonnet::perlvar{'lonUsersDir'});
   
     if($lastDownloadTime >= $modifiedTime) {      if($lastDownloadTime >= $modifiedTime && $modifiedTime >= 0) {
         $courseData{'lastDownloadTime'}=time;          $courseData{$namedata.':lastDownloadTime'}=time;
         $courseData{'UpToDate'} = 'true';          $courseData{$namedata.':UpToDate'} = 'true';
         return \%courseData;          return \%courseData;
     }      }
   
Line 203  sub DownloadCourseInformation { Line 207  sub DownloadCourseInformation {
     %courseData=&Apache::lonnet::dump($courseID, $domain, $name, $WhatIWant);      %courseData=&Apache::lonnet::dump($courseID, $domain, $name, $WhatIWant);
     $courseData{'UpToDate'} = 'false';      $courseData{'UpToDate'} = 'false';
     $courseData{'lastDownloadTime'}=time;      $courseData{'lastDownloadTime'}=time;
     return \%courseData;  
       my %newData;
       foreach (keys(%courseData)) {
           $newData{$namedata.':'.$_} = $courseData{$_};
       }
   
       return \%newData;
 }  }
   
 # ----- END DOWNLOAD INFORMATION ---------------------------------------  # ----- END DOWNLOAD INFORMATION ---------------------------------------
Line 281  sub ProcessTopResourceMap { Line 291  sub ProcessTopResourceMap {
     $currentSequence=-1;      $currentSequence=-1;
     my $topLevelSequenceNumber = $currentSequence;      my $topLevelSequenceNumber = $currentSequence;
   
     my $problemCount=0;  
     my $problemCount2=0;  
     my %sequenceRecord;      my %sequenceRecord;
     my $sequenceCount=0;  
     my $sequenceCount2=0;  
     while(1) {      while(1) {
         if($c->aborted()) {          if($c->aborted()) {
             last;              last;
Line 294  sub ProcessTopResourceMap { Line 300  sub ProcessTopResourceMap {
  #if page || sequence   #if page || sequence
  if(defined($hash{'map_pc_'.$hash{'src_'.$currentResourceID}}) &&   if(defined($hash{'map_pc_'.$hash{'src_'.$currentResourceID}}) &&
            !defined($sequenceRecord{$currentResourceID})) {             !defined($sequenceRecord{$currentResourceID})) {
             $sequenceCount++;  
             $sequenceRecord{$currentResourceID}++;              $sequenceRecord{$currentResourceID}++;
     push(@sequences, $currentSequence);      push(@sequences, $currentSequence);
     push(@currentResource, $currentResourceID);      push(@currentResource, $currentResourceID);
Line 332  sub ProcessTopResourceMap { Line 337  sub ProcessTopResourceMap {
  $currentResourceID=~/(\d+)\.(\d+)/;   $currentResourceID=~/(\d+)\.(\d+)/;
         my $partA=$1;          my $partA=$1;
         my $partB=$2;          my $partB=$2;
         if($hash{'src_'.$currentResourceID}=~/\.problem$/) {  
             $problemCount++;  
         }  
  if($hash{'src_'.$currentResourceID}=~   if($hash{'src_'.$currentResourceID}=~
    /\.(problem|exam|quiz|assess|survey|form)$/ &&     /\.(problem|exam|quiz|assess|survey|form)$/ &&
    $partA eq $currentSequence &&      $partA eq $currentSequence && 
            !defined($sequenceRecord{$currentSequence.':'.             !defined($sequenceRecord{$currentSequence.':'.
                                     $currentResourceID})) {                                      $currentResourceID})) {
             $problemCount2++;  
             $sequenceRecord{$currentSequence.':'.$currentResourceID}++;              $sequenceRecord{$currentSequence.':'.$currentResourceID}++;
     my $Problem = &Apache::lonnet::symbclean(      my $Problem = &Apache::lonnet::symbclean(
   &Apache::lonnet::declutter($hash{'map_id_'.$partA}).    &Apache::lonnet::declutter($hash{'map_id_'.$partA}).
Line 398  sub ProcessTopResourceMap { Line 399  sub ProcessTopResourceMap {
                         $beenHere{'o:'.$partId.$currentResourceID}++;                          $beenHere{'o:'.$partId.$currentResourceID}++;
                         if(defined($cache->{'OptionResponses'})) {                          if(defined($cache->{'OptionResponses'})) {
                             $cache->{'OptionResponses'}.= ':::'.                              $cache->{'OptionResponses'}.= ':::'.
                                 $currentResourceID.':'.                                  $currentSequence.':'.$currentResourceID.':'.
                                 $partId.':'.$responseId;                                  $partId.':'.$responseId;
                         } else {                          } else {
                             $cache->{'OptionResponses'}= $currentResourceID.                              $cache->{'OptionResponses'}= $currentSequence.':'.
                                 ':'.$partId.':'.$responseId;                                  $currentResourceID.':'.
                                   $partId.':'.$responseId;
                         }                          }
                     }                      }
                 }                  }
Line 416  sub ProcessTopResourceMap { Line 418  sub ProcessTopResourceMap {
     $lastResourceID=pop(@finishResource);      $lastResourceID=pop(@finishResource);
   
     if(defined($cache->{$currentSequence.':problems'})) {      if(defined($cache->{$currentSequence.':problems'})) {
                 $sequenceCount2++;  
  # Capture sequence information here   # Capture sequence information here
  $cache->{$currentSequence.':title'}=   $cache->{$currentSequence.':title'}=
     $hash{'title_'.$currentResourceID};      $hash{'title_'.$currentResourceID};
Line 481  sub ProcessTopResourceMap { Line 482  sub ProcessTopResourceMap {
  $currentResourceID=pop(@currentResource);   $currentResourceID=pop(@currentResource);
     }      }
   
     $cache->{'jasoncount'}=$problemCount;  
     $cache->{'jasoncount2'}=$problemCount2;  
     $cache->{'jasonseq'}=$sequenceCount;  
     $cache->{'jasonseq2'}=$sequenceCount2;  
     unless (untie(%hash)) {      unless (untie(%hash)) {
         &Apache::lonnet::logthis("<font color=blue>WARNING: ".          &Apache::lonnet::logthis("<font color=blue>WARNING: ".
                                  "Could not untie coursemap $fn (browse)".                                   "Could not untie coursemap $fn (browse)".
Line 552  sub ProcessClasslist { Line 549  sub ProcessClasslist {
         if($c->aborted()) {          if($c->aborted()) {
             return ();              return ();
         }          }
         push(@names,$name);  
         my $studentInformation = $classlist->{$name.':studentInformation'},          my $studentInformation = $classlist->{$name.':studentInformation'},
         my $sectionData = $classlist->{$name.':sections'},          my $sectionData = $classlist->{$name.':sections'},
         my $date = $classlist->{$name},          my $date = $classlist->{$name},
Line 566  sub ProcessClasslist { Line 562  sub ProcessClasslist {
             $cache->{$name.':updateTime'}=' Not updated';              $cache->{$name.':updateTime'}=' Not updated';
         }          }
   
         my ($checkForError)=keys(%$studentInformation);          my $error = 0;
         if($checkForError =~ /^(con_lost|error|no_such_host)/i) {          foreach(keys(%$studentInformation)) {
             $cache->{$name.':error'}=              if(/^(con_lost|error|no_such_host)/i) {
                 'Could not download student environment data.';                  $cache->{$name.':error'}=
             $cache->{$name.':fullname'}='';                      'Could not download student environment data.';
             $cache->{$name.':id'}='';                  $cache->{$name.':fullname'}='';
         } else {                  $cache->{$name.':id'}='';
             $cache->{$name.':fullname'}=&ProcessFullName(                  $error = 1;
               }
           }
           next if($error);
           push(@names,$name);
           $cache->{$name.':fullname'}=&ProcessFullName(
                                           $studentInformation->{'lastname'},                                            $studentInformation->{'lastname'},
                                           $studentInformation->{'generation'},                                            $studentInformation->{'generation'},
                                           $studentInformation->{'firstname'},                                            $studentInformation->{'firstname'},
                                           $studentInformation->{'middlename'});                                            $studentInformation->{'middlename'});
             $cache->{$name.':id'}=$studentInformation->{'id'};          $cache->{$name.':id'}=$studentInformation->{'id'};
         }  
   
         my ($end, $start)=split(':',$date);          my ($end, $start)=split(':',$date);
         $courseID=~s/\_/\//g;          $courseID=~s/\_/\//g;
Line 662  will only exist if an error occured.  Th Line 662  will only exist if an error occured.  Th
 sub ProcessStudentData {  sub ProcessStudentData {
     my ($cache,$courseData,$name)=@_;      my ($cache,$courseData,$name)=@_;
   
     if($courseData->{'UpToDate'} eq 'true') {      if(!&CheckDateStampError($courseData, $cache, $name)) {
         $cache->{$name.':lastDownloadTime'}=$courseData->{'lastDownloadTime'};  
         if($courseData->{'lastDownloadTime'} eq 'Not downloaded') {  
             $cache->{$name.':updateTime'} = ' Not updated';  
         } else {  
             $cache->{$name.':updateTime'}=  
                 localtime($courseData->{'lastDownloadTime'});  
         }  
         return;          return;
     }      }
   
     my @courseKeys = keys(%$courseData);      foreach (keys %$courseData) {
           $cache->{$_}=$courseData->{$_};
     foreach (@courseKeys) {  
         if(/^(con_lost|error|no_such_host)/i) {  
             $cache->{$name.':error'}='Could not download course data.';  
             return;  
         }  
     }      }
   
     $cache->{$name.':lastDownloadTime'}=$courseData->{'lastDownloadTime'};      return;
     if($courseData->{'lastDownloadTime'} eq 'Not downloaded') {  }
         $cache->{$name.':updateTime'} = ' Not updated';  
     } else {  sub ExtractStudentData {
         $cache->{$name.':updateTime'}=      my ($input, $output, $data, $name)=@_;
             localtime($courseData->{'lastDownloadTime'});  
       if(!&CheckDateStampError($input, $data, $name)) {
           return;
     }      }
     foreach (@courseKeys) {  
         $cache->{$name.':'.$_}=$courseData->{$_};      my ($username,$domain)=split(':',$name);
   
       my $Version;
       my $problemsCorrect = 0;
       my $totalProblems   = 0;
       my $problemsSolved  = 0;
       my $numberOfParts   = 0;
       my $totalAwarded    = 0;
       foreach my $sequence (split(':', $data->{'orderedSequences'})) {
           foreach my $problemID (split(':', $data->{$sequence.':problems'})) {
               my $problem = $data->{$problemID.':problem'};
               my $LatestVersion = $input->{$name.':version:'.$problem};
   
               # Output dashes for all the parts of this problem if there
               # is no version information about the current problem.
               if(!$LatestVersion) {
                   foreach my $part (split(/\:/,$data->{$sequence.':'.
                                                         $problemID.
                                                         ':parts'})) {
                       $output->{$name.':'.$problemID.':'.$part.':tries'} = 0;
                       $output->{$name.':'.$problemID.':'.$part.':awarded'} = 0;
                       $output->{$name.':'.$problemID.':'.$part.':code'} = ' ';
                       $totalProblems++;
                   }
                   $output->{$name.':'.$problemID.':NoVersion'} = 'true';
                   next;
               }
   
               my %partData=undef;
               # Initialize part data, display skips correctly
               # Skip refers to when a student made no submissions on that
               # part/problem.
               foreach my $part (split(/\:/,$data->{$sequence.':'.
                                                    $problemID.
                                                    ':parts'})) {
                   $partData{$part.':tries'}=0;
                   $partData{$part.':code'}=' ';
                   $partData{$part.':awarded'}=0;
                   $partData{$part.':timestamp'}=0;
                   foreach my $response (split(':', $data->{$sequence.':'.
                                                            $problemID.':'.
                                                            $part.':responseIDs'})) {
                       $partData{$part.':'.$response.':submission'}='';
                   }
               }
   
               # Looping through all the versions of each part, starting with the
               # oldest version.  Basically, it gets the most recent 
               # set of grade data for each part.
               my @submissions = ();
       for(my $Version=1; $Version<=$LatestVersion; $Version++) {
                   foreach my $part (split(/\:/,$data->{$sequence.':'.
                                                        $problemID.
                                                        ':parts'})) {
   
                       if(!defined($input->{"$name:$Version:$problem".
                                            ":resource.$part.solved"})) {
                           # No grade for this submission, so skip
                           next;
                       }
   
                       my $tries=0;
                       my $code=' ';
                       my $awarded=0;
   
                       $tries = $input->{$name.':'.$Version.':'.$problem.
                                         ':resource.'.$part.'.tries'};
                       $awarded = $input->{$name.':'.$Version.':'.$problem.
                                           ':resource.'.$part.'.awarded'};
   
                       $partData{$part.':awarded'}=($awarded) ? $awarded : 0;
                       $partData{$part.':tries'}=($tries) ? $tries : 0;
   
                       $partData{$part.':timestamp'}=$input->{$name.':'.$Version.':'.
                                                              $problem.
                                                              ':timestamp'};
                       if(!$input->{$name.':'.$Version.':'.$problem.':resource.'.$part.
                                    '.previous'}) {
                           foreach my $response (split(':',
                                                      $data->{$sequence.':'.
                                                              $problemID.':'.
                                                              $part.':responseIDs'})) {
                               @submissions=($input->{$name.':'.$Version.':'.
                                                      $problem.
                                                      ':resource.'.$part.'.'.
                                                      $response.'.submission'},
                                             @submissions);
                           }
                       }
   
                       my $val = $input->{$name.':'.$Version.':'.$problem.
                                          ':resource.'.$part.'.solved'};
                       if    ($val eq 'correct_by_student')   {$code = '*';} 
                       elsif ($val eq 'correct_by_override')  {$code = '+';}
                       elsif ($val eq 'incorrect_attempted')  {$code = '.';} 
                       elsif ($val eq 'incorrect_by_override'){$code = '-';}
                       elsif ($val eq 'excused')              {$code = 'x';}
                       elsif ($val eq 'ungraded_attempted')   {$code = '#';}
                       else                                   {$code = ' ';}
                       $partData{$part.':code'}=$code;
                   }
               }
   
               foreach my $part (split(/\:/,$data->{$sequence.':'.$problemID.
                                                    ':parts'})) {
                   $output->{$name.':'.$problemID.':'.$part.':wrong'} = 
                       $partData{$part.':tries'};
   
                   if($partData{$part.':code'} eq '*') {
                       $output->{$name.':'.$problemID.':'.$part.':wrong'}--;
                       $problemsCorrect++;
                   } elsif($partData{$part.':code'} eq '+') {
                       $output->{$name.':'.$problemID.':'.$part.':wrong'}--;
                       $problemsCorrect++;
                   }
   
                   $output->{$name.':'.$problemID.':'.$part.':tries'} = 
                       $partData{$part.':tries'};
                   $output->{$name.':'.$problemID.':'.$part.':code'} =
                       $partData{$part.':code'};
                   $output->{$name.':'.$problemID.':'.$part.':awarded'} =
                       $partData{$part.':awarded'};
                   $totalAwarded += $partData{$part.':awarded'};
                   $output->{$name.':'.$problemID.':'.$part.':timestamp'} =
                       $partData{$part.':timestamp'};
                   foreach my $response (split(':', $data->{$sequence.':'.
                                                            $problemID.':'.
                                                            $part.':responseIDs'})) {
                       $output->{$name.':'.$problemID.':'.$part.':'.$response.
                                 ':submission'}=join(':::',@submissions);
                   }
   
                   if($partData{$part.':code'} ne 'x') {
                       $totalProblems++;
                   }
               }
           }
   
           $output->{$name.':'.$sequence.':problemsCorrect'} = $problemsCorrect;
           $problemsSolved += $problemsCorrect;
    $problemsCorrect=0;
     }      }
   
       $output->{$name.':problemsSolved'} = $problemsSolved;
       $output->{$name.':totalProblems'} = $totalProblems;
       $output->{$name.':totalAwarded'} = $totalAwarded;
   
     return;      return;
 }  }
   
 sub LoadDiscussion {  sub LoadDiscussion {
     my ( $courseID)=@_;      my ($courseID)=@_;
     my %Discuss=();      my %Discuss=();
     my %contrib=&Apache::lonnet::dump(      my %contrib=&Apache::lonnet::dump(
                 $courseID,                  $courseID,
Line 733  jobs. Line 867  jobs.
   
 # ----- HELPER FUNCTIONS -----------------------------------------------  # ----- HELPER FUNCTIONS -----------------------------------------------
   
   sub CheckDateStampError {
       my ($courseData, $cache, $name)=@_;
       if($courseData->{$name.':UpToDate'} eq 'true') {
           $cache->{$name.':lastDownloadTime'} = 
               $courseData->{$name.':lastDownloadTime'};
           if($courseData->{$name.':lastDownloadTime'} eq 'Not downloaded') {
               $cache->{$name.':updateTime'} = ' Not updated';
           } else {
               $cache->{$name.':updateTime'}=
                   localtime($courseData->{$name.':lastDownloadTime'});
           }
           return 0;
       }
   
       $cache->{$name.':lastDownloadTime'}=$courseData->{$name.':lastDownloadTime'};
       if($courseData->{$name.':lastDownloadTime'} eq 'Not downloaded') {
           $cache->{$name.':updateTime'} = ' Not updated';
       } else {
           $cache->{$name.':updateTime'}=
               localtime($courseData->{$name.':lastDownloadTime'});
       }
   
       if(defined($courseData->{$name.':error'})) {
           $cache->{$name.':error'}=$courseData->{$name.':error'};
           return 0;
       }
   
       return 1;
   }
   
 =pod  =pod
   
 =item &ProcessFullName()  =item &ProcessFullName()
Line 847  sub TestCacheData { Line 1011  sub TestCacheData {
     return $isCached;      return $isCached;
 }  }
   
   sub DownloadStudentCourseData {
       my ($students,$checkDate,$cacheDB,$extract,$status,$courseID,$r,$c)=@_;
   
       my $title = 'LON-CAPA Statistics';
       my $heading = 'Download and Process Course Data';
       my $studentCount = scalar(@$students);
       my %cache;
   
   
       my $WhatIWant;
       $WhatIWant = '(^version:|';
       $WhatIWant .= '^\d+:.+?:(resource\.\d+\.';
       $WhatIWant .= '(solved|tries|previous|awarded|(\d+\.submission))\s*$';
       $WhatIWant .= '|timestamp)';
       $WhatIWant .= ')';
   #    $WhatIWant = '.';
   
       if($status eq 'true') {
           &Apache::lonhtmlcommon::Create_PrgWin($r, $title, $heading);
       }
   
       my $displayString;
       my $count=0;
       foreach (@$students) {
           if($c->aborted()) { return 'Aborted'; }
   
           if($status eq 'true') {
               $count++;
               my $displayString = $count.'/'.$studentCount.': '.$_;
               &Apache::lonhtmlcommon::Update_PrgWin($displayString, $r);
           }
   
           my $downloadTime='Not downloaded';
           if($checkDate eq 'true'  && 
              tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
               $downloadTime = $cache{$_.':lastDownloadTime'};
               untie(%cache);
           }
   
           if($c->aborted()) { return 'Aborted'; }
   
           if($downloadTime eq 'Not downloaded') {
               my $courseData = 
                   &DownloadCourseInformation($_, $courseID, $downloadTime, 
                                              $WhatIWant);
               if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_WRCREAT(),0640)) {
                   foreach my $key (keys(%$courseData)) {
                       if($key =~ /^(con_lost|error|no_such_host)/i) {
                           $courseData->{$_.':error'} = 'No course data for '.$_;
                           last;
                       }
                   }
                   if($extract eq 'true') {
                       &ExtractStudentData($courseData, \%cache, \%cache, $_);
                   } else {
                       &ProcessStudentData(\%cache, $courseData, $_);
                   }
                   untie(%cache);
               } else {
                   next;
               }
           }
       }
       if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r); }
   
       return 'OK';
   }
   
   sub DownloadStudentCourseDataSeparate {
       my ($students,$checkDate,$cacheDB,$extract,$status,$courseID,$r,$c)=@_;
       my $residualFile = '/home/httpd/perl/tmp/'.$courseID.'DownloadFile.db';
       my $title = 'LON-CAPA Statistics';
       my $heading = 'Download Course Data';
   
       my $WhatIWant;
       $WhatIWant = '(^version:|';
       $WhatIWant .= '^\d+:.+?:(resource\.\d+\.';
       $WhatIWant .= '(solved|tries|previous|awarded|(\d+\.submission))\s*$';
       $WhatIWant .= '|timestamp)';
       $WhatIWant .= ')';
   
       &CheckForResidualDownload($courseID, $cacheDB, $students, $c);
   
       my %cache;
   
       my $studentCount = scalar(@$students);
       if($status eq 'true') {
           &Apache::lonhtmlcommon::Create_PrgWin($r, $title, $heading);
       }
       my $count=0;
       my $displayString='';
       foreach (@$students) {
           if($c->aborted()) {
               return 'Aborted';
           }
   
           if($status eq 'true') {
               $count++;
               $displayString = $count.'/'.$studentCount.': '.$_;
               &Apache::lonhtmlcommon::Update_PrgWin($displayString, $r);
           }
   
           my $downloadTime='Not downloaded';
           if($checkDate eq 'true'  && 
              tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
               $downloadTime = $cache{$_.':lastDownloadTime'};
               untie(%cache);
           }
   
           if($c->aborted()) {
               return 'Aborted';
           }
   
           if($downloadTime eq 'Not downloaded') {
               my $error = 0;
               my $courseData = 
                   &DownloadCourseInformation($_, $courseID, $downloadTime,
                                              $WhatIWant);
               my %downloadData;
               unless(tie(%downloadData,'GDBM_File',$residualFile,
                          &GDBM_WRCREAT(),0640)) {
                   return 'Failed to tie temporary download hash.';
               }
               foreach my $key (keys(%$courseData)) {
                   $downloadData{$key} = $courseData->{$key};
                   if($key =~ /^(con_lost|error|no_such_host)/i) {
                       $error = 1;
                       last;
                   }
               }
               if($error) {
                   foreach my $deleteKey (keys(%$courseData)) {
                       delete $downloadData{$deleteKey};
                   }
                   $downloadData{$_.':error'} = 'No course data for '.$_;
               }
               untie(%downloadData);
           }
       }
       if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r); }
   
       return &CheckForResidualDownload($cacheDB, 'true', 'true', 
                                        $courseID, $r, $c);
   }
   
   sub CheckForResidualDownload {
       my ($cacheDB,$extract,$status,$courseID,$r,$c)=@_;
   
       my $residualFile = '/home/httpd/perl/tmp/'.$courseID.'DownloadFile.db';
       if(!-e $residualFile) {
           return 'OK';
       }
   
       my %downloadData;
       my %cache;
       unless(tie(%downloadData,'GDBM_File',$residualFile,&GDBM_READER(),0640)) {
           return 'Can not tie database for check for residual download: tempDB';
       }
       unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_WRCREAT(),0640)) {
           untie(%downloadData);
           return 'Can not tie database for check for residual download: cacheDB';
       }
   
       my @students=();
       my %checkStudent;
       my $key;
       while(($key, undef) = each %downloadData) {
           my @temp = split(':', $key);
           my $student = $temp[0].':'.$temp[1];
           if(!defined($checkStudent{$student})) {
               $checkStudent{$student}++;
               push(@students, $student);
           }
       }
   
       my $heading = 'Process Course Data';
       my $title = 'LON-CAPA Statistics';
       my $studentCount = scalar(@students);
       if($status eq 'true') {
           &Apache::lonhtmlcommon::Create_PrgWin($r, $title, $heading);
       }
   
       my $count=1;
       foreach my $name (@students) {
           last if($c->aborted());
   
           if($status eq 'true') {
               my $displayString = $count.'/'.$studentCount.': '.$name;
               &Apache::lonhtmlcommon::Update_PrgWin($displayString, $r);
           }
   
           if($extract eq 'true') {
               &ExtractStudentData(\%downloadData, \%cache, \%cache, $name);
           } else {
               &ProcessStudentData(\%cache, \%downloadData, $name);
           }
           $count++;
       }
   
       if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r); }
   
       untie(%cache);
       untie(%downloadData);
   
       if(!$c->aborted()) {
           my @files = ($residualFile);
           unlink(@files);
       }
   
       return 'OK';
   }
   
 sub GetFileTimestamp {  sub GetFileTimestamp {
     my ($studentDomain,$studentName,$filename,$root)=@_;      my ($studentDomain,$studentName,$filename,$root)=@_;
     $studentDomain=~s/\W//g;      $studentDomain=~s/\W//g;
Line 859  sub GetFileTimestamp { Line 1235  sub GetFileTimestamp {
                                        $root);                                         $root);
     my $fileStat = $dir[0];      my $fileStat = $dir[0];
     my @stats = split('&', $fileStat);      my @stats = split('&', $fileStat);
     if(@stats) {      if($stats[0] ne 'empty' && $stats[0] ne 'no_such_dir') {
         return $stats[9];          return $stats[9];
     } else {      } else {
         return -1;          return -1;

Removed from v.1.12  
changed lines
  Added in v.1.21


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