--- loncom/interface/loncoursedata.pm 2003/02/13 14:49:16 1.45 +++ loncom/interface/loncoursedata.pm 2003/02/20 14:28:25 1.49 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # (Publication Handler # -# $Id: loncoursedata.pm,v 1.45 2003/02/13 14:49:16 matthew Exp $ +# $Id: loncoursedata.pm,v 1.49 2003/02/20 14:28:25 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -283,6 +283,9 @@ The returned structure is a hash referen response_ids => [12,14,16] # only for assessment } +Also returned are array references to the symbs and assessments contained +in the sequence. + $hash->{'contents'} is a reference to an array of hashes of the same structure. =cut @@ -293,7 +296,8 @@ sub get_sequence_assessment_data { &Apache::lonnet::logthis('filename = '.$fn); ## ## use navmaps - my $navmap = Apache::lonnavmaps::navmap->new($fn.".bd",$fn."_parms.db",1,0); + my $navmap = Apache::lonnavmaps::navmap->new($fn.".db",$fn."_parms.db", + 1,0); if (!defined($navmap)) { return 'Can not open Coursemap'; } @@ -311,12 +315,15 @@ sub get_sequence_assessment_data { my $symb = $curRes->symb(); my $src = $curRes->src(); # + my @Sequences; + my @Assessments; my @Nested_Sequences = (); # Stack of sequences, keeps track of depth my $top = { title => $title, symb => $symb, type => 'container', num_assess => 0, contents => [], }; + push (@Sequences,$top); push (@Nested_Sequences, $top); # # We need to keep track of which sequences contain homework problems @@ -338,6 +345,7 @@ sub get_sequence_assessment_data { contents => [], }; push (@{$currentmap->{'contents'}},$newmap); # this is permanent + push (@Sequences,$newmap); push (@Nested_Sequences, $newmap); # this is a stack next; } @@ -357,10 +365,11 @@ sub get_sequence_assessment_data { symb => $symb, type => 'assessment', }; + push(@Assessments,$assessment); push(@{$currentmap->{'contents'}},$assessment); $currentmap->{'num_assess'}++; } - return $top; + return ($top,\@Sequences,\@Assessments); } =pod @@ -1346,7 +1355,7 @@ sub DownloadStudentCourseData { sub DownloadStudentCourseDataSeparate { 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 $heading = 'Download Course Data'; @@ -1427,7 +1436,7 @@ sub DownloadStudentCourseDataSeparate { sub CheckForResidualDownload { 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) { return 'OK'; } @@ -1491,6 +1500,164 @@ sub CheckForResidualDownload { 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 (); + } +} + ################################################ ################################################ 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.