--- loncom/interface/lonnavmaps.pm 2003/08/21 18:29:54 1.219.2.1
+++ loncom/interface/lonnavmaps.pm 2003/08/07 17:26:44 1.221
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Navigate Maps Handler
#
-# $Id: lonnavmaps.pm,v 1.219.2.1 2003/08/21 18:29:54 albertel Exp $
+# $Id: lonnavmaps.pm,v 1.221 2003/08/07 17:26:44 bowersj2 Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -129,9 +129,7 @@ sub real_handler {
$r->send_http_header;
# Create the nav map
- my $navmap = Apache::lonnavmaps::navmap->new(
- $ENV{"request.course.fn"}.".db",
- $ENV{"request.course.fn"}."_parms.db", 1, 1);
+ my $navmap = Apache::lonnavmaps::navmap->new();
if (!defined($navmap)) {
@@ -161,11 +159,6 @@ sub real_handler {
$r->rflush();
- # Now that we've displayed some stuff to the user, init the navmap
- $navmap->init();
-
- $r->rflush();
-
# Check that it's defined
if (!($navmap->courseMapDefined())) {
$r->print('Coursemap undefined.' .
@@ -1172,12 +1165,9 @@ sub render {
if (!$ENV{'form.folderManip'} && !defined($args->{'iterator'})) {
# Step 1: Check to see if we have a navmap
if (!defined($navmap)) {
- $navmap = Apache::lonnavmaps::navmap->new(
- $ENV{"request.course.fn"}.".db",
- $ENV{"request.course.fn"}."_parms.db", 1, 1);
+ $navmap = Apache::lonnavmaps::navmap->new();
$mustCloseNavMap = 1;
}
- $navmap->init();
# Step two: Locate what kind of here marker is necessary
# Determine where the "here" marker is and where the screen jumps to.
@@ -1238,13 +1228,9 @@ sub render {
# Step 1: Check to see if we have a navmap
if (!defined($navmap)) {
- $navmap = Apache::lonnavmaps::navmap->new($r,
- $ENV{"request.course.fn"}.".db",
- $ENV{"request.course.fn"}."_parms.db", 1, 1);
+ $navmap = Apache::lonnavmaps::navmap->new();
$mustCloseNavMap = 1;
}
- # Paranoia: Make sure it's ready
- $navmap->init();
# See if we're being passed a specific map
if ($args->{'iterator_map'}) {
@@ -1646,29 +1632,13 @@ To create a navmap object, use the follo
=over 4
-=item * Bnew>(navHashFile, parmHashFile,
- genCourseAndUserOptions, genMailDiscussStatus, getUserData):
+=item * Bnew>():
-Binds a new navmap object to the compiled nav map hash and parm hash
-given as filenames. genCourseAndUserOptions is a flag saying whether
-the course options and user options hash should be generated. This is
-for when you are using the parameters of the resources that require
-them; see documentation in resource object
-documentation. genMailDiscussStatus causes the nav map to retreive
-information about the email and discussion status of
-resources. Returns the navmap object if this is successful, or
-B if not. You must check for undef; errors will occur when you
-try to use the other methods otherwise. getUserData, if true, will
-retreive the user's performance data for various problems.
+Creates a new navmap object. Returns the navmap object if this is
+successful, or B if not.
=back
-Once you have the $navmap object, call ->init() on it when you are ready
-to use it. This allows you to check if the course map is defined (see
-B below) before engaging in potentially expensive
-initialization routines for the genCourseAndUserOptions and
-genMailDiscussStatus option.
-
When you are done with the $navmap object, you I call
$navmap->untieHashes(), or you'll prevent the current user from using that
course until the web server is restarted. (!)
@@ -1692,12 +1662,6 @@ sub new {
my $class = ref($proto) || $proto;
my $self = {};
- $self->{NAV_HASH_FILE} = shift;
- $self->{PARM_HASH_FILE} = shift;
- $self->{GENERATE_COURSE_USER_OPT} = shift;
- $self->{GENERATE_EMAIL_DISCUSS_STATUS} = shift;
- $self->{GET_USER_DATA} = shift;
-
# Resource cache stores navmap resources as we reference them. We generate
# them on-demand so we don't pay for creating resources unless we use them.
$self->{RESOURCE_CACHE} = {};
@@ -1710,12 +1674,13 @@ sub new {
my %navmaphash;
my %parmhash;
- if (!(tie(%navmaphash, 'GDBM_File', $self->{NAV_HASH_FILE},
+ my $courseFn = $ENV{"request.course.fn"};
+ if (!(tie(%navmaphash, 'GDBM_File', "${courseFn}.db",
&GDBM_READER(), 0640))) {
return undef;
}
- if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE},
+ if (!(tie(%parmhash, 'GDBM_File', "${courseFn}_parms.db",
&GDBM_READER(), 0640)))
{
untie %{$self->{PARM_HASH}};
@@ -1724,128 +1689,134 @@ sub new {
$self->{NAV_HASH} = \%navmaphash;
$self->{PARM_HASH} = \%parmhash;
- $self->{INITED} = 0;
+ $self->{PARM_CACHE} = {};
bless($self);
return $self;
}
-sub init {
+sub generate_course_user_opt {
my $self = shift;
- if ($self->{INITED}) { return; }
+ if ($self->{COURSE_USER_OPT_GENERATED}) { return; }
- # If the course opt hash and the user opt hash should be generated,
- # generate them
- if ($self->{GENERATE_COURSE_USER_OPT}) {
- my $uname=$ENV{'user.name'};
- my $udom=$ENV{'user.domain'};
- my $uhome=$ENV{'user.home'};
- my $cid=$ENV{'request.course.id'};
- my $chome=$ENV{'course.'.$cid.'.home'};
- my ($cdom,$cnum)=split(/\_/,$cid);
-
- my $userprefix=$uname.'_'.$udom.'_';
-
- my %courserdatas; my %useropt; my %courseopt; my %userrdatas;
- unless ($uhome eq 'no_host') {
+ my $uname=$ENV{'user.name'};
+ my $udom=$ENV{'user.domain'};
+ my $uhome=$ENV{'user.home'};
+ my $cid=$ENV{'request.course.id'};
+ my $chome=$ENV{'course.'.$cid.'.home'};
+ my ($cdom,$cnum)=split(/\_/,$cid);
+
+ my $userprefix=$uname.'_'.$udom.'_';
+
+ my %courserdatas; my %useropt; my %courseopt; my %userrdatas;
+ unless ($uhome eq 'no_host') {
# ------------------------------------------------- Get coursedata (if present)
- unless ((time-$courserdatas{$cid.'.last_cache'})<240) {
- my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.
- ':resourcedata',$chome);
- # Check for network failure
- if ( $reply =~ /no.such.host/i || $reply =~ /con_lost/i) {
- $self->{NETWORK_FAILURE} = 1;
- } elsif ($reply!~/^error\:/) {
- $courserdatas{$cid}=$reply;
- $courserdatas{$cid.'.last_cache'}=time;
- }
- }
- foreach (split(/\&/,$courserdatas{$cid})) {
- my ($name,$value)=split(/\=/,$_);
- $courseopt{$userprefix.&Apache::lonnet::unescape($name)}=
- &Apache::lonnet::unescape($value);
- }
+ unless ((time-$courserdatas{$cid.'.last_cache'})<240) {
+ my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.
+ ':resourcedata',$chome);
+ # Check for network failure
+ if ( $reply =~ /no.such.host/i || $reply =~ /con_lost/i) {
+ $self->{NETWORK_FAILURE} = 1;
+ } elsif ($reply!~/^error\:/) {
+ $courserdatas{$cid}=$reply;
+ $courserdatas{$cid.'.last_cache'}=time;
+ }
+ }
+ foreach (split(/\&/,$courserdatas{$cid})) {
+ my ($name,$value)=split(/\=/,$_);
+ $courseopt{$userprefix.&Apache::lonnet::unescape($name)}=
+ &Apache::lonnet::unescape($value);
+ }
# --------------------------------------------------- Get userdata (if present)
- unless ((time-$userrdatas{$uname.'___'.$udom.'.last_cache'})<240) {
- my $reply=&Apache::lonnet::reply('dump:'.$udom.':'.$uname.':resourcedata',$uhome);
- if ($reply!~/^error\:/) {
- $userrdatas{$uname.'___'.$udom}=$reply;
- $userrdatas{$uname.'___'.$udom.'.last_cache'}=time;
- }
- # check to see if network failed
- elsif ( $reply=~/no.such.host/i || $reply=~/con.*lost/i )
- {
- $self->{NETWORK_FAILURE} = 1;
- }
- }
- foreach (split(/\&/,$userrdatas{$uname.'___'.$udom})) {
- my ($name,$value)=split(/\=/,$_);
- $useropt{$userprefix.&Apache::lonnet::unescape($name)}=
- &Apache::lonnet::unescape($value);
- }
- $self->{COURSE_OPT} = \%courseopt;
- $self->{USER_OPT} = \%useropt;
- }
- }
-
- if ($self->{GENERATE_EMAIL_DISCUSS_STATUS}) {
- my $cid=$ENV{'request.course.id'};
- my ($cdom,$cnum)=split(/\_/,$cid);
-
- my %emailstatus = &Apache::lonnet::dump('email_status');
- my $logoutTime = $emailstatus{'logout'};
- my $courseLeaveTime = $emailstatus{'logout_'.$ENV{'request.course.id'}};
- $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ?
- $courseLeaveTime : $logoutTime);
- my %discussiontime = &Apache::lonnet::dump('discussiontimes',
- $cdom, $cnum);
- my %feedback=();
- my %error=();
- my $keys = &Apache::lonnet::reply('keys:'.
- $ENV{'user.domain'}.':'.
- $ENV{'user.name'}.':nohist_email',
- $ENV{'user.home'});
-
- foreach my $msgid (split(/\&/, $keys)) {
- $msgid=&Apache::lonnet::unescape($msgid);
- my $plain=&Apache::lonnet::unescape(&Apache::lonnet::unescape($msgid));
- if ($plain=~/(Error|Feedback) \[([^\]]+)\]/) {
- my ($what,$url)=($1,$2);
- my %status=
- &Apache::lonnet::get('email_status',[$msgid]);
- if ($status{$msgid}=~/^error\:/) {
- $status{$msgid}='';
- }
-
- if (($status{$msgid} eq 'new') ||
- (!$status{$msgid})) {
- if ($what eq 'Error') {
- $error{$url}.=','.$msgid;
- } else {
- $feedback{$url}.=','.$msgid;
- }
- }
- }
- }
-
- $self->{FEEDBACK} = \%feedback;
- $self->{ERROR_MSG} = \%error; # what is this? JB
- $self->{DISCUSSION_TIME} = \%discussiontime;
- $self->{EMAIL_STATUS} = \%emailstatus;
-
+ unless ((time-$userrdatas{$uname.'___'.$udom.'.last_cache'})<240) {
+ my $reply=&Apache::lonnet::reply('dump:'.$udom.':'.$uname.':resourcedata',$uhome);
+ if ($reply!~/^error\:/) {
+ $userrdatas{$uname.'___'.$udom}=$reply;
+ $userrdatas{$uname.'___'.$udom.'.last_cache'}=time;
+ }
+ # check to see if network failed
+ elsif ( $reply=~/no.such.host/i || $reply=~/con.*lost/i )
+ {
+ $self->{NETWORK_FAILURE} = 1;
+ }
+ }
+ foreach (split(/\&/,$userrdatas{$uname.'___'.$udom})) {
+ my ($name,$value)=split(/\=/,$_);
+ $useropt{$userprefix.&Apache::lonnet::unescape($name)}=
+ &Apache::lonnet::unescape($value);
+ }
+ $self->{COURSE_OPT} = \%courseopt;
+ $self->{USER_OPT} = \%useropt;
}
- if ($self->{GET_USER_DATA}) {
- # Retreive performance data on problems
- my %student_data = Apache::lonnet::currentdump($ENV{'request.course.id'},
- $ENV{'user.domain'},
- $ENV{'user.name'});
- $self->{STUDENT_DATA} = \%student_data;
+ $self->{COURSE_USER_OPT_GENERATED} = 1;
+
+ return;
+}
+
+sub generate_email_discuss_status {
+ my $self = shift;
+ if ($self->{EMAIL_DISCUSS_GENERATED}) { return; }
+
+ my $cid=$ENV{'request.course.id'};
+ my ($cdom,$cnum)=split(/\_/,$cid);
+
+ my %emailstatus = &Apache::lonnet::dump('email_status');
+ my $logoutTime = $emailstatus{'logout'};
+ my $courseLeaveTime = $emailstatus{'logout_'.$ENV{'request.course.id'}};
+ $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ?
+ $courseLeaveTime : $logoutTime);
+ my %discussiontime = &Apache::lonnet::dump('discussiontimes',
+ $cdom, $cnum);
+ my %feedback=();
+ my %error=();
+ my $keys = &Apache::lonnet::reply('keys:'.
+ $ENV{'user.domain'}.':'.
+ $ENV{'user.name'}.':nohist_email',
+ $ENV{'user.home'});
+
+ foreach my $msgid (split(/\&/, $keys)) {
+ $msgid=&Apache::lonnet::unescape($msgid);
+ my $plain=&Apache::lonnet::unescape(&Apache::lonnet::unescape($msgid));
+ if ($plain=~/(Error|Feedback) \[([^\]]+)\]/) {
+ my ($what,$url)=($1,$2);
+ my %status=
+ &Apache::lonnet::get('email_status',[$msgid]);
+ if ($status{$msgid}=~/^error\:/) {
+ $status{$msgid}='';
+ }
+
+ if (($status{$msgid} eq 'new') ||
+ (!$status{$msgid})) {
+ if ($what eq 'Error') {
+ $error{$url}.=','.$msgid;
+ } else {
+ $feedback{$url}.=','.$msgid;
+ }
+ }
+ }
}
+
+ $self->{FEEDBACK} = \%feedback;
+ $self->{ERROR_MSG} = \%error; # what is this? JB
+ $self->{DISCUSSION_TIME} = \%discussiontime;
+ $self->{EMAIL_STATUS} = \%emailstatus;
+
+ $self->{EMAIL_DISCUSS_GENERATED} = 1;
+}
- $self->{PARM_CACHE} = {};
- $self->{INITED} = 1;
+sub get_user_data {
+ my $self = shift;
+ if ($self->{RETRIEVED_USER_DATA}) { return; }
+
+ # Retrieve performance data on problems
+ my %student_data = Apache::lonnet::currentdump($ENV{'request.course.id'},
+ $ENV{'user.domain'},
+ $ENV{'user.name'});
+ $self->{STUDENT_DATA} = \%student_data;
+
+ $self->{RETRIEVED_USER_DATA} = 1;
}
# Internal function: Takes a key to look up in the nav hash and implements internal
@@ -1893,6 +1864,9 @@ sub untieHashes {
sub hasDiscussion {
my $self = shift;
my $symb = shift;
+
+ $self->generate_email_discuss_status();
+
if (!defined($self->{DISCUSSION_TIME})) { return 0; }
#return defined($self->{DISCUSSION_TIME}->{$symb});
@@ -1907,6 +1881,8 @@ sub getFeedback {
my $self = shift;
my $symb = shift;
+ $self->generate_email_discuss_status();
+
if (!defined($self->{FEEDBACK})) { return ""; }
return $self->{FEEDBACK}->{$symb};
@@ -1916,7 +1892,9 @@ sub getFeedback {
sub getErrors {
my $self = shift;
my $src = shift;
-
+
+ $self->generate_email_discuss_status();
+
if (!defined($self->{ERROR_MSG})) { return ""; }
return $self->{ERROR_MSG}->{$src};
}
@@ -2029,6 +2007,9 @@ sub parmval_real {
my $self = shift;
my ($what,$symb,$recurse) = @_;
+ # Make sure the {USER_OPT} and {COURSE_OPT} hashes are populated
+ $self->generate_course_user_opt();
+
my $cid=$ENV{'request.course.id'};
my $csec=$ENV{'request.course.sec'};
my $uname=$ENV{'user.name'};
@@ -3307,6 +3288,7 @@ sub answerdate {
}
sub awarded {
my $self = shift; my $part = shift;
+ $self->{NAV_MAP}->get_user_data();
if (!defined($part)) { $part = '0'; }
return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.awarded'};
}
@@ -3945,8 +3927,8 @@ sub status {
if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE) {
# and there are TRIES LEFT:
if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) {
- return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT;
- }
+ return TRIES_LEFT;
+ }
return $suppressFeedback ? ANSWER_SUBMITTED : INCORRECT; # otherwise, return orange; student can't fix this
}