[LON-CAPA-cvs] cvs: loncom /interface lonuserutils.pm lonwhatsnew.pm /lonnet/perl lonnet.pm
raeburn
raeburn at source.lon-capa.org
Sat Aug 18 20:18:42 EDT 2012
raeburn Sun Aug 19 00:18:42 2012 EDT
Modified files:
/loncom/interface lonwhatsnew.pm lonuserutils.pm
/loncom/lonnet/perl lonnet.pm
Log:
- Keep track of last course "login".
- Display of last "login" by user/role/section added to What's New screen
and also to "List Users" screen. ("login" is selection of course role).
- DC selecting adhoc role in a course (in which he/she has no existing
role, and use of role switcher within course do *not* cause update
of last log-in for that user/role/section.
-------------- next part --------------
Index: loncom/interface/lonwhatsnew.pm
diff -u loncom/interface/lonwhatsnew.pm:1.105 loncom/interface/lonwhatsnew.pm:1.106
--- loncom/interface/lonwhatsnew.pm:1.105 Fri Mar 16 21:16:38 2012
+++ loncom/interface/lonwhatsnew.pm Sun Aug 19 00:18:16 2012
@@ -1,5 +1,5 @@
#
-# $Id: lonwhatsnew.pm,v 1.105 2012/03/16 21:16:38 www Exp $
+# $Id: lonwhatsnew.pm,v 1.106 2012/08/19 00:18:16 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -72,6 +72,7 @@
['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'};
@@ -143,6 +144,13 @@
$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 @@
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 @@
} 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 @@
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";
<script type="text/javascript">
+// <![CDATA[
function change_display(caller,change) {
caller.value = change;
document.visible.submit();
@@ -264,6 +284,52 @@
}
$scripttag.='document.visible.submit();
}
+
+function togglelogins() {
+ var total = document.visible.logincount.value;
+ var sumrow = document.visible.loginrow.value;
+ if (total == 0) {
+ return;
+ }
+ var showlogindetails = 0;
+ for (var i=0; i<document.visible.logindetails.length; i++) {
+ if (document.visible.logindetails[i].checked) {
+ showlogindetails = document.visible.logindetails[i].value;
+ }
+ }
+ var detval = "none";
+ var sumval = "";
+ if (showlogindetails == 1) {
+ detval = "";
+ sumval = "none";
+ }
+ for (var j=0; j<total; j++) {
+ var counter = j+1;
+ var itemid = "logindet_"+counter;
+ personele = document.getElementById(itemid);
+ if (personele != null) {
+ personele.style.display = detval;
+ }
+ }
+ var detheaderele = document.getElementById("logintitledet");
+ if (detheaderele != null) {
+ detheaderele.style.display = detval;
+ }
+ for (var k=0; k<sumrow; k++) {
+ var counter = k+1;
+ var itemid = "loginsum_"+counter;
+ logincatele = document.getElementById(itemid);
+ if (logincatele != null) {
+ logincatele.style.display = sumval;
+ }
+ }
+ var sumheaderele = document.getElementById("logintitlesum");
+ if (sumheaderele != null) {
+ sumheaderele.style.display = sumval;
+ }
+ return;
+}
+// ]]>
</script>
';
}
@@ -315,6 +381,8 @@
my %expired;
my $activecount;
my %activated;
+ my %loggedin;
+ my $logincount;
my %res_title = ();
my %show = ();
my $needitems = 0;
@@ -445,6 +513,20 @@
$headings{'newroles'} = &mt('Roles for which access to '.$lctype.' has become available since yesterday');
}
+ $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 = time;
if ($timediff{'versions'} == -1) {
$timediff{'versions'} = time;
@@ -461,6 +543,12 @@
}
my $expiredstart = $now - $timediff{'oldroles'};
+ if ($timediff{'crslogin'} == -1) {
+ $timediff{'crslogin'} = time;
+ }
+
+ my $crsloginstart = $now - $timediff{'crslogin'};
+
my $countunread = $display_settings{$cid.':countunread'};
unless (defined($countunread)) {
$countunread = 'on';
@@ -474,7 +562,7 @@
$threshold{'av_attempts'},$threshold{'degdiff'},
'<br />',$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; }
@@ -512,6 +600,9 @@
if ($show{'newroles'}) {
$activecount = &getactivated(\%activated,$activatedstart,'active');
}
+ if ($show{'crslogin'}) {
+ $logincount = &getloggedin($cdom,$crs,\%loggedin,$crsloginstart);
+ }
$r->print(qq|<a href="javascript:changeAll('hide');">$lt{'hial'}</a>
<a href="javascript:changeAll('show');">$lt{'shal'}</a>
<form method="post" name="visible" action="/adm/whatsnew">\n|);
@@ -522,7 +613,7 @@
}
}
- $r->print('<input type="hidden" name="refpage" value="'.$refpage.'" /></form><table class="LC_double_column"><tr><td class="LC_left_col">');
+ $r->print('<input type="hidden" name="refpage" value="'.$refpage.'" /><table class="LC_double_column"><tr><td class="LC_left_col">');
my $displayed = 0;
my $totalboxes = 0;
@@ -540,7 +631,7 @@
if ($displayed == $halfway) {
$r->print('</td><td> </td><td class="LC_right_col" >');
}
- &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);
$displayed ++;
}
}
@@ -548,6 +639,7 @@
</td>
</tr>
</table>
+ </form>
');
}
@@ -628,6 +720,8 @@
$r->print('<br />'.&mt('Choose the time window to use to display roles for which access to the '.$lctype.' expired.').'<br />');
} elsif ($context eq 'newroles') {
$r->print('<br />'.&mt('Choose the time window to use to display roles for which access to the '.$lctype.' became available.').'<br />');
+ } elsif ($context eq 'crslogin') {
+ $r->print('<br />'.&mt('Choose the time window to use to display the last login by a user in the '.$lctype).'<br />');
} else {
$r->print('<br />'.&mt('Choose the time window to use to display resources in the '.$lctype.' with version changes.').'<br />');
}
@@ -793,10 +887,10 @@
$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) = @_;
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);
@@ -820,6 +914,9 @@
} elsif ($action eq 'oldroles') { # EXPIRED ROLES
&display_rolechanges($r,$expirecount,$expired,$interval->{'oldroles'},
$crstype);
+ } elsif ($action eq 'crslogin') { #LAST LOGIN
+ &display_crslogins($r,$logincount,$loggedin,$interval->{'crslogin'},
+ $crstype);
}
}
&end_box($r);
@@ -1419,6 +1516,39 @@
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);
@@ -1675,6 +1805,92 @@
}
return;
}
+
+sub display_crslogins {
+ my ($r,$logincount,$loggedin,$interval,$crstype) = @_;
+ my %lt = &Apache::lonlocal::texthash(
+ 'user' => 'User',
+ 'role' => 'Role',
+ 'sec' => 'Section',
+ 'number' => 'Total number of logins',
+ );
+ if ($logincount) {
+
+ my $hdr = '<tr class="LC_info_row" style="display:none" id="logintitledet">'.
+ '<td class="LC_left_item">'.$lt{'user'}.'</td>'.
+ '<td class="LC_left_item">'.$lt{'role'}.'</td>'.
+ '<td class="LC_left_item">'.$lt{'sec'}.'</td></tr>'.
+ '<tr class="LC_info_row" id="logintitlesum">'.
+ '<td class="LC_left_item">'.$lt{'number'}.'</td>'.
+ '<td class="LC_left_item">'.$lt{'role'}.'</td>'.
+ '<td class="LC_left_item">'.$lt{'sec'};
+ my (%bylastname,%counts);
+ if (ref($loggedin) eq 'HASH') {
+ my @logins = sort { $b <=> $a } (keys(%{$loggedin}));
+ my $numlogin = 0;
+ 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 = &Apache::loncommon::plainname($uname,$udom,'lastname');
+ my $link =
+ &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom);
+ push(@{$bylastname{$fullname}},
+ '<td>'.$link.'</td>'.
+ '<td>'.$role.'</td>'.
+ '<td>'.$section.'</td>');
+ }
+ }
+ }
+ }
+ 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 .= '<tr'.$css_class.' style="display:none;" id="logindet_'.$numlogin.'">'.$item.'</tr>';
+ }
+ }
+ }
+ 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 .= '<tr '.$css_class.' id="loginsum_'.$numrow.'">'.
+ '<td>'.$counts{$role}{$sec}.'</td>'.
+ '<td>'.$showrole.'</td>'.
+ '<td>'.$sec.'</td></tr>';
+ }
+ }
+ }
+ $r->print($hdr.'<input type="hidden" name="logincount" value="'.$numlogin.
+ '" /><input type="hidden" name="loginrow" value="'.$numrow.
+ '" /></td></tr>'.$table);
+ }
+ } else {
+ $r->print('<tr class="LC_empty_row"><td>'.
+ &mt('There are no '.$interval).
+ '<input type="hidden" name="logincount" value="'.$logincount.
+ '." /></td></tr>');
+ }
+ return;
+}
sub display_coursediscussion {
my ($r,$newdiscussions,$unread,$countunread,$res_title,$itemserror) = @_;
@@ -1836,6 +2052,8 @@
$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'};
}
@@ -1990,7 +2208,15 @@
<td class="LC_subheader" colspan="2"><a href="/adm/whatsnew?command=chgoldroleinterval&refpage='.$refpage.'">'.$lt{'chin'}.'</a></td>
</tr>');
}
- }
+ } elsif (($caller eq 'crslogin') && ($$show{$caller})) {
+ if ($$show{$caller}) {
+ $r->print('
+ <tr>
+ <td class="LC_subheader" align="left"><span class="LC_nobreak"><label><input type="radio" name="logindetails" value="0" checked="checked" onclick="javascript:togglelogins();" /> '.&mt('Summary').'</label><label><input type="radio" name="logindetails" value="1" onclick="javascript:togglelogins();" /> '.&mt('Details').'</label></span></td><td class="LC_subheader"><a href="/adm/whatsnew?command=chgcrslogininterval&refpage='.$refpage.'">'.$lt{'chin'}.'</a></td>
+ </tr>');
+ }
+ }
+
$r->print('
<tr>
<td colspan="2">
Index: loncom/interface/lonuserutils.pm
diff -u loncom/interface/lonuserutils.pm:1.138 loncom/interface/lonuserutils.pm:1.139
--- loncom/interface/lonuserutils.pm:1.138 Wed Apr 25 21:22:01 2012
+++ loncom/interface/lonuserutils.pm Sun Aug 19 00:18:16 2012
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Utility functions for managing LON-CAPA user accounts
#
-# $Id: lonuserutils.pm,v 1.138 2012/04/25 21:22:01 raeburn Exp $
+# $Id: lonuserutils.pm,v 1.139 2012/08/19 00:18:16 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -2321,6 +2321,7 @@
'type' => "enroll type/action",
'email' => "e-mail address",
'photo' => "photo",
+ 'lastlogin' => "last login",
'extent' => "extent",
'pr' => "Proceed",
'ca' => "check all",
@@ -2369,6 +2370,9 @@
push(@cols,'groups');
}
push(@cols,'email');
+ if ($context eq 'course') {
+ push(@cols,'lastlogin');
+ }
}
my $rolefilter = $env{'form.showrole'};
@@ -2593,6 +2597,11 @@
Future => 'Future',
Expired => 'Expired',
);
+ # If this is for a single course get last course "log-in".
+ my %crslogins;
+ if ($context eq 'course') {
+ %crslogins=&Apache::lonnet::dump('nohist_crslastlogin',$cdom,$cnum);
+ }
# Get groups, role, permanent e-mail so we can sort on them if
# necessary.
foreach my $user (keys(%{$userlist})) {
@@ -2741,6 +2750,12 @@
$in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
}
}
+ if ($context eq 'course') {
+ my $lastlogin = $crslogins{$in{'username'}.':'.$in{'domain'}.':'.$in{'section'}.':'.$role};
+ if ($lastlogin ne '') {
+ $in{'lastlogin'} = &Apache::lonlocal::locallocaltime($lastlogin);
+ }
+ }
if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') {
$r->print(&Apache::loncommon::start_data_table_row());
my $checkval;
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1184 loncom/lonnet/perl/lonnet.pm:1.1185
--- loncom/lonnet/perl/lonnet.pm:1.1184 Fri Aug 17 22:43:58 2012
+++ loncom/lonnet/perl/lonnet.pm Sun Aug 19 00:18:41 2012
@@ -1,7 +1,7 @@
# The LearningOnline Network
# TCP networking package
#
-# $Id: lonnet.pm,v 1.1184 2012/08/17 22:43:58 raeburn Exp $
+# $Id: lonnet.pm,v 1.1185 2012/08/19 00:18:41 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -5049,15 +5049,19 @@
sub check_adhoc_privs {
my ($cdom,$cnum,$update,$refresh,$now,$checkrole,$caller) = @_;
my $cckey = 'user.role.'.$checkrole.'./'.$cdom.'/'.$cnum;
+ my $setprivs;
if ($env{$cckey}) {
my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend);
&role_status($cckey,$update,$refresh,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend);
unless (($tstatus eq 'is') || ($tstatus eq 'will_not')) {
&set_adhoc_privileges($cdom,$cnum,$checkrole,$caller);
+ $setprivs = 1;
}
} else {
&set_adhoc_privileges($cdom,$cnum,$checkrole,$caller);
+ $setprivs = 1;
}
+ return $setprivs;
}
sub set_adhoc_privileges {
More information about the LON-CAPA-cvs
mailing list