--- loncom/interface/lonnavmaps.pm 2002/02/11 18:59:36 1.25 +++ loncom/interface/lonnavmaps.pm 2002/09/24 02:41:21 1.52 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.25 2002/02/11 18:59:36 albertel Exp $ +# $Id: lonnavmaps.pm,v 1.52 2002/09/24 02:41:21 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -67,6 +67,10 @@ my %courseopt; my %useropt; my %parmhash; +# This parameter keeps track of whether obtaining the user's information +# failed, which the colorizer in astatus can use +my $networkFailedFlag = 0; + # ------------------------------------------------------------------ Euclid gcd sub euclid { @@ -74,7 +78,7 @@ sub euclid { my $a; my $b; my $r; if ($e>$f) { $b=$e; $r=$f; } else { $r=$e; $b=$f; } while ($r!=0) { - $a=$b; $b=$r; + $a=$b; $b=$r; $r=$a%$b; } return $b; @@ -121,14 +125,14 @@ sub parmval { # ---------------------------------------------------------- first, check user if ($uname) { - if ($useropt{$courselevelr}) { return $useropt{$courselevelr}; } - if ($useropt{$courselevelm}) { return $useropt{$courselevelm}; } - if ($useropt{$courselevel}) { return $useropt{$courselevel}; } + if ($useropt{$courselevelr}) { return $useropt{$courselevelr}; } + if ($useropt{$courselevelm}) { return $useropt{$courselevelm}; } + if ($useropt{$courselevel}) { return $useropt{$courselevel}; } } # ------------------------------------------------------- second, check course if ($csec) { - if ($courseopt{$seclevelr}) { return $courseopt{$seclevelr}; } + if ($courseopt{$seclevelr}) { return $courseopt{$seclevelr}; } if ($courseopt{$seclevelm}) { return $courseopt{$seclevelm}; } if ($courseopt{$seclevel}) { return $courseopt{$seclevel}; } } @@ -152,14 +156,14 @@ sub parmval { my ($space,@qualifier)=split(/\./,$rwhat); my $qualifier=join('.',@qualifier); unless ($space eq '0') { - my ($part,$id)=split(/\_/,$space); - if ($id) { - my $partgeneral=&parmval($part.".$qualifier",$symb); - if ($partgeneral) { return $partgeneral; } - } else { - my $resourcegeneral=&parmval("0.$qualifier",$symb); - if ($resourcegeneral) { return $resourcegeneral; } - } + my ($part,$id)=split(/\_/,$space); + if ($id) { + my $partgeneral=&parmval($part.".$qualifier",$symb); + if ($partgeneral) { return $partgeneral; } + } else { + my $resourcegeneral=&parmval("0.$qualifier",$symb); + if ($resourcegeneral) { return $resourcegeneral; } + } } return ''; } @@ -178,25 +182,31 @@ sub parmval { # 1: not attempted # 2: attempted but wrong, or incorrect by instructor # 3: solved or correct by instructor -# "excused" needs to be supported, but is not yet. Could be code=4. +# 4: partially correct (one or more parts correct) +# "excused" needs to be supported, but is not yet. sub astatus { my $rid=shift; - my $code=1; + my $code=0; my $ctext=''; $rid=~/(\d+)\.(\d+)/; my $symb=&Apache::lonnet::declutter($hash{'map_id_'.$1}).'___'.$2.'___'. - &Apache::lonnet::declutter($hash{'src_'.$rid}); - $Apache::lonxml::debug=1; + &Apache::lonnet::declutter($hash{'src_'.$rid}); my %duedate=(); my %opendate=(); my %answerdate=(); # need to always check part 0's open/due/answer status - foreach (sort(split(/\,/,&Apache::lonnet::metadata($hash{'src_'.$rid},'keys')))) { + foreach (sort(split(/\,/,&Apache::lonnet::metadata($hash{'src_'.$rid},'allpo\ssiblekeys')))) { if ($_=~/^parameter\_(.*)\_opendate$/) { - my $part=$1; + my $part=$1; $duedate{$part}=&parmval($part.'.duedate',$symb); $opendate{$part}=&parmval($part.'.opendate',$symb); $answerdate{$part}=&parmval($part.'.answerdate',$symb); + if (&parmval($part.'.opendate.type',$symb) eq 'date_interval') { + $opendate{$part}=$duedate{$part}-$opendate{$part}; + } + if (&parmval($part.'.answerdate.type',$symb) eq 'date_interval') { + $answerdate{$part}=$duedate{$part}+$answerdate{$part}; + } } } my $now=time; @@ -205,499 +215,2004 @@ sub astatus { my %returnhash=&Apache::lonnet::restore($symb); foreach (sort(keys(%opendate))) { - my $duedate=$duedate{$_}; - my $opendate=$opendate{$_}; - my $answerdate=$answerdate{$_}; - my $preface=''; - unless ($_ eq '0') { $preface=' Part: '.$_.' '; } - if ($opendate) { - if ($now<$duedate || (!$duedate)) { - unless ($tcode==4) { $tcode=2; } - if ($duedate) { - $ctext.=$preface.'Due: '.localtime($duedate); - } else { - $ctext.=$preface.'No Due Date'; - } - if ($now<$opendate) { - unless ($tcode) { $tcode=1; } - $ctext.=$preface.'Open: '.localtime($opendate); - } - if ($duedate && $duedate-$now<86400) { - $tcode=4; - $ctext.=$preface.'Due: '.localtime($duedate); - } - } else { - unless (($tcode==4) || ($tcode eq 2)) { $tcode=3; } - if ($now<$answerdate) { - $ctext.='Answer: '.localtime($duedate); - } - } - } else { - unless (($tcode==2) || ($tcode==4)) { $tcode=1; } - } - - my $status=$returnhash{'resource.'.$_.'.solved'}; - - if ($status eq 'correct_by_student') { - unless ($code==2) { $code=3; } - $ctext.=' solved'; - } elsif ($status eq 'correct_by_override') { - unless ($code==2) { $code=3; } - $ctext.=' override'; - } elsif ($status eq 'incorrect_attempted') { - $code=2; - $ctext.=' ('. - ($returnhash{'resource.'.$_.'.tries'}? - $returnhash{'resource.'.$_.'.tries'}:'0'); - my $numtries = &parmval($_.'.maxtries',$symb); - if ($numtries) { $ctext.='/'.$numtries.' tries'; } - $ctext.=')'; - } elsif ($status eq 'incorrect_by_override') { - $code=2; - $ctext.=' override'; - } elsif ($status eq 'excused') { - unless ($code==2) { $code=3; } - $ctext.=' excused'; - } + my $duedate=$duedate{$_}; + my $opendate=$opendate{$_}; + my $answerdate=$answerdate{$_}; + my $preface=''; + unless ($_ eq '0') { $preface=' Part: '.$_.' '; } + if ($opendate) { + if ($now<$duedate || (!$duedate)) { + unless ($tcode==4) { $tcode=2; } + if ($duedate) { + $ctext.=$preface.'Due: '.localtime($duedate); + } else { + $ctext.=$preface.'No Due Date'; + } + if ($now<$opendate) { + unless ($tcode) { $tcode=1; } + $ctext.=$preface.'Open: '.localtime($opendate); + } + if ($duedate && $duedate-$now<86400) { + $tcode=4; + $ctext.=$preface.'Due: '.localtime($duedate); + } + } else { + unless (($tcode==4) || ($tcode eq 2)) { $tcode=3; } + if ($now<$answerdate) { + $ctext.='Answer: '.localtime($duedate); + } + } + } else { + unless (($tcode==2) || ($tcode==4)) { $tcode=1; } + } + + my $status=$returnhash{'resource.'.$_.'.solved'}; + + if ($status eq 'correct_by_student') { + if ($code==0||$code==3) { $code=3; } else { $code=4; } + $ctext.=' solved'; + } elsif ($status eq 'correct_by_override') { + if ($code==0||$code==3) { $code=3; } else { $code=4; } + $ctext.=' override'; + } elsif ($status eq 'incorrect_attempted') { + if ($code!=4 && $code!=3) { $code=2; } + if ($code==3) { $code=4; } + $ctext.=' ('. + ($returnhash{'resource.'.$_.'.tries'}? + $returnhash{'resource.'.$_.'.tries'}:'0'); + my $numtries = &parmval($_.'.maxtries',$symb); + if ($numtries) { $ctext.='/'.$numtries.' tries'; } + $ctext.=')'; + } elsif ($status eq 'incorrect_by_override') { + if ($code!=4 && $code!=3) { $code=2; } + if ($code==3) { $code=4; } + $ctext.=' override'; + } elsif ($status eq 'excused') { + if ($code==0||$code==3) { $code=3; } else { $code=4; } + $ctext.=' excused'; + } else { + if ($code==0) { $code=1; } + } } return 'p'.$code.$tcode.'"'.$ctext.'"'; } + +sub addresource { + my ($resource,$sofar,$rid,$showtypes,$indent,$linkid)=@_; + if ($showtypes eq 'problems') { + if ($resource!~/\.(problem|exam|quiz|assess|survey|form)$/) { + return; + } + } + my $brepriv=&Apache::lonnet::allowed('bre',$resource); + if ($hash{'src_'.$rid}) { + if (($brepriv eq '2') || ($brepriv eq 'F')) { + my $pprefix=''; + if ($resource=~/\.(problem|exam|quiz|assess|survey|form)$/) { + $pprefix=&astatus($rid); + } + $$sofar++; + if ($indent) { $pprefix='i'.$indent.','.$pprefix; } + if ($linkid) { $pprefix='l'.$linkid.','.$pprefix; } + if (defined($rows[$$sofar])) { + $rows[$$sofar].='&'.$pprefix.$rid; + } else { + $rows[$$sofar]=$pprefix.$rid; + } + } + } +} + +sub followlinks () { + my ($rid,$sofar,$beenhere,$further,$showtypes,$indent,$linkid)=@_; + my $mincond=1; + my $next=''; + foreach (split(/\,/,$hash{'to_'.$rid})) { + my $thiscond= + &Apache::lonnet::directcondval($hash{'condid_'.$hash{'undercond_'.$_}}); + if ($thiscond>=$mincond) { + if ($next) { + $next.=','.$_.':'.$thiscond; + } else { + $next=$_.':'.$thiscond; + } + if ($thiscond>$mincond) { $mincond=$thiscond; } + } + } + my $col=0; + &Apache::lonxml::debug("following links -$next-"); + foreach (split(/\,/,$next)) { + my ($nextlinkid,$condval)=split(/\:/,$_); + if ($condval>=$mincond) { + my $now=&tracetable($sofar,$hash{'goesto_'.$nextlinkid}, + $beenhere,$showtypes,$indent,$linkid); + if ($now>$further) { + if ($col>0) { + my $string; + for(my $i=0;$i<$col;$i++) { $string.='&'; } + for(my $i=$further+1;$now-1>$i;$i++) { + $rows[$i]=$string.$rows[$i]; + } + } + $further=$now; + } + } + $col++; + } + return $further; +} # ------------------------------------------------------------ Build page table sub tracetable { - my ($sofar,$rid,$beenhere)=@_; + my ($sofar,$rid,$beenhere,$showtypes,$indent,$linkid)=@_; + my $newshowtypes=$showtypes; my $further=$sofar; - unless ($beenhere=~/\&$rid\&/) { - $beenhere.=$rid.'&'; - - if (defined($hash{'is_map_'.$rid})) { - $sofar++; - my $tprefix=''; - if ($hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$rid}}} - eq 'sequence') { - $tprefix='h'; - } - if (defined($rows[$sofar])) { - $rows[$sofar].='&'.$tprefix.$rid; - } else { - $rows[$sofar]=$tprefix.$rid; - } - if ((defined($hash{'map_start_'.$hash{'src_'.$rid}})) && - (defined($hash{'map_finish_'.$hash{'src_'.$rid}})) && - ($tprefix eq 'h')) { - my $frid=$hash{'map_finish_'.$hash{'src_'.$rid}}; - $sofar= - &tracetable($sofar,$hash{'map_start_'.$hash{'src_'.$rid}}, - '&'.$frid.'&'); - $sofar++; - if ($hash{'src_'.$frid}) { - my $brepriv=&Apache::lonnet::allowed('bre',$hash{'src_'.$frid}); - if (($brepriv eq '2') || ($brepriv eq 'F')) { - my $pprefix=''; - if ($hash{'src_'.$frid}=~ - /\.(problem|exam|quiz|assess|survey|form)$/) { - $pprefix=&astatus($frid); - - } - if (defined($rows[$sofar])) { - $rows[$sofar].='&'.$pprefix.$frid; - } else { - $rows[$sofar]=$pprefix.$frid; - } - } - } - } - } else { - $sofar++; - if ($hash{'src_'.$rid}) { - my $brepriv=&Apache::lonnet::allowed('bre',$hash{'src_'.$rid}); - if (($brepriv eq '2') || ($brepriv eq 'F')) { - my $pprefix=''; - if ($hash{'src_'.$rid}=~ - /\.(problem|exam|quiz|assess|survey|form)$/) { - $pprefix=&astatus($rid); - } - if (defined($rows[$sofar])) { - $rows[$sofar].='&'.$pprefix.$rid; - } else { - $rows[$sofar]=$pprefix.$rid; - } - } - } - } - - if (defined($hash{'to_'.$rid})) { - my $mincond=1; - my $next=''; - map { - my $thiscond= - &Apache::lonnet::directcondval($hash{'condid_'.$hash{'undercond_'.$_}}); - if ($thiscond>=$mincond) { - if ($next) { - $next.=','.$_.':'.$thiscond; - } else { - $next=$_.':'.$thiscond; - } - if ($thiscond>$mincond) { $mincond=$thiscond; } - } - } split(/\,/,$hash{'to_'.$rid}); - map { - my ($linkid,$condval)=split(/\:/,$_); - if ($condval>=$mincond) { - my $now=&tracetable($sofar,$hash{'goesto_'.$linkid},$beenhere); - if ($now>$further) { $further=$now; } - } - } split(/\,/,$next); +# $Apache::lonxml::debug=1; + &Apache::lonxml::debug("$rid ; $linkid ; $sofar ; $beenhere ; ".$hash{'src_'.$rid}); + if ($beenhere=~/\&$rid\&/) { return $further; } + $beenhere.=$rid.'&'; + + if (defined($hash{'is_map_'.$rid})) { + $sofar++; + my $tprefix=''; + if ($hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$rid}}} + eq 'sequence') { + $tprefix='h'; + } elsif ($hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$rid}}} + eq 'page') { + $tprefix='j'; + if ($indent) { $tprefix='i'.$indent.','.$tprefix; } + if ($linkid) { $tprefix='l'.$linkid.','.$tprefix; } + $newshowtypes='problems'; + $indent++; + #if in a .page continue to link the encompising .page + if (!$linkid) { $linkid=$rid; } + } + if (defined($rows[$sofar])) { + $rows[$sofar].='&'.$tprefix.$rid; + } else { + $rows[$sofar]=$tprefix.$rid; + } + if ((defined($hash{'map_start_'.$hash{'src_'.$rid}})) && + (defined($hash{'map_finish_'.$hash{'src_'.$rid}}))) { + my $frid=$hash{'map_finish_'.$hash{'src_'.$rid}}; + $sofar=&tracetable($sofar,$hash{'map_start_'.$hash{'src_'.$rid}}, + '&'.$frid.'&',$newshowtypes,$indent,$linkid); + &addresource($hash{'src_'.$frid},\$sofar,$frid,$newshowtypes, + $indent,$linkid); + if ($tprefix =~ /j$/) { $indent--; $linkid=''; } + } + } else { + &addresource($hash{'src_'.$rid},\$sofar,$rid,$showtypes, + $indent,$linkid); + } - } + if (defined($hash{'to_'.$rid})) { + $further=&followlinks($rid,$sofar,$beenhere,$further,$showtypes, + $indent,$linkid); } + return $further; } # ================================================================ Main Handler sub handler { - my $r=shift; + my $r=shift; + &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); + + if ($ENV{'form.jtest'} ne "1") + { + return new_handle($r); + } # ------------------------------------------- Set document type for header only - if ($r->header_only) { - if ($ENV{'browser.mathml'}) { - $r->content_type('text/xml'); - } else { - $r->content_type('text/html'); - } - $r->send_http_header; - return OK; - } - my $requrl=$r->uri; + if ($r->header_only) { + if ($ENV{'browser.mathml'}) { + $r->content_type('text/xml'); + } else { + $r->content_type('text/html'); + } + $r->send_http_header; + return OK; + } + my $requrl=$r->uri; + my $hashtied; # ----------------------------------------------------------------- Tie db file - if ($ENV{'request.course.fn'}) { - my $fn=$ENV{'request.course.fn'}; - if (-e "$fn.db") { - if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER,0640)) && - (tie(%parmhash,'GDBM_File', - $ENV{'request.course.fn'}.'_parms.db',&GDBM_READER,0640))) { + my $fn; + if ($ENV{'request.course.fn'}) { + $fn=$ENV{'request.course.fn'}; + if (-e "$fn.db") { + if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640)) && + (tie(%parmhash,'GDBM_File', + $ENV{'request.course.fn'}.'_parms.db', + &GDBM_READER(),0640))) { + $hashtied=1; + } + } + } + if (!$hashtied) { + $ENV{'user.error.msg'}="$requrl:bre:0:0:Course not initialized"; + return HTTP_NOT_ACCEPTABLE; + } + # ------------------------------------------------------------------- Hash tied - my $firstres=$hash{'map_start_/res/'.$ENV{'request.course.uri'}}; - my $lastres=$hash{'map_finish_/res/'.$ENV{'request.course.uri'}}; - if (($firstres) && ($lastres)) { + + if ($ENV{'browser.mathml'}) { + $r->content_type('text/xml'); + } else { + $r->content_type('text/html'); + } + &Apache::loncommon::no_cache($r); + $r->send_http_header; + + my $firstres=$hash{'map_start_'. + &Apache::lonnet::clutter($ENV{'request.course.uri'})}; + my $lastres=$hash{'map_finish_'. + &Apache::lonnet::clutter($ENV{'request.course.uri'})}; + if (!(($firstres) && ($lastres))) { + $r->print('
Coursemap undefined.'); + } else { + # ----------------------------------------------------------------- Render page # -------------------------------------------------------------- Set parameters # ---------------------------- initialize coursedata and userdata for this user - undef %courseopt; - undef %useropt; + undef %courseopt; + undef %useropt; - 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.'_'; - - unless ($uhome eq 'no_host') { -# -------------------------------------------------------------- Get coursedata - unless - ((time-$courserdatas{$cid.'.last_cache'})<240) { - my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum. - ':resourcedata',$chome); - if ($reply!~/^error\:/) { - $courserdatas{$cid}=$reply; - $courserdatas{$cid.'.last_cache'}=time; - } - } - map { - my ($name,$value)=split(/\=/,$_); - $courseopt{$userprefix.&Apache::lonnet::unescape($name)}= + 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.'_'; + + 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); + if ($reply!~/^error\:/) { + $courserdatas{$cid}=$reply; + $courserdatas{$cid.'.last_cache'}=time; + } + # check to see if network failed + elsif ( $reply=~/no.such.host/i || $reply=~/con.*lost/i ) + { + $networkFailedFlag = 1; + } + } + foreach (split(/\&/,$courserdatas{$cid})) { + my ($name,$value)=split(/\=/,$_); + $courseopt{$userprefix.&Apache::lonnet::unescape($name)}= &Apache::lonnet::unescape($value); - } split(/\&/,$courserdatas{$cid}); + } # --------------------------------------------------- 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; - } - } - map { - my ($name,$value)=split(/\=/,$_); - $useropt{$userprefix.&Apache::lonnet::unescape($name)}= - &Apache::lonnet::unescape($value); - } split(/\&/,$userrdatas{$uname.'___'.$udom}); - } - - @rows=(); - - &tracetable(0,$firstres,'&'.$lastres.'&'); - if ($hash{'src_'.$lastres}) { - my $brepriv= - &Apache::lonnet::allowed('bre',$hash{'src_'.$lastres}); - if (($brepriv eq '2') || ($brepriv eq 'F')) { - $rows[$#rows+1]=''.$lastres; - } - } + 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; + } + } + foreach (split(/\&/,$userrdatas{$uname.'___'.$udom})) { + my ($name,$value)=split(/\=/,$_); + $useropt{$userprefix.&Apache::lonnet::unescape($name)}= + &Apache::lonnet::unescape($value); + } + } + + @rows=(); + + &tracetable(0,$firstres,'&','',0); # ------------------------------------------------------------------ Page parms - my $j; - my $i; - my $lcm=1; - my $contents=0; + my $j; + my $i; + my $lcm=1; + my $contents=0; # ---------------------------------------------- Go through table to get layout - for ($i=0;$i<=$#rows;$i++) { - if ($rows[$i]) { - $contents++; - my @colcont=split(/\&/,$rows[$i]); - $lcm*=($#colcont+1)/euclid($lcm,($#colcont+1)); - } - } + for ($i=0;$i<=$#rows;$i++) { + if ($rows[$i]) { + &Apache::lonxml::debug("Row $i is:".$rows[$i]); + $contents++; + my @colcont=split(/\&/,$rows[$i]); + $lcm*=($#colcont+1)/euclid($lcm,($#colcont+1)); + } + } - unless ($contents) { - $r->content_type('text/html'); - $r->send_http_header; - $r->print('Empty Map.'); - } else { + unless ($contents) { + $r->print('Empty Map.'); + } else { # ------------------------------------------------------------------ Build page - my $currenturl=$ENV{'form.postdata'}; - $currenturl=~s/^http\:\/\///; - $currenturl=~s/^[^\/]+//; + my $currenturl=$ENV{'form.postdata'}; + $currenturl=~s/^http\:\/\///; + $currenturl=~s/^[^\/]+//; # ---------------------------------------------------------------- Send headers - $r->content_type('text/html'); - &Apache::loncommon::no_cache($r); - $r->send_http_header; - - my $date=localtime; - my $now=time; + my $date=localtime; + my $now=time; # ----------------------------------------- Get email status and discussiontime - my %emailstatus=&Apache::lonnet::dump('email_status'); - my $logouttime=$emailstatus{'logout'}; - my $courseleave= - $emailstatus{'logout_'.$ENV{'request.course.id'}}; - my $lastcheck= - ($courseleave>$logouttime?$courseleave:$logouttime); - - my %discussiontimes=&Apache::lonnet::dump( - 'discussiontimes', - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); - - my %feedback=(); - my %error=(); - foreach my $msgid ( - split(/\&/,&Apache::lonnet::reply('keys:'. - $ENV{'user.domain'}.':'. - $ENV{'user.name'}.':nohist_email', - $ENV{'user.home'}))) { - $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; - } - } - } - } + my %emailstatus=&Apache::lonnet::dump('email_status'); + my $logouttime=$emailstatus{'logout'}; + my $courseleave=$emailstatus{'logout_'.$ENV{'request.course.id'}}; + my $lastcheck=($courseleave>$logouttime?$courseleave:$logouttime); + + my %discussiontimes=&Apache::lonnet::dump('discussiontimes', + $cdom,$cnum); + + my %feedback=(); + my %error=(); + foreach my $msgid (split(/\&/,&Apache::lonnet::reply('keys:'. + $ENV{'user.domain'}.':'. + $ENV{'user.name'}.':nohist_email', + $ENV{'user.home'}))) { + $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; + } + } + } + } # ----------------------------------------------------------- Start Page Output - $r->print( - ''); - if (($currenturl=~/^\/res/) && - ($currenturl!~/^\/res\/adm/)) { - $r->print('Current Location
'); - } + my $bodytagadd=''; + $r->print( + '
'); + if (($currenturl=~/^\/res/) && + ($currenturl!~/^\/res\/adm/)) { + $r->print('Current Location
'); + } + + # Handle a network error + + if ($networkFailedFlag) + { + $r->print('
LON-CAPA's network is having difficulties, some problem" .
+ " information, such as due dates, will not be available.");
+ }
# ----------------------------------------------------- The little content list
- for ($i=0;$i<=$#rows;$i++) {
- if ($rows[$i]) {
- my @colcont=split(/\&/,$rows[$i]);
- my $avespan=$lcm/($#colcont+1);
- for ($j=0;$j<=$#colcont;$j++) {
- my $rid=$colcont[$j];
- if ($rid=~/^h(.+)/) {
- $rid=$1;
- $r->print(
- ' '.$hash{'title_'.$rid}.'
');
- }
- }
- }
- }
+ for ($i=0;$i<=$#rows;$i++) {
+ if ($rows[$i]) {
+ my @colcont=split(/\&/,$rows[$i]);
+ my $avespan=$lcm/($#colcont+1);
+ for ($j=0;$j<=$#colcont;$j++) {
+ my $rid=$colcont[$j];
+ if ($rid=~/^h(.+)/) {
+ $rid=$1;
+ $r->print(' '.$hash{'title_'.$rid}.
+ '
');
+ }
+ }
+ }
+ }
# ----------------------------------------------------------------- Start table
- $r->print('
'; - my $adde=' | '; - my $hwk=''; - my $hwke=''; - if ($rid=~/^h(.+)/) { - $rid=$1; - $add= - ''; - $adde=' | '; - } - if ($rid=~/^p(\d)(\d)\"([\w\: \(\)\/\,]*)\"(.+)/) { - # sub astatus describes what code/tcode mean - my $code=$1; - my $tcode=$2; - my $ctext=$3; - $rid=$4; - if ($tcode eq '1') { - $add=''; - } - if ($code eq '3') { - $add=' | '; - } else { - $add=' | '; - if ($tcode eq '2') { - $add=' | '; - } - if ($tcode eq '4') { - $add=' | '; - $adde=' | '; - } - } - $hwk=''; - $hwke=''; - if ($code eq '1') { - $hwke=' ('.$ctext.')'; - } - if ($code eq '2') { - $hwk=''; - $hwke=' ('.$ctext.')'; - } - if ($code eq '3') { - $hwk=''; - $hwke=' ('.$ctext.')'; - } - } - if ($hash{'src_'.$rid} eq $currenturl) { - $add=$add.''. - '> '; - $adde= - ' <'.$adde; - } - my $src= - &Apache::lonnet::declutter($hash{'src_'.$rid}); - $rid=~/^(\d+)\.(\d+)$/; - my $symb= - &Apache::lonnet::declutter($hash{'map_id_'.$1}).'___'.$2.'___'.$src; - if ($discussiontimes{$symb}>$lastcheck) { - $adde= - ''. - $adde; - } - if ($error{$src}) { - foreach (split(/\,/,$error{$src})) { - if ($_) { - $adde= - ' ' - .$adde; - } - } - } - if ($feedback{$src}) { - foreach (split(/\,/,$feedback{$src})) { - if ($_) { - $adde= - ' ' - .$adde; - } - } - } - $r->print($add.''.$hwk. - $hash{'title_'.$rid}.$hwke.''.$adde); - } - $r->print('
---|
'; + my $adde=' | '; + my $hwk=''; + my $hwke=''; + if ($rid=~/^l(\d+\.\d+),(.+)/) { $linkid=$1; $rid=$2; } + if ($rid=~/^i(\d+),(.+)/) { $indent=$1; $rid=$2; } + if ($rid=~/^h(.+)/) { + $rid=$1; + $add=''; + $adde=' | '; + if (($ENV{'user.adv'}) && + ($parmhash{$symb.'.0.parameter_randompick'})) { + $adde=' (randomly select '. + $parmhash{$symb.'.0.parameter_randompick'}. + ')'; + } + } + if ($rid=~/^j(.+)/) { $rid=$1; } + if ($rid=~/^p(\d)(\d)\"([\w\: \(\)\/\,]*)\"(.+)/) { + # sub astatus describes what code/tcode mean + my $code=$1; + my $tcode=$2; + my $ctext=$3; + $rid=$4; + + # will open later + if ($tcode eq '1') { + $add=''; + } + + # solved/correct + if ($code eq '3') { + $add=' | '; + } elsif ($code eq '4') { # partially correct + $add=' | '; + } else { + # not attempted + + # we end up here on network failure, so pick a neutral + # color if the network failed instead of bright red. + if ( $networkFailedFlag ) + { + $add = ' | '; + } + else + { + $add=' | '; + } + + if ($tcode eq '2') { # open, not past due + $add=' | '; + } + + if ($tcode eq '4') { # due in next 24 hours + $add=' | '; + $adde=' | '; + } + } + $hwk=''; + $hwke=''; + if ($code eq '1') { + $hwke=' ('.$ctext.')'; + } + if ($code eq '2' || $code eq '4') { + $hwk=''; + $hwke=' ('.$ctext.')'; + } + if ($code eq '3') { + $hwk=''; + $hwke=' ('.$ctext.')'; + } + if ($networkFailedFlag) + { + $hwke=' (status unavailable)'; + } + } + if ($rid && $hash{'src_'.$rid} eq $currenturl) { + $add=$add.''. + '> '; + $adde= + ' <'.$adde; + } + if ($discussiontimes{$symb}>$lastcheck) { + $adde= + ''. + $adde; + } + if ($error{$src}) { + foreach (split(/\,/,$error{$src})) { + if ($_) { + $adde= + ' ' + .$adde; + } + } + } + if ($feedback{$src}) { + foreach (split(/\,/,$feedback{$src})) { + if ($_) { + $adde= + ' ' + .$adde; + } + } + } + if ($indent) { + my $is=" "; + for(my $i=-1;$i<$indent;$i++) { $indentstr.=$is; } + } + if (!$linkid) { $linkid=$rid; } + if ($hash{'randomout_'.$rid}) { + $adde=' (hidden)'.$adde; + } + $r->print($add.$indentstr); + if ($rid) { + $r->print(''. + $hwk.$hash{'title_'.$rid}.$hwke.''); + } + $r->print($adde); + } + $r->print('
---|