--- loncom/interface/loncoursedata.pm 2002/08/28 22:02:47 1.23 +++ loncom/interface/loncoursedata.pm 2002/09/03 12:27:05 1.30 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # (Publication Handler # -# $Id: loncoursedata.pm,v 1.23 2002/08/28 22:02:47 stredwic Exp $ +# $Id: loncoursedata.pm,v 1.30 2002/09/03 12:27:05 stredwic Exp $ # # Copyright Michigan State University Board of Trustees # @@ -309,6 +309,15 @@ sub ProcessTopResourceMap { return 'Can not open Coursemap.'; } + my $oldkeys; + if(defined($cache->{'ResourceKeys'})) { + $oldkeys = $cache->{'ResourceKeys'}; + foreach (split(':::', $cache->{'ResourceKeys'})) { + delete $cache->{$_}; + } + delete $cache->{'ResourceKeys'}; + } + # Initialize state machine. Set information pointing to top level map. my (@sequences, @currentResource, @finishResource); my ($currentSequence, $currentResourceID, $lastResourceID); @@ -320,6 +329,7 @@ sub ProcessTopResourceMap { my $topLevelSequenceNumber = $currentSequence; my %sequenceRecord; + my %allkeys; while(1) { if($c->aborted()) { last; @@ -344,6 +354,7 @@ sub ProcessTopResourceMap { } else { $cache->{'orderedSequences'}.=':'.$currentSequence; } + $allkeys{'orderedSequences'}++; $lastResourceID=$hash{'map_finish_'. $hash{'src_'.$currentResourceID}}; @@ -378,20 +389,24 @@ sub ProcessTopResourceMap { $currentResourceID})); $cache->{$currentResourceID.':problem'}=$Problem; + $allkeys{$currentResourceID.':problem'}++; if(!defined($cache->{$currentSequence.':problems'})) { $cache->{$currentSequence.':problems'}=$currentResourceID; } else { $cache->{$currentSequence.':problems'}.= ':'.$currentResourceID; } + $allkeys{$currentSequence.':problems'}++; my $meta=$hash{'src_'.$currentResourceID}; # $cache->{$currentResourceID.':title'}= # &Apache::lonnet::metdata($meta,'title'); $cache->{$currentResourceID.':title'}= $hash{'title_'.$currentResourceID}; + $allkeys{$currentResourceID.':title'}++; $cache->{$currentResourceID.':source'}= $hash{'src_'.$currentResourceID}; + $allkeys{$currentResourceID.':source'}++; # Get Parts for problem my %beenHere; @@ -408,6 +423,8 @@ sub ProcessTopResourceMap { $cache->{$currentSequence.':'.$currentResourceID. ':parts'}.=':'.$partId; } + $allkeys{$currentSequence.':'.$currentResourceID. + ':parts'}++; } if($beenHere{'r:'.$partId.':'.$responseId} == 0) { $beenHere{'r:'.$partId.':'.$responseId}++; @@ -421,6 +438,8 @@ sub ProcessTopResourceMap { ':'.$partId.':responseIDs'}.=':'. $responseId; } + $allkeys{$currentSequence.':'.$currentResourceID.':'. + $partId.':responseIDs'}++; } if(/^optionresponse/ && $beenHere{'o:'.$partId.':'.$currentResourceID} == 0) { @@ -434,6 +453,7 @@ sub ProcessTopResourceMap { $currentResourceID.':'. $partId.':'.$responseId; } + $allkeys{'OptionResponses'}++; } } } @@ -449,8 +469,10 @@ sub ProcessTopResourceMap { # Capture sequence information here $cache->{$currentSequence.':title'}= $hash{'title_'.$currentResourceID}; + $allkeys{$currentSequence.':title'}++; $cache->{$currentSequence.':source'}= $hash{'src_'.$currentResourceID}; + $allkeys{$currentSequence.':source'}++; my $totalProblems=0; foreach my $currentProblem (split(/\:/, @@ -474,6 +496,7 @@ sub ProcessTopResourceMap { $cache->{$currentSequence.':columnWidth'}= (scalar @titleLength); } + $allkeys{$currentSequence.':columnWidth'}++; } else { # Remove sequence from list, if it contains no problems to # display. @@ -510,6 +533,15 @@ sub ProcessTopResourceMap { $currentResourceID=pop(@currentResource); } + my @theKeys = keys(%allkeys); + my $newkeys = join(':::', @theKeys); + $cache->{'ResourceKeys'} = join(':::', $newkeys); + if($newkeys ne $oldkeys) { + $cache->{'ResourceUpdated'} = 'true'; + } else { + $cache->{'ResourceUpdated'} = 'false'; + } + unless (untie(%hash)) { &Apache::lonnet::logthis("WARNING: ". "Could not untie coursemap $fn (browse)". @@ -693,11 +725,26 @@ sub ProcessStudentData { return; } + # This little delete thing, should not be here. Move some other + # time though. + if(defined($cache->{$name.':keys'})) { + foreach (split(':::', $cache->{$name.':keys'})) { + delete $cache->{$name.':'.$_}; + } + delete $cache->{$name.':keys'}; + } + + my %courseKeys; # user name:domain was prepended earlier in DownloadCourseInformation foreach (keys %$courseData) { + my $currentKey = $_; + $currentKey =~ s/^$name//; + $courseKeys{$currentKey}++; $cache->{$_}=$courseData->{$_}; } + $cache->{$name.':keys'} = join(':::', keys(%courseKeys)); + return; } @@ -753,6 +800,16 @@ sub ExtractStudentData { return; } + # This little delete thing, should not be here. Move some other + # time though. + my %allkeys; + if(defined($output->{$name.':keys'})) { + foreach (split(':::', $output->{$name.':keys'})) { + delete $output->{$name.':'.$_}; + } + delete $output->{$name.':keys'}; + } + my ($username,$domain)=split(':',$name); my $Version; @@ -768,6 +825,8 @@ sub ExtractStudentData { # Output dashes for all the parts of this problem if there # is no version information about the current problem. + $output->{$name.':'.$problemID.':NoVersion'} = 'false'; + $allkeys{$name.':'.$problemID.':NoVersion'}++; if(!$LatestVersion) { foreach my $part (split(/\:/,$data->{$sequence.':'. $problemID. @@ -775,6 +834,9 @@ sub ExtractStudentData { $output->{$name.':'.$problemID.':'.$part.':tries'} = 0; $output->{$name.':'.$problemID.':'.$part.':awarded'} = 0; $output->{$name.':'.$problemID.':'.$part.':code'} = ' '; + $allkeys{$name.':'.$problemID.':'.$part.':tries'}++; + $allkeys{$name.':'.$problemID.':'.$part.':awarded'}++; + $allkeys{$name.':'.$problemID.':'.$part.':code'}++; $totalProblems++; } $output->{$name.':'.$problemID.':NoVersion'} = 'true'; @@ -860,6 +922,7 @@ sub ExtractStudentData { ':parts'})) { $output->{$name.':'.$problemID.':'.$part.':wrong'} = $partData{$part.':tries'}; + $allkeys{$name.':'.$problemID.':'.$part.':wrong'}++; if($partData{$part.':code'} eq '*') { $output->{$name.':'.$problemID.':'.$part.':wrong'}--; @@ -875,14 +938,22 @@ sub ExtractStudentData { $partData{$part.':code'}; $output->{$name.':'.$problemID.':'.$part.':awarded'} = $partData{$part.':awarded'}; + $allkeys{$name.':'.$problemID.':'.$part.':tries'}++; + $allkeys{$name.':'.$problemID.':'.$part.':code'}++; + $allkeys{$name.':'.$problemID.':'.$part.':awarded'}++; + $totalAwarded += $partData{$part.':awarded'}; $output->{$name.':'.$problemID.':'.$part.':timestamp'} = $partData{$part.':timestamp'}; + $allkeys{$name.':'.$problemID.':'.$part.':timestamp'}++; + foreach my $response (split(':', $data->{$sequence.':'. $problemID.':'. $part.':responseIDs'})) { $output->{$name.':'.$problemID.':'.$part.':'.$response. ':submission'}=join(':::',@submissions); + $allkeys{$name.':'.$problemID.':'.$part.':'.$response. + ':submission'}++; } if($partData{$part.':code'} ne 'x') { @@ -892,6 +963,7 @@ sub ExtractStudentData { } $output->{$name.':'.$sequence.':problemsCorrect'} = $problemsCorrect; + $allkeys{$name.':'.$sequence.':problemsCorrect'}++; $problemsSolved += $problemsCorrect; $problemsCorrect=0; } @@ -899,6 +971,11 @@ sub ExtractStudentData { $output->{$name.':problemsSolved'} = $problemsSolved; $output->{$name.':totalProblems'} = $totalProblems; $output->{$name.':totalAwarded'} = $totalAwarded; + $allkeys{$name.':problemsSolved'}++; + $allkeys{$name.':totalProblems'}++; + $allkeys{$name.':totalAwarded'}++; + + $output->{$name.':keys'} = join(':::', keys(%allkeys)); return; } @@ -1095,8 +1172,6 @@ sub DownloadStudentCourseData { my $title = 'LON-CAPA Statistics'; my $heading = 'Download and Process Course Data'; my $studentCount = scalar(@$students); - my %cache; - my $WhatIWant; $WhatIWant = '(^version:|'; @@ -1113,6 +1188,8 @@ sub DownloadStudentCourseData { my $displayString; my $count=0; foreach (@$students) { + my %cache; + if($c->aborted()) { return 'Aborted'; } if($status eq 'true') { @@ -1122,35 +1199,38 @@ sub DownloadStudentCourseData { } my $downloadTime='Not downloaded'; + my $needUpdate = 'false'; if($checkDate eq 'true' && tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) { $downloadTime = $cache{$_.':lastDownloadTime'}; + $needUpdate = $cache{'ResourceUpdated'}; 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($needUpdate eq 'true') { + $downloadTime = '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); } @@ -1170,9 +1250,7 @@ sub DownloadStudentCourseDataSeparate { $WhatIWant .= '|timestamp)'; $WhatIWant .= ')'; - &CheckForResidualDownload($courseID, $cacheDB, $students, $c); - - my %cache; + &CheckForResidualDownload($cacheDB, 'true', 'true', $courseID, $r, $c); my $studentCount = scalar(@$students); if($status eq 'true') { @@ -1191,10 +1269,13 @@ sub DownloadStudentCourseDataSeparate { &Apache::lonhtmlcommon::Update_PrgWin($displayString, $r); } + my %cache; my $downloadTime='Not downloaded'; + my $needUpdate = 'false'; if($checkDate eq 'true' && tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) { $downloadTime = $cache{$_.':lastDownloadTime'}; + $needUpdate = $cache{'ResourceUpdated'}; untie(%cache); } @@ -1202,31 +1283,33 @@ sub DownloadStudentCourseDataSeparate { 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($needUpdate eq 'true') { + $downloadTime = '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 '.$_; + } + if($error) { + foreach my $deleteKey (keys(%$courseData)) { + delete $downloadData{$deleteKey}; } - untie(%downloadData); + $downloadData{$_.':error'} = 'No course data for '.$_; } + untie(%downloadData); } if($status eq 'true') { &Apache::lonhtmlcommon::Close_PrgWin($r); }