--- loncom/interface/lonwhatsnew.pm 2009/11/24 02:43:45 1.98 +++ loncom/interface/lonwhatsnew.pm 2016/08/07 02:06:00 1.105.2.11 @@ -1,5 +1,5 @@ # -# $Id: lonwhatsnew.pm,v 1.98 2009/11/24 02:43:45 raeburn Exp $ +# $Id: lonwhatsnew.pm,v 1.105.2.11 2016/08/07 02:06:00 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -72,6 +72,7 @@ sub handler { ['mdc','versionchanges',0], ['vcl','newroles',1], ['vcl','oldroles',1], + ['whn','crslogin',1], ) { my ($perm,$key,$check_section) = @{ $perm_check }; my $scope = $env{'request.course.id'}; @@ -88,7 +89,7 @@ sub handler { 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"; + $env{'user.error.msg'}="/adm/whatsnew:whn:0:0:Cannot display what's new page"; return HTTP_NOT_ACCEPTABLE; } @@ -143,6 +144,13 @@ sub handler { $r->print(&Apache::lonhtmlcommon::breadcrumbs ("What's New?",#'Course_Action_Items_Intervals' )); + } elsif ($command eq 'chgcrslogininterval' && $checkallowed{'crslogin'}) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/whatsnew?command=chgcrslogininterval&refpage='.$refpage, + text=>"Change interval"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs + ("What's New?",#'Course_Action_Items_Intervals' + )); } else { $r->print(&Apache::lonhtmlcommon::breadcrumbs ("What's New?",#'Course_Action_Items_Display' @@ -188,10 +196,17 @@ sub display_main_box { 604800 => 'roles which expired since last week', 86400 => 'roles which expired since yesterday', ); + my %crslogins = ( + -1 => 'last logins for anyone who has ever logged in', + 2592000 => 'last logins for users in last 30 days', + 604800 => 'last logins for users in last 7 days', + 86400 => 'last logins for users in last 24 hours', + ); my %interval_titles = ( versions => \%versions, newroles => \%newroles, oldroles => \%oldroles, + crslogin => \%crslogins, ); my %initpage = &Apache::lonlocal::texthash ( firstres => "first resource in the $lctype", @@ -220,6 +235,9 @@ sub display_main_box { } elsif (($command eq 'chgoldroleinterval') && $checkallowed->{'oldroles'}) { &display_interval_config($r,$refpage,\%interval_titles,'oldroles'); + } elsif (($command eq 'chgcrslogininterval') + && $checkallowed->{'crslogin'}) { + &display_interval_config($r,$refpage,\%interval_titles,'crslogin'); } else { &display_actions_box($r,$command,$refpage,\%threshold_titles, \%interval_titles,\%initpage,$cdom,$crs,$checkallowed); @@ -245,9 +263,11 @@ sub display_header { my $scripttag; unless ($command eq 'chgthreshold' || $command eq 'chginterval' || - $command eq 'chgoldroleinterval' || $command eq 'chgnewroleinterval') { + $command eq 'chgoldroleinterval' || + $command eq 'chgnewroleinterval' || $command eq 'chgcrslogininterval') { $scripttag = <<"END"; '; } @@ -315,6 +386,8 @@ sub display_actions_box { my %expired; my $activecount; my %activated; + my %loggedin; + my $logincount; my %res_title = (); my %show = (); my $needitems = 0; @@ -445,21 +518,46 @@ sub display_actions_box { $headings{'newroles'} = &mt('Roles for which access to '.$lctype.' has become available since yesterday'); } - my $now = time; + $timediff{'crslogin'} = $display_settings{$cid.':crslogininterval'}; + unless (defined($timediff{'crslogin'})) { $timediff{'crslogin'} = 604800; } + $interval{'crslogin'} = $interval_titles->{'crslogin'}->{$timediff{'crslogin'}}; + + if ($timediff{'crslogin'} == -1) { + $headings{'crslogin'} = &mt('Last login for anyone who has ever logged in'); + } elsif ($timediff{'crslogin'} == 2592000) { + $headings{'crslogin'} = &mt('Last login for users in last 30 days'); + } elsif ($timediff{'crslogin'} == 604800) { + $headings{'crslogin'} = &mt('Last login for users in last 7 days'); + } elsif ($timediff{'crslogin'} == 86400) { + $headings{'crslogin'} = &mt('Last login for users in last 24 hours'); + } + + my ($now,$starttime,$activatedstart,$expiredstart,$crsloginstart); + $now = time; + if ($timediff{'versions'} == -1) { - $timediff{'versions'} = time; + $starttime = 0; + } else { + $starttime = $now - $timediff{'versions'}; } - my $starttime = $now - $timediff{'versions'}; if ($timediff{'newroles'} == -1) { - $timediff{'newroles'} = time; + $activatedstart = 0; + } else { + $activatedstart = $now - $timediff{'newroles'}; } - my $activatedstart = $now - $timediff{'newroles'}; if ($timediff{'oldroles'} == -1) { - $timediff{'oldroles'} = time; + $expiredstart = 0; + } else { + $expiredstart = $now - $timediff{'oldroles'}; + } + + if ($timediff{'crslogin'} == -1) { + $crsloginstart = 0; + } else { + $crsloginstart = $now - $timediff{'crslogin'}; } - my $expiredstart = $now - $timediff{'oldroles'}; my $countunread = $display_settings{$cid.':countunread'}; unless (defined($countunread)) { @@ -474,7 +572,7 @@ sub display_actions_box { $threshold{'av_attempts'},$threshold{'degdiff'}, '
',$threshold{'numstudents'}); - my @actionorder = ('handgrading','haserrors','abovethreshold','versionchanges','coursediscussion','coursenormalmail','coursecritmail','newroles','oldroles'); + my @actionorder = ('handgrading','haserrors','abovethreshold','versionchanges','coursediscussion','coursenormalmail','coursecritmail','newroles','oldroles','crslogin'); foreach my $key (keys(%{$checkallowed})) { if ($key =~ /_section$/) { next; } @@ -500,6 +598,10 @@ sub display_actions_box { if ($needitems) { $itemserror = &getitems(\%unread,\%ungraded,\%bombed,\%triggered,\%changed,\@newdiscussions,\@tograde,\@bombs,\@warnings,\%threshold,$cdom,$crs,\%res_title,\%show,$starttime,$countunread); } + my $classlist; + if ($show{'oldroles'} || $show{'newroles'} || $show{'crslogin'}) { + $classlist = &Apache::loncoursedata::get_classlist(); + } if ($show{'coursenormalmail'}) { $msgcount = &getnormalmail(\@newmsgs); } @@ -507,10 +609,13 @@ sub display_actions_box { $critmsgcount = &getcritmail(\@critmsgs); } if ($show{'oldroles'}) { - $expirecount = &getexpired(\%expired,$expiredstart,'previous'); + $expirecount = &getexpired(\%expired,$expiredstart,'previous',$classlist); } if ($show{'newroles'}) { - $activecount = &getactivated(\%activated,$activatedstart,'active'); + $activecount = &getactivated(\%activated,$activatedstart,'active',$classlist); + } + if ($show{'crslogin'}) { + $logincount = &getloggedin($cdom,$crs,\%loggedin,$crsloginstart); } $r->print(qq|$lt{'hial'}   $lt{'shal'} @@ -522,7 +627,7 @@ sub display_actions_box { } } - $r->print(''); } } elsif ($itemserror) { @@ -1531,12 +1689,9 @@ sub display_abovethreshold { ); if (@{$warnings} > 0) { @{$warnings} = sort { &cmp_title($a,$b,$res_title) } @{$warnings}; - $r->print(''. - ' '."\n". - ' '. - "\n"); $r->print(''. - ''. + ''. ''. ''. ''. + $r->print(''. $$triggered{$res}{text}[$i].''); } } } } - $r->print(''); + $r->print(''); } elsif ($itemserror) { $r->print(''); } else { @@ -1618,7 +1773,7 @@ sub display_versionchanges { } sub display_rolechanges { - my ($r,$chgcount,$changed,$interval,$crstype) = @_; + my ($r,$chgcount,$changed,$interval,$crstype,$classlist) = @_; my $now = time(); my %lt = &Apache::lonlocal::texthash( 'user' => 'User', @@ -1637,6 +1792,7 @@ sub display_rolechanges { if (ref($changed) eq 'HASH') { my @changes = sort { $b <=> $a } (keys(%{$changed})); my $changenum = 0; + my $fullnameidx = &Apache::loncoursedata::CL_FULLNAME(); foreach my $item (@changes) { if (ref($changed->{$item}) eq 'ARRAY') { foreach my $chg (@{$changed->{$item}}) { @@ -1654,8 +1810,14 @@ sub display_rolechanges { my $udom = $chg->{'udom'}; $changenum ++; my $css_class = $changenum%2?' class="LC_odd_row"':''; + my $fullname; + if (ref($classlist->{$uname.':'.$udom}) eq 'ARRAY') { + $fullname = $classlist->{$uname.':'.$udom}->[$fullnameidx]; + } else { + $fullname = &Apache::loncommon::plainname($uname,$udom,'lastname'); + } my $link = - &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom); + &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom); $r->print(''. ''. ''. @@ -1673,6 +1835,99 @@ sub display_rolechanges { } return; } + +sub display_crslogins { + my ($r,$logincount,$loggedin,$interval,$crstype,$classlist) = @_; + return unless (ref($classlist) eq 'HASH'); + my %lt = &Apache::lonlocal::texthash( + 'user' => 'User', + 'role' => 'Role', + 'sec' => 'Section', + 'number' => 'Total number of logins', + ); + if ($logincount) { + + my $hdr = ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''); + } + } + } + } + my $table; + foreach my $person (sort(keys(%bylastname))) { + if (ref($bylastname{$person}) eq 'ARRAY') { + foreach my $item (@{$bylastname{$person}}) { + $numlogin ++; + my $css_class = $numlogin%2?' class="LC_odd_row"':''; + $table .= ''; + } + } + } + my $numrow = 0; + foreach my $role (sort(keys(%counts))) { + my $showrole = &Apache::lonnet::plaintext($role,$crstype); + if (ref($counts{$role}) eq 'HASH') { + foreach my $sec (sort { $b <=> $a } (keys(%{$counts{$role}}))) { + $numrow ++; + my $css_class = $numrow%2?' class="LC_odd_row"':''; + $table .= ''. + ''. + ''. + ''; + } + } + } + $r->print($hdr.''.$table); + } + } else { + $r->print(''); + } + return; +} sub display_coursediscussion { my ($r,$newdiscussions,$unread,$countunread,$res_title,$itemserror) = @_; @@ -1703,7 +1958,7 @@ sub display_coursediscussion { my $forum_title = $$unread{$ressymb}{'title'}; my $type = 'Resource'; my $feedurl=&Apache::lonfeedback::get_feedurl($ressymb); - my $disclink = $feedurl.'?symb='.$$unread{$ressymb}{symb}; + my $disclink = $feedurl.'?symb='.&escape($$unread{$ressymb}{symb}); if ($feedurl =~ /bulletinboard/) { $type = 'Discussion Board'; } @@ -1834,6 +2089,8 @@ sub store_interval_setting { $interval_settings{$cid.':oldroleinterval'} = $env{'form.interval'}; } elsif ($context eq 'newroles') { $interval_settings{$cid.':newroleinterval'} = $env{'form.interval'}; + } elsif ($context eq 'crslogin') { + $interval_settings{$cid.':crslogininterval'} = $env{'form.interval'}; } else { $interval_settings{$cid.':interval'} = $env{'form.interval'}; } @@ -1841,19 +2098,19 @@ sub store_interval_setting { \%interval_settings,$udom,$uname); if ($outcome eq 'ok') { if (ref($interval_titles->{$context}) eq 'HASH') { - $result = &mt('New filter setting: [_1].',''. - $interval_titles->{$context}->{$env{'form.interval'}}.'').'
'; + $result = &Apache::lonhtmlcommon::confirm_success(&mt('New filter setting: [_1].',''. + $interval_titles->{$context}->{$env{'form.interval'}}.'').'
'); } } else { my $lctype = lc(&Apache::loncommon::course_type()); &Apache::lonnet::logthis('Error saving whatsnew '.$context.' interval setting'. ' '.$outcome.' for '.$uname.':'.$udom.' in '.$lctype.' '.$cid); - $result = &mt('Unable to set interval to [_1] due to [_2].', + $result = &Apache::lonhtmlcommon::confirm_success(&mt('Unable to set interval to [_1] due to [_2].', ''.$interval_titles->{$context}->{$env{'form.interval'}}.'', - ''.$outcome.'.
'); + ''.$outcome.''),1); } } - return $result; + return &Apache::loncommon::confirmwrapper($result); } sub store_discussion_setting { @@ -1865,20 +2122,20 @@ sub store_discussion_setting { my $outcome = &Apache::lonnet::put('nohist_whatsnew', \%discussion_settings,$udom,$uname); if ($outcome eq 'ok') { - $result = &mt('Count unread posts in discussions display set to [_1]', - ''.&mt($env{'form.countunread'}).'').'
'; + $result = &Apache::lonhtmlcommon::confirm_success(&mt('Count unread posts in discussions display set to [_1]', + ''.&mt($env{'form.countunread'}).'').'
'); } else { my $lctype = lc(&Apache::loncommon::course_type()); &Apache::lonnet::logthis('Error saving whatsnew countunread setting'. ' '.$outcome.' for '.$uname.':'.$udom.' in '.$lctype.' '.$cid); - $result = &mt('Unable to set "number unread posts display" to [_1]'. + $result = &Apache::lonhtmlcommon::confirm_success(&mt('Unable to set "number unread posts display" to [_1]'. ' due to [_2].', ''.&mt($env{'form.countunread'}).'', - ''.$outcome.'.
'); + ''.$outcome.''),1); } } - return $result; + return &Apache::loncommon::confirmwrapper($result); } sub store_courseinit_setting { @@ -1903,30 +2160,29 @@ sub store_courseinit_setting { \%courseinit_settings,$udom,$uname); if ($outcome eq 'ok') { if ($page_control eq 'global preferences') { - $result = &mt("Page displayed after role selection in $lctype now set by [_1]user's global preferences[_2].",'',''); + $result = &Apache::lonhtmlcommon::confirm_success(&mt("Page displayed after role selection in $lctype now set by [_1]user's global preferences[_2].",'','')); } else { - $result = &mt('Page displayed after role selection in this '.$lctype.' set to [_1].' - ,''.$$initpage{$env{'form.courseinit_page'}}.''); + $result = &Apache::lonhtmlcommon::confirm_success(&mt('Page displayed after role selection in this '.$lctype.' set to [_1].' + ,''.$$initpage{$env{'form.courseinit_page'}}.'')); } } else { &Apache::lonnet::logthis('Error saving whatsnew courseinit '. 'setting: '.$outcome.' for '.$uname. ':'.$udom.' in '.$lctype.' '.$cid); if ($page_control eq 'global preferences') { - $result = &mt('Unable to set control of page display to [_1]'. + $result = &Apache::lonhtmlcommon::confirm_success(&mt('Unable to set control of page display to [_1]'. ' due to [_2].', ''.$page_control.'', - ''.$outcome.'.
'); + ''.$outcome.''),1); } else { - $result = &mt('Unable to set page display, after role selection, for this '.$lctype.' to [_1] due to [_2].' + $result = &Apache::lonhtmlcommon::confirm_success(&mt('Unable to set page display, after role selection, for this '.$lctype.' to [_1] due to [_2].' ,''.$$initpage{$env{'form.courseinit_page'}}.'' - ,''.$outcome.'') - .'
'; + ,''.$outcome.''),1); } } } } - return $result; + return &Apache::loncommon::confirmwrapper($result); } sub start_box { @@ -1989,7 +2245,15 @@ sub start_box { '); } - } + } elsif (($caller eq 'crslogin') && ($$show{$caller})) { + if ($$show{$caller}) { + $r->print(' + + + '); + } + } + $r->print('
'); + $r->print('
'); my $displayed = 0; my $totalboxes = 0; @@ -540,7 +645,7 @@ sub display_actions_box { if ($displayed == $halfway) { $r->print(' '); } - &display_launcher($r,$actionitem,$refpage,$checkallowed,\%show,\%headings,\%res_title,\@tograde,\%ungraded,\@bombs,\%bombed,\%changed,\@warnings,\%triggered,\@newdiscussions,\%unread,$msgcount,\@newmsgs,$critmsgcount,\@critmsgs,\%interval,$countunread,\%expired,$expirecount,\%activated,$activecount,$crstype,$itemserror); + &display_launcher($r,$actionitem,$refpage,$checkallowed,\%show,\%headings,\%res_title,\@tograde,\%ungraded,\@bombs,\%bombed,\%changed,\@warnings,\%triggered,\@newdiscussions,\%unread,$msgcount,\@newmsgs,$critmsgcount,\@critmsgs,\%interval,$countunread,\%expired,$expirecount,\%activated,$activecount,$crstype,$itemserror,\%loggedin,$logincount,$classlist); $displayed ++; } } @@ -548,6 +653,7 @@ sub display_actions_box {
+ '); } @@ -586,7 +692,7 @@ sub display_threshold_config { foreach my $type (@thresholditems) { my $parameter = $env{'request.course.id'}.':threshold_'.$type; # onchange is javascript to automatically check the 'Set' button. - my $onchange = 'onFocus="javascript:window.document.forms'. + my $onchange = 'onfocus="javascript:window.document.forms'. "['thresholdform'].elements['".$parameter."_setparmval']". '.checked=true;"'; $r->print(&Apache::loncommon::start_data_table_row()."\n". @@ -628,6 +734,8 @@ sub display_interval_config { $r->print('
'.&mt('Choose the time window to use to display roles for which access to the '.$lctype.' expired.').'
'); } elsif ($context eq 'newroles') { $r->print('
'.&mt('Choose the time window to use to display roles for which access to the '.$lctype.' became available.').'
'); + } elsif ($context eq 'crslogin') { + $r->print('
'.&mt('Choose the time window to use to display the last login by a user in the '.$lctype).'
'); } else { $r->print('
'.&mt('Choose the time window to use to display resources in the '.$lctype.' with version changes.').'
'); } @@ -691,7 +799,7 @@ function toggle_countunread(choice) { .'
' .&mt("This can increase the time taken to gather data for the [_1]What's New Page[_2] by a few seconds.",'','') .'  ' - .&mt('Currently set to [_1].',''.$current.'.') + .&mt('Currently set to [_1].',''.$current.'') ); $r->print('

@@ -793,10 +901,10 @@ sub display_launcher { $tograde,$ungraded,$bombs,$bombed,$changed,$warnings,$triggered, $newdiscussions,$unread,$msgcount,$newmsgs,$critmsgcount,$critmsgs, $interval,$countunread,$expired,$expirecount,$activated,$activecount, - $crstype,$itemserror) = @_; + $crstype,$itemserror,$loggedin,$logincount,$classlist) = @_; if ($$checkallowed{$action}) { - &start_box($r,$show,$headings,$action,$refpage,$action); + &start_box($r,$show,$headings,$action,$refpage); if ($$show{$action}) { if ($action eq 'handgrading') { # UNGRADED ITEMS &display_handgrade($r,$tograde,$ungraded,$itemserror); @@ -816,10 +924,13 @@ sub display_launcher { &display_coursecritmail($r,$critmsgcount,$critmsgs); } elsif ($action eq 'newroles') { # ACTIVATED ROLES &display_rolechanges($r,$activecount,$activated,$interval->{'newroles'}, - $crstype); + $crstype,$classlist); } elsif ($action eq 'oldroles') { # EXPIRED ROLES &display_rolechanges($r,$expirecount,$expired,$interval->{'oldroles'}, - $crstype); + $crstype,$classlist); + } elsif ($action eq 'crslogin') { #LAST LOGIN + &display_crslogins($r,$logincount,$loggedin,$interval->{'crslogin'}, + $crstype,$classlist); } } &end_box($r); @@ -974,6 +1085,9 @@ sub check_thresholds { if ($resource->handgrade($part) eq 'yes') { next; } + if ($resource->is_anonsurvey($part)) { + next; + } if ($resource->is_survey($part)) { next; } @@ -996,6 +1110,7 @@ sub check_thresholds { $av_attempts = $attempts/$users; $av_attempts = sprintf("%.2f",$av_attempts); } + &Apache::lonnet::statslog($symb,$part,$users,$av_attempts,$degdiff); if ((($degdiff ne '' && $degdiff >= $$threshold{'degdiff'}) || ($av_attempts ne '' && $av_attempts >= $$threshold{'av_attempts'})) && ($users >= $$threshold{'numstudents'})) { $stats{$part}{degdiff} = $degdiff; $stats{$part}{attempts} = $av_attempts; @@ -1049,7 +1164,7 @@ sub get_curr_thresholds { my $thresholdcount = 0; my ($tmp) = %thresholdsettings; unless ($tmp =~ /^(con_lost|error|no_such_host)/i) { - foreach my $item (keys %{$threshold}) { + foreach my $item (keys(%{$threshold})) { if (exists($thresholdsettings{$cid.':threshold_'.$item})) { $$threshold{$item} = $thresholdsettings{$cid.':threshold_'.$item}; @@ -1064,7 +1179,7 @@ sub get_curr_thresholds { $cdom,$crs,'internal.threshold'); my ($temp) = %coursesettings; unless ($temp =~ /^(con_lost|error|no_such_host)/i) { - foreach my $item (keys %{$threshold}) { + foreach my $item (keys(%{$threshold})) { unless (exists($thresholdsettings{$cid.':threshold_'.$item})) { if (exists($coursesettings{'internal.threshold_'.$item})) { $$threshold{$item} = @@ -1130,10 +1245,14 @@ sub process_reset { sub process_update { my ($uname,$udom,$threshold_titles) = @_; - my $setoutput = ''.&mt('Changes to threshold(s) for problem tracking:').'
'; - foreach (keys %env) { - next if ($_!~/^form\.(.+)\_setparmval$/); - my $name = $1; + my $setoutput = ''.&mt('Changes to threshold(s) for problem tracking:').'

'; + foreach my $key (keys(%env)) { + my $name; + if ($key =~/^form\.(.+)\_setparmval$/) { + $name = $1; + } else { + next; + } my $value = $env{'form.'.$name.'_value'}; if ($name && defined($value) && ($value ne '')) { my $put_result = &Apache::lonnet::put('nohist_whatsnew', @@ -1141,45 +1260,51 @@ sub process_update { my ($shortname) = ($name =~ /^\Q$env{'request.course.id'}\E:threshold_(.+)$/); if ($put_result eq 'ok') { - $setoutput.=&mt('Set threshold for [_1] to [_2]', + $setoutput.= &Apache::lonhtmlcommon::confirm_success(&mt('Set threshold for [_1] to [_2]', ''.$$threshold_titles{$shortname}.'', - ''.$value.'').'
'; + ''.$value.'').'
'); } else { - $setoutput.=&mt('Unable to set threshold for [_1] to [_2] due to [_3].', + $setoutput.= &Apache::lonhtmlcommon::confirm_success(&mt('Unable to set threshold for [_1] to [_2] due to [_3].', ''.$name.'',''.$value.'', - ''.$put_result.'').'
'; + ''.$put_result.'').'
',1); } } } - return $setoutput; + return &Apache::loncommon::confirmwrapper($setoutput); } sub getnormalmail { my ($newmsgs) = @_; -# Check for unread mail in course +# Check for unread messages in user's INBOX (which were sent in context of current course). my $msgcount = 0; - - my @messages = sort(&Apache::lonnet::getkeys('nohist_email')); - foreach my $message (@messages) { - my $msgid=&escape($message); - my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)= - &Apache::lonmsg::unpackmsgid($msgid); - if (($fromcid) && ($fromcid eq $env{'request.course.id'})) { - if (defined($sendtime) && $sendtime!~/error/) { - my $numsendtime = $sendtime; - if ($status eq 'new') { - $sendtime = &Apache::lonlocal::locallocaltime($sendtime); - $msgcount ++; - if ($shortsubj eq '') { - $shortsubj = &mt('No subject'); + my @messages = &Apache::lonnet::getkeys('nohist_email'); + return $msgcount if (!@messages); + my %emailstatus = &Apache::lonnet::dump('email_status'); + foreach my $msgid (sort(@messages)) { + if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) { + my $skipstatus; + if ($emailstatus{$msgid} eq 'new') { + $skipstatus = 1; + } + my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)= + &Apache::lonmsg::unpackmsgid($msgid,undef,$skipstatus,undef, + $env{'request.course.id'}); + if (($fromcid) && ($fromcid eq $env{'request.course.id'})) { + if (defined($sendtime) && $sendtime!~/error/) { + if (($emailstatus{$msgid} eq 'new') || ($status eq 'new')) { + $sendtime = &Apache::lonlocal::locallocaltime($sendtime); + $msgcount ++; + if ($shortsubj eq '') { + $shortsubj = &mt('No subject'); + } + push(@{$newmsgs}, { + msgid => $msgid, + sendtime => $sendtime, + shortsub => $shortsubj, + from => $fromname, + fromdom => $fromdom + }); } - push(@{$newmsgs}, { - msgid => $msgid, - sendtime => $sendtime, - shortsub => $shortsubj, - from => $fromname, - fromdom => $fromdom - }); } } } @@ -1189,16 +1314,16 @@ sub getnormalmail { sub getcritmail { my ($critmsgs) = @_; -# Check for critical messages in course +# Check for critical messages which were sent in context of current course. my %what=&Apache::lonnet::dump('critical'); my $result = ''; my $critmsgcount = 0; foreach my $msgid (sort(keys(%what))) { my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)= - &Apache::lonmsg::unpackmsgid($msgid); + &Apache::lonmsg::unpackmsgid($msgid,undef,1,undef, + $env{'request.course.id'}); if (($fromcid) && ($fromcid eq $env{'request.course.id'})) { if (defined($sendtime) && $sendtime!~/error/) { - my $numsendtime = $sendtime; $sendtime = &Apache::lonlocal::locallocaltime($sendtime); $critmsgcount ++; if ($shortsubj eq '') { @@ -1218,13 +1343,13 @@ sub getcritmail { } sub getexpired { - my ($rolechgs,$rolechgtime,$status) = @_; - my $expirecount = &getrolechanges($rolechgs,$rolechgtime,$status); + my ($rolechgs,$rolechgtime,$status,$classlist) = @_; + my $expirecount = &getrolechanges($rolechgs,$rolechgtime,$status,$classlist); return $expirecount; } sub getactivated { - my ($rolechgs,$rolechgtime,$status) = @_; + my ($rolechgs,$rolechgtime,$status,$classlist) = @_; my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $now = time(); @@ -1236,28 +1361,26 @@ sub getactivated { my (%stucounted,%advcounted); my $activatedcount = 0; if (keys(%changes) > 0) { - foreach my $chg (sort { $b <=> $a } (keys(%changes))) { + foreach my $chg (keys(%changes)) { if (ref($changes{$chg}) eq 'HASH') { - my $timestamp = $changes{$chg}{'exe_time'}; - if ($timestamp) { - if ($rolechgtime > 0) { - if ($timestamp < $rolechgtime) { - last; - } - } + next if ($changes{$chg}{'delflag'}); + if ($rolechgtime > 0) { + next if ($changes{$chg}{'exe_time'} < $rolechgtime); + } + if ($changes{$chg}{'exe_time'}) { + my $timestamp = $changes{$chg}{'exe_time'}; if (ref($changes{$chg}{'logentry'}) eq 'HASH') { - next if ($changes{$chg}{'delflag'}); - my $start = $changes{$chg}{'logentry'}{'start'}; my $end = $changes{$chg}{'logentry'}{'end'}; - my $section = $changes{$chg}{'logentry'}{'section'}; - my $role = $changes{$chg}{'logentry'}{'role'}; - my $uname = $changes{$chg}{'uname'}; - my $udom = $changes{$chg}{'udom'}; next if ($end && $end <= $now); + my $start = $changes{$chg}{'logentry'}{'start'}; + next if ($start >= $timestamp); + my $section = $changes{$chg}{'logentry'}{'section'}; if (($viewablesec ne '') && ($section ne '')) { next if ($viewablesec ne $section); } - next if ($start >= $timestamp); + my $role = $changes{$chg}{'logentry'}{'role'}; + my $uname = $changes{$chg}{'uname'}; + my $udom = $changes{$chg}{'udom'}; if ($role eq 'st') { $stucounted{$uname.':'.$udom.':'.$section} = $start.':'.$end; } else { @@ -1277,12 +1400,13 @@ sub getactivated { } } } - $activatedcount += &getrolechanges($rolechgs,$rolechgtime,$status,\%stucounted,\%advcounted); + $activatedcount += &getrolechanges($rolechgs,$rolechgtime,$status,$classlist,\%stucounted, + \%advcounted); return $activatedcount; } sub getrolechanges { - my ($rolechgs,$rolechgtime,$status,$stucountref,$advcountref) = @_; + my ($rolechgs,$rolechgtime,$status,$classlist,$stucountref,$advcountref) = @_; my (%stucounted,%advcounted); if (ref($stucountref) eq 'HASH') { %stucounted = %{$stucountref}; @@ -1300,63 +1424,64 @@ sub getrolechanges { my ($permission,$allowed) = &Apache::lonuserutils::get_permission($context); my $viewablesec = &Apache::lonuserutils::viewable_section($permission); - my $classlist = &Apache::loncoursedata::get_classlist(); my $secidx = &Apache::loncoursedata::CL_SECTION(); my $startidx = &Apache::loncoursedata::CL_START(); my $endidx = &Apache::loncoursedata::CL_END(); my $rolechgcount = 0; - foreach my $key (keys(%{$classlist})) { - my ($userstatus,$eventtime); - my $student = $classlist->{$key}; - if (ref($student) eq 'ARRAY') { - my $start = $student->[$startidx]; - my $end = $student->[$endidx]; - my $sec = $student->[$secidx]; - my ($stuname,$studom) = split(/:/,$key); - if ($status eq 'active') { - if (exists($stucounted{$key.':'.$sec})) { - next; + if (ref($classlist) eq 'HASH') { + foreach my $key (keys(%{$classlist})) { + my ($userstatus,$eventtime); + my $student = $classlist->{$key}; + if (ref($student) eq 'ARRAY') { + my $start = $student->[$startidx]; + my $end = $student->[$endidx]; + my $sec = $student->[$secidx]; + my ($stuname,$studom) = split(/:/,$key); + if ($status eq 'active') { + if (exists($stucounted{$key.':'.$sec})) { + next; + } } - } - if (($end == 0) || ($end > $start)) { - if ($start <= $now) { - if ($end && $end < $now) { - if ($rolechgtime > 0) { - if ($end > $rolechgtime) { + if (($end == 0) || ($end > $start)) { + if ($start <= $now) { + if ($end && $end < $now) { + if ($rolechgtime > 0) { + if ($end > $rolechgtime) { + $userstatus = 'previous'; + } + } else { $userstatus = 'previous'; } } else { - $userstatus = 'previous'; - } - } else { - if ($rolechgtime > 0) { - if ($start >= $rolechgtime) { + if ($rolechgtime > 0) { + if ($start >= $rolechgtime) { + $userstatus = 'active'; + } + } else { $userstatus = 'active'; } - } else { - $userstatus = 'active'; } } } + next if ($userstatus ne $status); + if ($status eq 'active') { + $eventtime = $start; + } else { + $eventtime = $end; + } + if (($viewablesec ne '') && ($sec ne '')) { + next if ($viewablesec ne $sec); + } + my %chginfo = ( + 'section' => $sec, + 'uname' => $stuname, + 'udom' => $studom, + 'role' => 'st', + 'status' => $userstatus, + ); + $rolechgcount ++; + push(@{$rolechgs->{$eventtime}},\%chginfo); } - next if ($userstatus ne $status); - if ($status eq 'active') { - $eventtime = $start; - } else { - $eventtime = $end; - } - if (($viewablesec ne '') && ($sec ne '')) { - next if ($viewablesec ne $sec); - } - my %chginfo = ( - 'section' => $sec, - 'uname' => $stuname, - 'udom' => $studom, - 'role' => 'st', - 'status' => $userstatus, - ); - $rolechgcount ++; - push (@{$rolechgs->{$eventtime}},\%chginfo); } } my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef, @@ -1417,6 +1542,39 @@ sub getrolechanges { return $rolechgcount; } +sub getloggedin { + my ($cdom,$crs,$lastlogins,$starttime) = @_; + my $context = 'course'; + my ($permission,$allowed) = + &Apache::lonuserutils::get_permission($context); + my $viewablesec = &Apache::lonuserutils::viewable_section($permission); + my %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$crs); + my $logincount = 0; + my ($tmp) = keys(%crslogins); + unless ($tmp =~ /^(con_lost|error|no_such_host)/i) { + if (keys(%crslogins) > 0) { + foreach my $key (keys(%crslogins)) { + my ($uname,$udom,$section,$role) = split(/:/,$key); + my $eventtime = $crslogins{$key}; + if ($eventtime > $starttime) { + if (($viewablesec ne '') && ($section ne '')) { + next if ($viewablesec ne $section); + } + my %chginfo = ( + 'section' => $section, + 'uname' => $uname, + 'udom' => $udom, + 'role' => $role, + ); + $logincount ++; + push (@{$lastlogins->{$eventtime}},\%chginfo); + } + } + } + } + return $logincount; +} + sub checkversions { my ($cdom,$crs,$navmap,$changed,$starttime) = @_; my %changes=&Apache::lonnet::dump('versionupdate',$cdom,$crs); @@ -1433,7 +1591,7 @@ sub checkversions { 'lastrevisiondate'); $revdate = &Apache::lonlocal::locallocaltime($revdate); my $linkurl=&Apache::lonnet::clutter($key); - my $usedversion=$navmap->usedVersion('version_'.$linkurl); + my $usedversion=$navmap->usedVersion($linkurl); my @resources = $navmap->getResourceByUrl($linkurl,1); if (($usedversion) && ($usedversion ne 'mostrecent')) { $version = $usedversion; @@ -1476,9 +1634,9 @@ sub display_handgrade { my $linkurl=&Apache::lonnet::clutter($url); $linkurl .= '?symb='.&escape($res); if ($$ungraded{$res}{'enclink'}) { - $linkurl = + $linkurl = $$ungraded{$res}{'enclink'}.'?symb='.$$ungraded{$res}{'encsymb'}; - } + } $r->print('
'.$$ungraded{$res}{title}.''.$$ungraded{$res}{count}.'
'.$lt{'reso'}.''.$lt{'reso'}. + ''.$lt{'part'}.''.$lt{'nust'}.''.$lt{'avat'}.''.$lt{'dedi'}.''.$lt{'lare'}.''. @@ -1566,13 +1721,13 @@ sub display_abovethreshold { if (ref($$triggered{$res}{text}) eq 'ARRAY') { if (@{$$triggered{$res}{text}} > 1) { for (my $i=1; $i<@{$$triggered{$res}{text}}; $i++) { - $r->print('


'.$itemserror.'
'.&Apache::lonlocal::locallocaltime($item).''.$link.'
'.$lt{'number'}.''.$lt{'role'}.''.$lt{'sec'}; + my (%bylastname,%counts); + if (ref($loggedin) eq 'HASH') { + my @logins = sort { $b <=> $a } (keys(%{$loggedin})); + my $numlogin = 0; + my $fullnameidx = &Apache::loncoursedata::CL_FULLNAME(); + foreach my $item (@logins) { + if (ref($loggedin->{$item}) eq 'ARRAY') { + foreach my $user (@{$loggedin->{$item}}) { + if (ref($user) eq 'HASH') { + my $section; + my $role = + &Apache::lonnet::plaintext($user->{'role'},$crstype); + my $status = &mt($user->{'status'}); + if ($user->{'section'} eq '') { + $section = &mt('none'); + } else { + $section = $user->{'section'}; + } + $counts{$user->{'role'}}{$section} ++; + my $uname = $user->{'uname'}; + my $udom = $user->{'udom'}; + my $fullname; + if (ref($classlist->{$uname.':'.$udom}) eq 'ARRAY') { + $fullname = $classlist->{$uname.':'.$udom}->[$fullnameidx]; + } else { + $fullname = &Apache::loncommon::plainname($uname,$udom,'lastname'); + } + my $link = + &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom); + push(@{$bylastname{$fullname}}, + ''.$link.''.$role.''.$section.'
'.$counts{$role}{$sec}.''.$showrole.''.$sec.'
'. + &mt('There are no '.$interval). + '
'.$lt{'chin'}.'
'.$lt{'chin'}.'
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.