version 1.45, 2003/02/13 14:49:16
|
version 1.51, 2003/02/25 16:05:24
|
Line 120 sub DownloadClasslist {
|
Line 120 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 261 with stopping downloading then can not t
|
Line 262 with stopping downloading then can not t
|
|
|
# ----- PROCESSING FUNCTIONS --------------------------------------- |
# ----- PROCESSING FUNCTIONS --------------------------------------- |
|
|
|
#################################################### |
|
#################################################### |
|
|
=pod |
=pod |
|
|
Line 278 The returned structure is a hash referen
|
Line 280 The returned structure is a hash referen
|
symb => 'symb', |
symb => 'symb', |
source => '/s/o/u/r/c/e', |
source => '/s/o/u/r/c/e', |
type => (container|assessment), |
type => (container|assessment), |
|
num_assess => 2, # only for container |
contents => [ {},{},{},{} ], # only for container |
contents => [ {},{},{},{} ], # only for container |
parts => [11,13,15], # only for assessment |
parts => [11,13,15], # only for assessment |
response_ids => [12,14,16] # 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. |
$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 |
=cut |
|
|
|
#################################################### |
|
#################################################### |
sub get_sequence_assessment_data { |
sub get_sequence_assessment_data { |
return undef; |
|
my $fn=$ENV{'request.course.fn'}; |
my $fn=$ENV{'request.course.fn'}; |
&Apache::lonnet::logthis('filename = '.$fn); |
|
## |
## |
## use navmaps |
## 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)) { |
if (!defined($navmap)) { |
return 'Can not open Coursemap'; |
return 'Can not open Coursemap'; |
} |
} |
Line 311 sub get_sequence_assessment_data {
|
Line 320 sub get_sequence_assessment_data {
|
my $symb = $curRes->symb(); |
my $symb = $curRes->symb(); |
my $src = $curRes->src(); |
my $src = $curRes->src(); |
# |
# |
|
my @Sequences; |
|
my @Assessments; |
my @Nested_Sequences = (); # Stack of sequences, keeps track of depth |
my @Nested_Sequences = (); # Stack of sequences, keeps track of depth |
my $top = { title => $title, |
my $top = { title => $title, |
symb => $symb, |
symb => $symb, |
type => 'container', |
type => 'container', |
num_assess => 0, |
num_assess => 0, |
contents => [], }; |
contents => [], }; |
|
push (@Sequences,$top); |
push (@Nested_Sequences, $top); |
push (@Nested_Sequences, $top); |
# |
# |
# We need to keep track of which sequences contain homework problems |
# We need to keep track of which sequences contain homework problems |
# |
# |
|
my $previous = $top; |
while (scalar(@Nested_Sequences)) { |
while (scalar(@Nested_Sequences)) { |
|
$previous = $curRes; |
$curRes = $iterator->next(); |
$curRes = $iterator->next(); |
my $currentmap = $Nested_Sequences[-1]; # Last one on the stack |
my $currentmap = $Nested_Sequences[-1]; # Last one on the stack |
if ($curRes == $iterator->BEGIN_MAP()) { |
if ($curRes == $iterator->BEGIN_MAP()) { |
# get the map itself, instead of BEGIN_MAP |
# get the map itself, instead of BEGIN_MAP |
$curRes = $iterator->next(); |
$title = $previous->title(); |
$title = $curRes->title(); |
$symb = $previous->symb(); |
$symb = $curRes->symb(); |
$src = $previous->src(); |
$src = $curRes->src(); |
|
my $newmap = { title => $title, |
my $newmap = { title => $title, |
src => $src, |
src => $src, |
symb => $symb, |
symb => $symb, |
Line 338 sub get_sequence_assessment_data {
|
Line 351 sub get_sequence_assessment_data {
|
contents => [], |
contents => [], |
}; |
}; |
push (@{$currentmap->{'contents'}},$newmap); # this is permanent |
push (@{$currentmap->{'contents'}},$newmap); # this is permanent |
|
push (@Sequences,$newmap); |
push (@Nested_Sequences, $newmap); # this is a stack |
push (@Nested_Sequences, $newmap); # this is a stack |
next; |
next; |
} |
} |
Line 346 sub get_sequence_assessment_data {
|
Line 360 sub get_sequence_assessment_data {
|
next; |
next; |
} |
} |
next if (! ref($curRes)); |
next if (! ref($curRes)); |
next if (! $curRes->is_problem() && !$curRes->randomout); |
next if (! $curRes->is_problem());# && !$curRes->randomout); |
# Okay, from here on out we only deal with assessments |
# Okay, from here on out we only deal with assessments |
$title = $curRes->title(); |
$title = $curRes->title(); |
$symb = $curRes->symb(); |
$symb = $curRes->symb(); |
Line 357 sub get_sequence_assessment_data {
|
Line 371 sub get_sequence_assessment_data {
|
symb => $symb, |
symb => $symb, |
type => 'assessment', |
type => 'assessment', |
}; |
}; |
|
push(@Assessments,$assessment); |
push(@{$currentmap->{'contents'}},$assessment); |
push(@{$currentmap->{'contents'}},$assessment); |
$currentmap->{'num_assess'}++; |
$currentmap->{'num_assess'}++; |
} |
} |
return $top; |
return ($top,\@Sequences,\@Assessments); |
} |
} |
|
|
|
################################################# |
|
################################################# |
|
|
=pod |
=pod |
|
|
=item &ProcessTopResourceMap() |
=item &ProcessTopResourceMap() |
Line 1346 sub DownloadStudentCourseData {
|
Line 1364 sub DownloadStudentCourseData {
|
|
|
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'; |
|
|
Line 1427 sub DownloadStudentCourseDataSeparate {
|
Line 1445 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 1491 sub CheckForResidualDownload {
|
Line 1509 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 (); |
|
} |
|
} |
|
|
################################################ |
################################################ |
################################################ |
################################################ |
|
|