# # $Id: lonwhatsnew.pm,v 1.5 2005/04/07 06:56:23 albertel Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::lonwhatsnew; use strict; use lib qw(/home/httpd/lib/perl); use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonlocal; use Apache::loncoursedata(); use Apache::lonnavmaps(); use Apache::Constants qw(:common :http); use Time::Local; #---------------------------- # handler # #---------------------------- sub handler { my $r = shift; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['command']); my $command = $env{'form.command'}; if ($command eq '') { $command = "info"; } $r->print(&display_header()); if (! (($env{'request.course.fn'}) && (&Apache::lonnet::allowed('vsa',$env{'request.course.id'})))) { # Not in a course, or not allowed to modify parms $env{'user.error.msg'}="/adm/whatsnew:vsa:0:0:Cannot display student activity"; return HTTP_NOT_ACCEPTABLE; } &display_main_box($r,$command); } #------------------------------ # display_main_box # # Display all the elements within the main box #------------------------------ sub display_main_box { my ($r,$command) = @_; my $domain=&Apache::loncommon::determinedomain(); my $tabbg=&Apache::loncommon::designparm('coordinator.tabbg',$domain); $r->print(<
'); $r->print('
Course Action Items  
END_OF_BLOCK &display_nav_box($r,$command); $r->print('
'); if ($command eq 'config') { &display_config_box($r); } else { &display_actions_box($r); } $r->print(<

END_OF_BLOCK } #------------------------------ # display_nav_box # # Display the navigation box #------------------------------ sub display_nav_box { my ($r,$command) = @_; $r->print(''."\n"); if ($command eq "info") { $r->print(''); } else { $r->print(''); } $r->print(''); if ($command eq "config") { $r->print(''); } else { $r->print(''); } $r->print('
'); $r->print('Action Items
'); $r->print('
'); $r->print('Current Action Items
'); $r->print('
 
'); $r->print('Display options
'); $r->print('
'); $r->print('Display options
'); $r->print('
'); } #------------------------------- # display_header # # Display the header information and set # up the HTML #------------------------------- sub display_header{ my $html=&Apache::lonxml::xmlbegin(); my $bodytag=&Apache::loncommon::bodytag('Course Action Items'); return(< Course Action Items $bodytag ENDHEAD } #------------------------------- # display_actions_box # # Display the action items # #------------------------------- sub display_actions_box() { my $r = shift; my $rowColor1 = "#ffffff"; my $rowColor2 = "#eeeeee"; my $rowColor; my %unread = (); my %ungraded = (); my %bombed = (); my @newmsgs = (); my @critmsgs = (); my @newdiscussions = (); my @tograde = (); my @bombs = (); my $domain=&Apache::loncommon::determinedomain(); my $function; if ($env{'request.role'}=~/^(cc|in|ta|ep)/) { $function='coordinator'; } if ($env{'request.role'}=~/^(su|dc|ad|li)/) { $function='admin'; } my $pgbg=&Apache::loncommon::designparm($function.'.pgbg',$domain); my $tabbg=&Apache::loncommon::designparm($function.'.tabbg',$domain); &getitems(\%unread,\%ungraded,\%bombed,\@newdiscussions,\@tograde,\@bombs); my ($msgcount,$critmsgcount) = &getmail(\@newmsgs,\@critmsgs); unless ($env{'request.course.id'}) { $r->print('
You are accessing an invalid course


'); return; } $r->print('Course Action Items

'); ## UNREAD COURSE DISCUSSION POSTS ## $r->print(<<"END");
Unread course discussion posts:
END if (@newdiscussions > 0) { # @newdiscussions = sort { &cmp_title($a,$b) } @newdiscussions; my $rowNum = 0; foreach my $ressymb (@newdiscussions) { my $forum_title = $unread{$ressymb}{'title'}; my $feedurl=&Apache::lonfeedback::get_feedurl($ressymb); my $unreadnum = keys(%{$unread{$ressymb}}); $unreadnum = $unreadnum - 2; if ($unreadnum > 0) { if ($rowNum %2 == 1) { $rowColor = $rowColor1; } else { $rowColor = $rowColor2; } $r->print(''); $rowNum ++; } } } else { $r->print(''); } $r->print('
'.$forum_title.': '.$unreadnum.' 

 No unread posts in course discussions


'); ## UNGRADED ITEMS ## $r->print(<
Problems requiring handgrading:
END if (@tograde > 0) { $r->print(''); my $rowNum = 0; foreach my $res (@tograde) { if ($rowNum %2 == 1) { $rowColor = $rowColor1; } else { $rowColor = $rowColor2; } $r->print(''); $rowNum ++; } } else { $r->print(''); } $r->print('
Problem NameNumber ungraded
'.$ungraded{$res}{title}.''.$ungraded{$res}{count}.'

  No problems require handgrading  


'); $r->print(' '); ## MESSAGES ## $r->print(<
New course messages
END if ($msgcount > 0) { my $rowNum = 0; my $mailcount = 1; foreach my $msg (@newmsgs) { if ($rowNum %2 == 1) { $rowColor = $rowColor1; } else { $rowColor = $rowColor2; } $r->print(''); $rowNum ++; $mailcount ++; } } else { $r->print(''); } $r->print('
'.$mailcount.'.  '.$msg->{'shortsub'}.'    '.$msg->{'from'}.'@'.$msg->{'fromdom'}.' '.$msg->{'sendtime'}.'

No new course messages


'); $r->print(<
New critical messages in course
END if ($critmsgcount > 0) { my $rowNum = 0; my $mailcount = 1; foreach my $msg (@critmsgs) { if ($rowNum %2 == 1) { $rowColor = $rowColor1; } else { $rowColor = $rowColor2; } $r->print(''); $rowNum ++; $mailcount ++; } } else { $r->print(''); } $r->print('
'.$mailcount.'.  '.$msg->{'shortsub'}.'    '.$msg->{'from'}.'@'.$msg->{'fromdom'}.' '.$msg->{'sendtime'}.'

No unread critical messages in course


'); ## BOMBS ## $r->print(<
Problems with errors
END my $bombnum = 0; if (@bombs > 0) { # @bombs = sort { &cmp_title($a,$b) } @bombs; foreach my $bomb (@bombs) { if ($bombnum %2 == 1) { $rowColor = $rowColor1; } else { $rowColor = $rowColor2; } $r->print(''); $bombnum ++; } } else { $r->print(''); } $r->print('
'.$bombed{$bomb}{errorlink}.'

No problems with errors

'); $r->print(' '); $r->print(''); } sub getitems { my ($unread,$ungraded,$bombed,$newdiscussions,$tograde,$bombs) = @_; my $navmap = Apache::lonnavmaps::navmap->new(); my @allres=$navmap->retrieveResources(); my %discussiontime = &Apache::lonnet::dump('discussiontimes', $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); my %lastread = &Apache::lonnet::dump('nohist_'.$env{'request.course.id'}.'_discuss',$env{'user.domain'},$env{'user.name'},'lastread'); my %lastreadtime = (); my @discussions = (); my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist(); foreach my $key (keys(%lastread)) { my $newkey = $key; $newkey =~ s/_lastread$//; $lastreadtime{$newkey} = $lastread{$key}; } foreach my $resource (@allres) { my $result = ''; my $applies = 0; my $symb = $resource->symb(); %{$$bombed{$symb}} = (); %{$$ungraded{$symb}} = (); my $title = $resource->compTitle(); my $ressymb = $symb; if ($ressymb =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) { $ressymb = &Apache::lonfeedback::wrap_symb('bulletin___'.$2.$1.'/'. $2.'/bulletinboard'); } # Check for unread discussion postings if (defined($discussiontime{$ressymb})) { push(@discussions,$ressymb); my $prevread = 0; my $unreadcount = 0; %{$$unread{$ressymb}} = (); $$unread{$ressymb}{'title'} = $title; $$unread{$ressymb}{'symb'} = $symb; if (defined($lastreadtime{$ressymb})) { $prevread = $lastreadtime{$ressymb}; } my %contrib = &Apache::lonnet::restore($ressymb,$env{'request.course.id'}, $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); if ($contrib{'version'}) { for (my $id=1;$id<=$contrib{'version'};$id++) { unless (($contrib{'hidden'}=~/\.$id\./) || ($contrib{'deleted'}=~/\.$id\./)) { if ($prevread <$contrib{$id.':timestamp'}) { $$unread{$ressymb}{$unreadcount} = $id.': '.$contrib{$id.':subject'}; $unreadcount ++; push(@{$newdiscussions}, $ressymb); } } } } } # Check for ungraded problems if ($resource->is_problem()) { my $ctr = 0; my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); my ($partlist,$handgrade,$responseType) = &Apache::grades::response_type($url,$symb); foreach my $student (keys(%$classlist)) { my ($uname,$udom) = split(/:/,$student); my %status=&Apache::grades::student_gradeStatus($url,$symb,$udom,$uname,$partlist); my $submitted = 0; my $graded = 0; foreach (keys(%status)) { $submitted = 1 if ($status{$_} ne 'nothing'); $graded = 1 if ($status{$_} !~ /^correct/); my ($foo,$partid,$foo1) = split(/\./,$_); if ($status{'resource.'.$partid.'.submitted_by'} ne '') { $submitted = 0; } } next if (!$submitted || !$graded); $ctr ++; } if ($ctr) { $$ungraded{$symb}{count} = $ctr; $$ungraded{$symb}{title} = $title; push(@{$tograde}, $symb); } } # Check for bombs if ($resource->getErrors()) { my $errors = $resource->getErrors(); my @bombs = split(/,/, $errors); my $errorcount = scalar(@bombs); my $errorlink = ''; $$bombed{$symb}{errorcount} = $errorcount; $$bombed{$symb}{errorlink} = $errorlink; push(@{$bombs}, $symb); } } # Compile maxtries and degree of difficulty. } sub getmail { my ($newmsgs,$critmsgs) = @_; # Check for unread mail in course my $msgcount = 0; my @messages = &Apache::lonnet::getkeys('nohist_email'); foreach my $message (@messages) { my $msgid=&Apache::lonnet::escape($message); my ($sendtime,$shortsubj,$fromname,$fromdom,$fromcid,$status)= &Apache::lonmsg::unpackmsgid($msgid); if ($fromcid eq $env{'request.course.id'}) { if (defined($sendtime) && $sendtime!~/error/) { my $numsendtime = $sendtime; $sendtime = &Apache::lonlocal::locallocaltime($sendtime); if ($status eq 'new') { $$msgcount ++; push(@{$newmsgs}, { msgid => $msgid, sendtime => $sendtime, shortsub => &Apache::lonnet::unescape($shortsubj), from => $fromname, fromdom => $fromdom }); } } } } # Check for critical messages in course my %what=&Apache::lonnet::dump('critical'); my $result = ''; my $critmsgcount = 0; foreach my $msgid (sort(keys(%what))) { my ($sendtime,$shortsubj,$fromname,$fromdom,$fromcid,$status)= &Apache::lonmsg::unpackmsgid($_); if ($fromcid eq $env{'request.course.id'}) { if (defined($sendtime) && $sendtime!~/error/) { my $numsendtime = $sendtime; $sendtime = &Apache::lonlocal::locallocaltime($sendtime); $critmsgcount ++; push(@{$critmsgs}, { msgid => $msgid, sendtime => $sendtime, shortsub => &Apache::lonnet::unescape($shortsubj), from => $fromname, fromdom => $fromdom }); } } } return ($msgcount,$critmsgcount); } sub cmp_title { my ($atitle,$btitle) = (lc($_[0]->compTitle),lc($_[1]->compTitle)); $atitle=~s/^\s*//; $btitle=~s/^\s*//; return $atitle cmp $btitle; }