#
# $Id: lonwhatsnew.pm,v 1.67 2006/12/20 23:02:33 raeburn 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::lonuserstate;
use Apache::Constants qw(:common :http);
use Time::Local;
use GDBM_File;
use lib '/home/httpd/lib/perl/';
use LONCAPA;
#----------------------------
# handler
#
#----------------------------
sub handler {
my $r = shift;
if ($r->header_only) {
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK;
}
&Apache::loncommon::get_unprocessed_cgi(
$ENV{'QUERY_STRING'},['command','refpage']);
my $command = $env{'form.command'};
my $refpage = $env{'form.refpage'};
my %checkallowed = ( coursenormalmail => 1,
coursecritmail => 1, );
foreach my $perm_check (['whn','whatsnew',1],
['pch','coursediscussion',1],
['mgr','handgrading',1],
['vgr','abovethreshold',1],
['opa','haserrors',1],
['mdc','versionchanges',0],
) {
my ($perm,$key,$check_section) = @{ $perm_check };
my $scope = $env{'request.course.id'};
if (!($checkallowed{$key} = &Apache::lonnet::allowed($perm,$scope))) {
$scope .= '/'.$env{'request.course.sec'};
if ( $check_section ) {
$checkallowed{$key} = &Apache::lonnet::allowed($perm,$scope);
}
if ($checkallowed{$key}) {
$checkallowed{$key.'_section'} = $env{'request.course.sec'};
}
}
}
if ( ! $env{'request.course.fn'} || ! $checkallowed{'whatsnew'}) {
# Not in a course, or no whn priv in course
$env{'user.error.msg'}="/adm/whatsnew::whn:0:0:Cannot display what's new page";
return HTTP_NOT_ACCEPTABLE;
}
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
$r->print(&display_header($command,\%checkallowed));
&Apache::lonhtmlcommon::clear_breadcrumbs();
&Apache::lonhtmlcommon::add_breadcrumb
({href=>'/adm/whatsnew',
text=>"Display Action Items"});
if (($command eq 'chgthreshold') && $checkallowed{'abovethreshold'}) {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>'/adm/whatsnew?command=chgthreshold&refpage='.$refpage,
text=>"Change thresholds"});
$r->print(&Apache::lonhtmlcommon::breadcrumbs
("What's New?",#'Course_Action_Items_Thresholds'
));
} elsif (($command eq 'chginterval') && $checkallowed{'versionchanges'} ) {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>'/adm/whatsnew?command=chginterval&refpage='.$refpage,
text=>"Change interval"});
$r->print(&Apache::lonhtmlcommon::breadcrumbs
("What's New?",#'Course_Action_Items_Intervals'
));
} elsif (($command eq 'chgdisc') && $checkallowed{'coursediscussion'}) {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>'/adm/whatsnew?command=chgdisc&refpage='.$refpage,
text=>"Change discussion display"});
$r->print(&Apache::lonhtmlcommon::breadcrumbs
("What's New?",#'Course_Action_Items_Intervals'
));
} elsif ($command eq 'courseinit') {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>'/adm/whatsnew?command=courseinit&refpage='.$refpage,
text=>"Course initialization preference"});
$r->print(&Apache::lonhtmlcommon::breadcrumbs
("What's New?",#'Course_Action_Items_Initialization'
));
} else {
$r->print(&Apache::lonhtmlcommon::breadcrumbs
("What's New?",#'Course_Action_Items_Display'
));
}
&display_main_box($r,$command,$refpage,\%checkallowed);
return OK;
}
#------------------------------
# display_main_box
#
# Display all the elements within the main box
#------------------------------
sub display_main_box {
my ($r,$command,$refpage,$checkallowed) = @_;
my $domain=&Apache::loncommon::determinedomain();
my $function = &Apache::loncommon::get_users_function();
my $tabbg=&Apache::loncommon::designparm($function.'.tabbg',$domain);
my $lctype = lc(&Apache::loncommon::course_type());
$r->print('
');
my %threshold_titles = &Apache::lonlocal::texthash (
av_attempts => 'Average number of attempts',
degdiff => 'Degree of difficulty',
numstudents => 'Total number of students with submissions',
);
my %interval_titles = &Apache::lonlocal::texthash (
-1 => "since start of $lctype",
2592000 => 'since last month',
604800 => 'since last week',
86400 => 'since yesterday',
);
my %initpage = &Apache::lonlocal::texthash (
firstres => "first resource in the $lctype",
whatsnew => "what's new? page",
userpref => 'your general user preferences',
coursespecific => "specific setting for this $lctype",
);
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
if (($command eq 'chgthreshold')
&& $checkallowed->{'abovethreshold'}) {
&display_threshold_config($r,$refpage,$tabbg,\%threshold_titles,
$cdom,$crs);
} elsif (($command eq 'chginterval')
&& $checkallowed->{'versionchanges'}) {
&display_interval_config($r,$refpage,\%interval_titles);
} elsif (($command eq 'chgdisc')
&& $checkallowed->{'coursediscussion'}) {
&display_discussion_config($r,$refpage);
} elsif ($command eq 'courseinit') {
&courseinit_config($r,$refpage,\%initpage);
} else {
&display_actions_box($r,$tabbg,$command,$refpage,\%threshold_titles,
\%interval_titles,\%initpage,$cdom,$crs,$checkallowed);
}
my $end_page = &Apache::loncommon::end_page();
$r->print(<
$end_page
END_OF_BLOCK
}
#-------------------------------
# display_header
#
# Display the header information and set
# up the HTML
#-------------------------------
sub display_header {
my ($command,$checkallowed) = @_;
my $scripttag;
unless ($command eq 'chgthreshold' || $command eq 'chginterval') {
$scripttag = <<"END";
';
}
my $course_type=&Apache::loncommon::course_type();
return &Apache::loncommon::start_page($course_type.' Action Items',
$scripttag);
}
#-------------------------------
# display_actions_box
#
# Display the action items
#
#-------------------------------
sub display_actions_box {
my ($r,$tabbg,$command,$refpage,$threshold_titles,$interval_titles,
$initpage,$cdom,$crs,$checkallowed) = @_;
my $rowColor1 = "#ffffff";
my $rowColor2 = "#eeeeee";
my $udom = $env{'user.domain'};
my $uname = $env{'user.name'};
my $cid = $env{'request.course.id'};
my $crstype = &Apache::loncommon::course_type();
my $lctype = lc($crstype);
my %stulabel = (
'Course' => 'students',
'Group' => 'members',
);
my %lt = &Apache::lonlocal::texthash(
'yacc' => 'You are accessing an invalid course',
'gtfr' => 'Go to first resource',
'hial' => 'Hide all',
'shal' => 'Show all',
);
my %unread = ();
my %ungraded = ();
my %bombed = ();
my %triggered = ();
my %changed = ();
my @newmsgs = ();
my @critmsgs = ();
my @newdiscussions = ();
my @tograde = ();
my @bombs = ();
my @warnings = ();
my $msgcount = 0;
my $critmsgcount = 0;
my %res_title = ();
my %show = ();
my $needitems = 0;
my $boxcount = 0;
my $result;
if ($command eq 'newcourseinit') {
$result = &store_courseinit_setting($uname,$udom,$cid,$initpage);
}
my %threshold = ();
my %pagedesc = &Apache::lonlocal::texthash (
firstres => 'First resource',
whatsnew => "What's New? page",
userpref => 'user preference',
coursespecific => $lctype.' only',
default => 'default',
);
my ($initcontrol,$initdisp) = &curr_courseinit();
my $currinit = $pagedesc{$initdisp}.' ('.$pagedesc{$initcontrol}.')';
unless ($cid) {
$r->print('
'.$lt{'yacc'}.'
');
return;
}
if ($refpage eq 'start') {
if (tie(my %bighash,'GDBM_File',$env{'request.course.fn'}.'.db',
&GDBM_READER(),0640)) {
my $furl=$bighash{'first_url'};
untie(%bighash);
$r->print(''.$lt{'gtfr'}.
' ');
}
}
$r->print(&mt('Page set to be displayed after you have selected a role in this '.$lctype).
'. '.&mt('Currently: [_1]',$currinit).'. '.
&mt('Change for just this '.$lctype.'',$refpage).' '.
&mt('or for all your courses',$refpage).' ');
if ($command eq 'reset') {
$result = &process_reset($cdom,$crs);
} elsif ($command eq 'update') {
$result = &process_update($uname,$udom,$threshold_titles);
} elsif ($command eq 'newinterval') {
$result = &store_interval_setting($uname,$udom,$cid,$interval_titles);
} elsif ($command eq 'newdiscconf') {
$result = &store_discussion_setting($uname,$udom,$cid);
}
my $store_result=&store_display_settings($uname,$udom,$cid,$checkallowed);
unless ($store_result eq 'ok') {
&Apache::lonnet::logthis('Error storing whatsnew settings: '.
$store_result.' for '.'user '.$uname.':'.$udom.' in '.$lctype.' '.$cid);
$result .= &mt('Unable to store visibility settings due to [_1]',
$store_result);
}
if ($result) {
$r->print($result.'');
}
$r->rflush();
my %display_settings = &get_display_settings($uname,$udom,$cid);
my $timediff = $display_settings{$cid.':interval'};
unless (defined($timediff)) { $timediff = 604800; }
my $now = time;
my $interval = $$interval_titles{$timediff};
if ($timediff == -1) {
$timediff = time;
}
my $starttime = $now - $timediff;
my $countunread = $display_settings{$cid.':countunread'};
unless (defined($countunread)) {
$countunread = 'on';
}
my %headings = &Apache::lonlocal::texthash(
coursediscussion => 'Unread '.$lctype.' discussion posts',
handgrading => 'Problems requiring handgrading',
haserrors => 'Problems with errors',
versionchanges => 'Resources in '.$lctype.' with version changes '.$interval,
coursenormalmail => 'New '.$lctype.' messages',
coursecritmail => 'New critical messages in '.$lctype,
);
if ($$checkallowed{'abovethreshold'}) {
&get_curr_thresholds(\%threshold,$uname,$udom,$cid,$cdom,$crs);
}
$headings{'abovethreshold'} =
&mt('Problems with av. attempts ≥ [_1] or deg. difficulty ≥ [_2] and total number of '.$stulabel{$crstype}.' with submissions ≥ [_3]',
$threshold{'av_attempts'},$threshold{'degdiff'},
$threshold{'numstudents'});
my @actionorder = ('handgrading','haserrors','abovethreshold','versionchanges','coursediscussion','coursenormalmail','coursecritmail');
foreach my $key (keys(%{$checkallowed})) {
if ($key =~ /_section$/) { next; }
$show{$key} = 0;
if ($$checkallowed{$key}) {
unless ($display_settings{$cid.':'.$key} eq 'hide') {
$show{$key} = 1;
}
}
}
foreach my $item (@actionorder) {
unless ($item eq 'coursenormalmail' || $item eq 'coursecritmail') {
if ($show{$item}) {
$needitems = 1;
last;
}
}
}
if ($needitems) {
&getitems(\%unread,\%ungraded,\%bombed,\%triggered,\%changed,\@newdiscussions,\@tograde,\@bombs,\@warnings,$rowColor1,$rowColor2,\%threshold,$cdom,$crs,\%res_title,\%show,$starttime,$countunread);
}
if ($show{'coursenormalmail'}) {
$msgcount = &getnormalmail(\@newmsgs);
}
if ($show{'coursecritmail'}) {
$critmsgcount = &getcritmail(\@critmsgs);
}
$r->print(qq|$lt{'hial'}$lt{'shal'}
');
my $displayed = 0;
my $totalboxes = 0;
foreach my $key (keys(%{$checkallowed})) {
if ($key =~ /_section$/) { next; }
if ($key eq 'whatsnew' ) { next; } # whatsnew check creates no box
if ($$checkallowed{$key}) {
$totalboxes ++;
}
}
my $halfway = int($totalboxes/2) + $totalboxes%2;
foreach my $actionitem (@actionorder) {
if ($$checkallowed{$actionitem}) {
if ($displayed == $halfway) {
$r->print('
');
}
#-------------------------------
# display_threshold_config
#
# Display the threshold setting screen
#
#-------------------------------
sub display_threshold_config {
my ($r,$refpage,$tabbg,$threshold_titles,$cdom,$crs) = @_;
my $uname = $env{'user.name'};
my $udom = $env{'user.dom'};
my $cid = $env{'request.course.id'};
my %threshold = ();
my $rowColor1 = "#ffffff";
my $rowColor2 = "#eeeeee";
my $rowColor;
my @thresholditems = ("av_attempts","degdiff","numstudents");
my %threshold_titles = &Apache::lonlocal::texthash(
av_attempts => 'Average number of attempts',
degdiff => 'Degree of difficulty',
numstudents => 'Total number of students with submissions',
);
&get_curr_thresholds(\%threshold,$uname,$udom,$cid,$cdom,$crs);
$r->print('