--- loncom/interface/loncoursedata.pm 2002/07/09 15:43:49 1.1
+++ loncom/interface/loncoursedata.pm 2002/07/24 14:52:32 1.4
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# (Publication Handler
#
-# $Id: loncoursedata.pm,v 1.1 2002/07/09 15:43:49 stredwic Exp $
+# $Id: loncoursedata.pm,v 1.4 2002/07/24 14:52:32 stredwic Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -70,7 +70,7 @@ here in the future.
=pod
-=item &DownloadNamePIDSection()
+=item &DownloadClasslist()
Collects lastname, generation, middlename, firstname, PID, and section for each
student from their environment database. The list of students is built from
@@ -101,12 +101,23 @@ middlename, and PID : Key is $name.'stud
=cut
-sub DownloadStudentNamePIDSection {
- my ($courseID, $c)=@_;
+sub DownloadClasslist {
+ my ($courseID, $lastDownloadTime, $c)=@_;
my ($courseDomain,$courseNumber)=split(/\_/,$courseID);
+ my %classlist;
- my %classlist=&Apache::lonnet::dump('classlist',$courseDomain,
- $courseNumber);
+ my $modifiedTime = &GetFileTimestamp($courseDomain, $courseNumber,
+ 'classlist.db',
+ $Apache::lonnet::perlvar{'lonUsersDir'});
+
+ if($lastDownloadTime ne 'Not downloaded' &&
+ $lastDownloadTime >= $modifiedTime && $modifiedTime >= 0) {
+ $classlist{'lastDownloadTime'}=time;
+ $classlist{'UpToDate'} = 'true';
+ return \%classlist;
+ }
+
+ %classlist=&Apache::lonnet::dump('classlist',$courseDomain, $courseNumber);
my ($checkForError)=keys (%classlist);
if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
return \%classlist;
@@ -135,18 +146,23 @@ sub DownloadStudentNamePIDSection {
#Section
my %section=&Apache::lonnet::dump('roles',$studentDomain,$studentName);
- $classlist{$name.':section'}=\%section;
+ $classlist{$name.':sections'}=\%section;
}
+ $classlist{'UpToDate'} = 'false';
+ $classlist{'lastDownloadTime'}=time;
+
return \%classlist;
}
=pod
-=item &DownloadStudentCourseInformation()
+=item &DownloadCourseInformation()
Dump of all the course information for a single student. There is no
-pruning of data, it is all stored in a hash and returned.
+pruning of data, it is all stored in a hash and returned. It also
+checks the timestamp of the students course database file and only downloads
+if it has been modified since the last download.
=over 4
@@ -165,13 +181,24 @@ database.
=cut
-sub DownloadStudentCourseInformation {
- my ($name,$courseID)=@_;
- my ($studentName,$studentDomain) = split(/\:/,$name);
-
- # Download student course data
- my %courseData=&Apache::lonnet::dump($courseID,$studentDomain,
- $studentName);
+sub DownloadCourseInformation {
+ my ($namedata,$courseID,$lastDownloadTime)=@_;
+ my %courseData;
+ my ($name,$domain) = split(/\:/,$namedata);
+
+ my $modifiedTime = &GetFileTimestamp($domain, $name,
+ $courseID.'.db',
+ $Apache::lonnet::perlvar{'lonUsersDir'});
+ if($lastDownloadTime >= $modifiedTime) {
+ $courseData{'lastDownloadTime'}=time;
+ $courseData{'UpToDate'} = 'true';
+ return \%courseData;
+ }
+
+ # Download course data
+ %courseData=&Apache::lonnet::dump($courseID, $domain, $name);
+ $courseData{'UpToDate'} = 'false';
+ $courseData{'lastDownloadTime'}=time;
return \%courseData;
}
@@ -309,8 +336,13 @@ sub ProcessTopResourceMap {
':'.$currentResourceID;
}
- # Get Parts for problem
my $meta=$hash{'src_'.$currentResourceID};
+# $cache->{$currentResourceID.':title'}=
+# &Apache::lonnet::metdata($meta,'title');
+ $cache->{$currentResourceID.':title'}=
+ $hash{'title_'.$currentResourceID};
+
+ # Get Parts for problem
foreach (split(/\,/,&Apache::lonnet::metadata($meta,'keys'))) {
if($_=~/^stores\_(\d+)\_tries$/) {
my $Part=&Apache::lonnet::metadata($meta,$_.'.part');
@@ -322,7 +354,23 @@ sub ProcessTopResourceMap {
$cache->{$currentSequence.':'.$currentResourceID.
':parts'}.=':'.$Part;
}
- }
+ foreach (split(/\,/,
+ &Apache::lonnet::metadata($meta,'packages'))) {
+ if($_=~/^optionresponse\_($Part)\_(\w+)$/) {
+ if(defined($cache->{'OptionResponses'})) {
+ $cache->{'OptionResponses'}.= ':::'.
+ $hash{'src_'.$currentResourceID}.'::'.
+ $hash{'title_'.$currentResourceID}.'::'.
+ $Part.'::'.$Problem;
+ } else {
+ $cache->{'OptionResponses'}=
+ $hash{'src_'.$currentResourceID}.'::'.
+ $hash{'title_'.$currentResourceID}.'::'.
+ $Part.'::'.$Problem;
+ }
+ }
+ }
+ }
}
}
@@ -336,6 +384,8 @@ sub ProcessTopResourceMap {
# Capture sequence information here
$cache->{$currentSequence.':title'}=
$hash{'title_'.$currentResourceID};
+ $cache->{$currentSequence.':source'}=
+ $hash{'src_'.$currentResourceID};
my $totalProblems=0;
foreach my $currentProblem (split(/\:/,
@@ -399,165 +449,17 @@ sub ProcessTopResourceMap {
=pod
-=item &ProcessSection()
-
-Determine the section number for a student for the class. A student can have
-multiple sections for the same class. The correct one is chosen.
-
-=over 4
-
-Input: $sectionData, $courseid, $ActiveFlag
-
-$sectionData: A pointer to a hash containing all section data for this
-student for the class
+=item &ProcessClasslist()
-$courseid: The course ID.
-
-$ActiveFlag: The student's active status (Active/Expired)
-
-Output: $oldsection, $cursection, or -1
-
-$oldsection and $cursection and sections number that will be displayed in the
-chart.
-
--1 is returned if an error occurs.
-
-=back
-
-=cut
-
-sub ProcessSection {
- my ($sectionData,$courseid,$ActiveFlag)=@_;
- $courseid=~s/\_/\//g;
- $courseid=~s/^(\w)/\/$1/;
-
- my $cursection='-1';
- my $oldsection='-1';
- my $status='Expired';
- my $section='';
- foreach my $key (keys (%$sectionData)) {
- my $value = $sectionData->{$key};
- if ($key=~/^$courseid(?:\/)*(\w+)*\_st$/) {
- $section=$1;
- if($key eq $courseid.'_st') {
- $section='';
- }
- my ($dummy,$end,$start)=split(/\_/,$value);
- my $now=time;
- my $notactive=0;
- if ($start) {
- if($now<$start) {
- $notactive=1;
- }
- }
- if($end) {
- if ($now>$end) {
- $notactive=1;
- }
- }
- if($notactive == 0) {
- $status='Active';
- $cursection=$section;
- last;
- }
- if($notactive == 1) {
- $oldsection=$section;
- }
- }
- }
- if($status eq $ActiveFlag) {
- if($cursection eq '-1') {
- return $oldsection;
- }
- return $cursection;
- }
- if($ActiveFlag eq 'Any') {
- if($cursection eq '-1') {
- return $oldsection;
- }
- return $cursection;
- }
- return '-1';
-}
-
-=pod
-
-=item &ProcessNamePIDSection()
+Taking the class list dumped from &DownloadClasslist(), all the
+students and their non-class information is processed using the
+&ProcessStudentInformation() function. A date stamp is also recorded for
+when the data was processed.
Takes data downloaded for a student and breaks it up into managable pieces and
stored in cache data. The username, domain, class related date, PID,
full name, and section are all processed here.
-=over 4
-
-Input: $cache, $studentInformation, $section, $date, $name, $courseID
-
-$cache: A hash pointer to store the data
-
-$studentInformation: Student information is what was requested in
-&DownloadPrerequistedData(). See that function for what data is requested.
-
-$section: A hash pointer to class section related information.
-
-$date: A composite of the start and end date for this class for this
-student. Format: end:start
-
-$name: the username:domain information
-
-$courseID: The course ID
-
-Output: None
-
-*NOTE: There is no return value, but if an error occurs a key is added to
-the cache data with the value being the error message. The key is
-username:domain:error. It will only exist if an error occurs.
-
-=back
-
-=cut
-
-sub ProcessStudentNamePIDSection {
- my ($cache,$studentInformation,$section,$date,$name,$courseID,$status)=@_;
- my ($studentName,$studentDomain) = split(/\:/,$name);
-
- $cache->{$name.':username'}=$studentName;
- $cache->{$name.':domain'}=$studentDomain;
- $cache->{$name.':date'}=$date;
-
- my ($checkForError)=keys(%$studentInformation);
- if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
- $cache->{$name.':error'}=
- 'Could not download student environment data.';
- $cache->{$name.':fullname'}='';
- $cache->{$name.':id'}='';
- } else {
- $cache->{$name.':fullname'}=&ProcessFullName(
- $studentInformation->{'lastname'},
- $studentInformation->{'generation'},
- $studentInformation->{'firstname'},
- $studentInformation->{'middlename'});
- $cache->{$name.':id'}=$studentInformation->{'id'};
- }
-
- # Get student's section number
- my $sec=&ProcessSection($section, $courseID, $status);
- if($sec != -1) {
- $cache->{$name.':section'}=$sec;
- } else {
- $cache->{$name.':section'}='';
- }
-
- return;
-}
-
-=pod
-
-=item &ProcessClassList()
-
-Taking the class list dumped from &DownloadPrerequisiteData(), all the
-students and their non-class information is processed using the
-&ProcessStudentInformation() function. A date stamp is also recorded for
-when the data was processed.
=over 4
@@ -566,7 +468,7 @@ Input: $cache, $classlist, $courseID, $C
$cache: A hash pointer to store the data
$classlist: The hash of data collected about a student from
-&DownloadPrerequisteData(). The hash contains a list of students, a pointer
+&DownloadClasslist(). The hash contains a list of students, a pointer
to a hash of student information for each student, and each student's section
number.
@@ -586,28 +488,80 @@ be considered in an arbitrary order.
=cut
-sub ProcessClassList {
- my ($cache,$classlist,$courseID,$status,$c)=@_;
+sub ProcessClasslist {
+ my ($cache,$classlist,$courseID,$c)=@_;
my @names=();
+ $cache->{'ClasslistTimeStamp'}=$classlist->{'lastDownloadTime'};
+ if($classlist->{'UpToDate'} eq 'true') {
+ return split(/:::/,$cache->{'NamesOfStudents'});;
+ }
+
foreach my $name (keys(%$classlist)) {
if($name =~ /\:section/ || $name =~ /\:studentInformation/ ||
- $name eq '') {
+ $name eq '' || $name eq 'UpToDate' || $name eq 'lastDownloadTime') {
next;
}
if($c->aborted()) {
- last;
+ return ();
}
push(@names,$name);
- &ProcessStudentNamePIDSection($cache,
- $classlist->{$name.':studentInformation'},
- $classlist->{$name.':section'},
- $classlist->{$name},
- $name,$courseID,$status);
+ my $studentInformation = $classlist->{$name.':studentInformation'},
+ my $sectionData = $classlist->{$name.':sections'},
+ my $date = $classlist->{$name},
+ my ($studentName,$studentDomain) = split(/\:/,$name);
+
+ $cache->{$name.':username'}=$studentName;
+ $cache->{$name.':domain'}=$studentDomain;
+ if(!defined($cache->{$name.':lastDownloadTime'})) {
+ $cache->{$name.':lastDownloadTime'}='Not downloaded';
+ }
+
+ my ($checkForError)=keys(%$studentInformation);
+ if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
+ $cache->{$name.':error'}=
+ 'Could not download student environment data.';
+ $cache->{$name.':fullname'}='';
+ $cache->{$name.':id'}='';
+ } else {
+ $cache->{$name.':fullname'}=&ProcessFullName(
+ $studentInformation->{'lastname'},
+ $studentInformation->{'generation'},
+ $studentInformation->{'firstname'},
+ $studentInformation->{'middlename'});
+ $cache->{$name.':id'}=$studentInformation->{'id'};
+ }
+
+ my ($end, $start)=split(':',$date);
+ $courseID=~s/\_/\//g;
+ $courseID=~s/^(\w)/\/$1/;
+
+ my $sec='';
+ foreach my $key (keys (%$sectionData)) {
+ my $value = $sectionData->{$key};
+ if ($key=~/^$courseID(?:\/)*(\w+)*\_st$/) {
+ my $tempsection=$1;
+ if($key eq $courseID.'_st') {
+ $tempsection='';
+ }
+ my ($dummy,$roleend,$rolestart)=split(/\_/,$value);
+ if($roleend eq $end && $rolestart eq $start) {
+ $sec = $tempsection;
+ last;
+ }
+ }
+ }
+
+ my $status='Expired';
+ if(((!$end) || time < $end) && ((!$start) || (time > $start))) {
+ $status='Active';
+ }
+ $cache->{$name.':Status'}=$status;
+ $cache->{$name.':section'}=$sec;
}
- # Time of download
- $cache->{'time'}=localtime();
+ $cache->{'ClasslistTimestamp'}=time;
+ $cache->{'NamesOfStudents'}=join(':::',@names);
return @names;
}
@@ -617,7 +571,7 @@ sub ProcessClassList {
=item &ProcessStudentData()
Takes the course data downloaded for a student in
-&DownloadStudentCourseInformation() and breaks it up into key value pairs
+&DownloadCourseInformation() and breaks it up into key value pairs
to be stored in the cached data. The keys are comprised of the
$username:$domain:$keyFromCourseDatabase. The student username:domain is
stored away signifying that the student's information has been downloaded and
@@ -639,7 +593,7 @@ Output: None
*NOTE: There is no output, but an error message is stored away in the cache
data. This is checked in &FormatStudentData(). The key username:domain:error
will only exist if an error occured. The error is an error from
-&DownloadStudentCourseInformation().
+&DownloadCourseInformation().
=back
@@ -648,23 +602,55 @@ will only exist if an error occured. Th
sub ProcessStudentData {
my ($cache,$courseData,$name)=@_;
- my ($checkForError) = keys(%$courseData);
- if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
- $cache->{$name.':error'}='Could not download course data.';
- } else {
- foreach my $key (keys (%$courseData)) {
- $cache->{$name.':'.$key}=$courseData->{$key};
- }
- if(defined($cache->{'NamesOfStudents'})) {
- $cache->{'NamesOfStudents'}.=':::'.$name;
- } else {
- $cache->{'NamesOfStudents'}=$name;
+ if($courseData->{'UpToDate'} eq 'true') {
+ $cache->{$name.':lastDownloadTime'}=$courseData->{'lastDownloadTime'};
+ return;
+ }
+
+ my @courseKeys = keys(%$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'};
+ foreach (@courseKeys) {
+ $cache->{$name.':'.$_}=$courseData->{$_};
+ }
+
return;
}
+sub LoadDiscussion {
+# my $symb=shift;
+# $r->print('
$cid ... '.$symb);
+# my %contrib=&Apache::lonnet::dump('msu_2964385f9033c63msul1','msu','2964385f9033c63msul1');
+ my ($name, $courseID, $Discuss)=@_;
+ my %contrib=&DownloadCourseInformation($name, $courseID, 0);
+
+ foreach my $temp(keys %contrib) {
+ if ($temp=~/^version/) {
+ my $ver=$contrib{$temp};
+ my ($dummy,$prb)=split(':',$temp);
+ for (my $idx=1; $idx<=$ver; $idx++ ) {
+ my $name=$contrib{"$idx:$prb:sendername"};
+ $Discuss->{"$name:$prb"}=$idx;
+ }
+ }
+ }
+# $r->print('
cid='.$cid);
+# my %contrib=&Apache::lonnet::restore($symb,$cid,
+# $ENV{$cid.'.domain'},
+# $ENV{'course.'.$cid.'.num'});
+
+# $Apache::lonxml::debug=1;
+# &Apache::lonhomework::showhash(%Discuss);
+# $Apache::lonxml::debug=0;
+}
+
# ----- END PROCESSING FUNCTIONS ---------------------------------------
=pod
@@ -792,6 +778,25 @@ sub TestCacheData {
return $isCached;
}
+sub GetFileTimestamp {
+ my ($studentDomain,$studentName,$filename,$root)=@_;
+ $studentDomain=~s/\W//g;
+ $studentName=~s/\W//g;
+ my $subdir=$studentName.'__';
+ $subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/;
+ my $proname="$studentDomain/$subdir/$studentName";
+ $proname .= '/'.$filename;
+ my @dir = &Apache::lonnet::dirlist($proname, $studentDomain, $studentName,
+ $root);
+ my $fileStat = $dir[0];
+ my @stats = split('&', $fileStat);
+ if(@stats) {
+ return $stats[9];
+ } else {
+ return -1;
+ }
+}
+
# ----- END HELPER FUNCTIONS --------------------------------------------
1;