--- loncom/interface/lonquickgrades.pm 2011/06/02 01:34:34 1.98
+++ loncom/interface/lonquickgrades.pm 2015/03/30 22:29:24 1.107
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Quick Student Grades Display
#
-# $Id: lonquickgrades.pm,v 1.98 2011/06/02 01:34:34 www Exp $
+# $Id: lonquickgrades.pm,v 1.107 2015/03/30 22:29:24 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -29,22 +29,30 @@
package Apache::lonquickgrades;
use strict;
-use Apache::Constants qw(:common :http);
+use Apache::Constants qw(:common :http REDIRECT);
use POSIX;
use Apache::loncommon;
use Apache::lonlocal;
use Apache::lonnet;
use Apache::grades;
-use Time::HiRes;
-my $time=0;
+use Apache::loncoursedata;
+use Apache::lonstudentassessment;
+use Apache::lonuserstate;
-sub tim {
- my ($label)=@_;
- my $tt=&Time::HiRes::time();
- my $dt=$tt-$time;
- &Apache::lonnet::logthis("qg $label ".$dt);
- $time=$tt;
-}
+use Time::HiRes;
+use Spreadsheet::WriteExcel;
+use Spreadsheet::WriteExcel::Utility();
+#
+# Excel data
+#
+my $excel_sheet;
+my $excel_workbook;
+my $filename;
+my $format;
+my $request_aborted;
+my $header_row;
+my $cols_output;
+my %prog_state;
sub handler {
@@ -68,6 +76,39 @@ sub real_handler {
return OK;
}
+ my $cangrade=&Apache::lonnet::allowed('mgr');
+
+ unless ($cangrade) {
+ # Check for critical messages and redirect if present.
+ my ($redirect,$url) = &Apache::loncommon::critical_redirect(300);
+ if ($redirect) {
+ &Apache::loncommon::content_type($r,'text/html');
+ $r->header_out(Location => $url);
+ return REDIRECT;
+ }
+
+ # Check if course needs to be re-initialized
+ my $loncaparev = $r->dir_config('lonVersion');
+ my ($result,@reinit) = &Apache::loncommon::needs_coursereinit($loncaparev);
+
+ if ($result eq 'switch') {
+ &Apache::loncommon::content_type($r,'text/html');
+ $r->send_http_header;
+ $r->print(&Apache::loncommon::check_release_result(@reinit));
+ return OK;
+ } elsif ($result eq 'update') {
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");
+ if ($ferr) {
+ my $requrl = $r->uri;
+ $env{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";
+ $env{'user.reinit'} = 1;
+ return HTTP_NOT_ACCEPTABLE;
+ }
+ }
+ }
+
# Send header, don't cache this page
&Apache::loncommon::no_cache($r);
$r->send_http_header;
@@ -92,7 +133,6 @@ sub real_handler {
&startGradeScreen($r,'quick');
- my $cangrade=&Apache::lonnet::allowed('mgr');
#
# Pick student
#
@@ -100,6 +140,39 @@ sub real_handler {
my $udom;
my $stdid;
if ($cangrade) {
+ $r->print("
".&mt("Download Multiple")."
".
+ ''."\n"
+ );
+ $r->print("
".&mt("Display Individual")."
");
if ($env{'form.uname'}) { $uname=$env{'form.uname'}; }
if ($env{'form.udom'}) { $udom=$env{'form.udom'}; }
if ($env{'form.id'}) { $stdid=$env{'form.id'}; }
@@ -117,8 +190,8 @@ sub real_handler {
$r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
,''
,' '
- ,$chooseopt).'
'.
- '');
+ ,$chooseopt).
+ ' ');
if (($uname) && ($udom)) {
$r->print(''.&mt('Full Name: [_1]',&Apache::loncommon::plainname($uname,$udom)).'
');
}
@@ -141,6 +214,35 @@ sub real_handler {
}
+sub getStudentCatGrade {
+ my ($uname,$udom,%categories)=@_;
+ my ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=
+ &getData(1,$uname,$udom);
+ return &output_category_table(undef,0,$navmap,0,%categories);
+}
+
+sub getAllStudentData {
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+
+ my %categories=&Apache::lonnet::dump('grading_categories',$cdom,$cnum);
+
+ my $classlist = &Apache::loncoursedata::get_classlist();
+
+ my $statusidx = &Apache::loncoursedata::CL_STATUS();
+ my $usernameidx = &Apache::loncoursedata::CL_SNAME();
+ my $domainidx = &Apache::loncoursedata::CL_SDOM();
+ my $fullnameidx = &Apache::loncoursedata::CL_FULLNAME();
+
+ foreach my $key (keys(%{$classlist})) {
+ my $student = $classlist->{$key};
+ my $perc=&getStudentCatGrade($classlist->{$student}->[$usernameidx],
+ $classlist->{$student}->[$domainidx],
+ %categories);
+ }
+}
+
+
sub startGradeScreen {
my ($r,$mode)=@_;
@@ -192,7 +294,7 @@ sub startGradeScreen {
if ($env{'form.symb'}) {
$r->print("\n".' '.
+ '&command=gradingmenu"> '.
&mt('Problem Grading').' ');
}
@@ -206,6 +308,68 @@ sub endGradeScreen {
$r->print(''.&Apache::loncommon::end_page());
}
+# -----------
+
+
+sub excel_cleanup {
+ undef ($excel_sheet);
+ undef ($excel_workbook);
+ undef ($filename);
+ undef ($format);
+}
+
+
+sub excel_initialize {
+ my ($r) = @_;
+
+ &excel_cleanup();
+
+ # Create sheet
+ ($excel_workbook,$filename,$format)=
+ &Apache::loncommon::create_workbook($r);
+ return if (! defined($excel_workbook));
+ #
+ # Add a worksheet
+ my $sheetname = $env{'course.'.$env{'request.course.id'}.'.description'};
+ $sheetname = &Apache::loncommon::clean_excel_name($sheetname);
+ $excel_sheet = $excel_workbook->addworksheet($sheetname);
+ #
+ # Put the course description in the header
+ $excel_sheet->write($header_row,$cols_output++,
+ $env{'course.'.$env{'request.course.id'}.'.description'},
+ $format->{'h1'});
+}
+
+sub excel_finish {
+ my ($r) = @_;
+ if ($request_aborted || ! defined($excel_sheet)) {
+ &excel_cleanup();
+ return;
+ }
+ #
+ # Write the excel file
+ $excel_workbook->close();
+ #
+ # Close the progress window
+ &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
+ #
+ # Tell the user where to get their excel file
+ $r->print('
'.
+ ''.&mt('Your Excel spreadsheet').''."\n");
+ $r->rflush();
+ &excel_cleanup();
+ return;
+}
+
+
+#
+# CSV data
+#
+# -----------
+
+#
+# Go through the complete course and collect data
+#
sub getData {
@@ -472,7 +636,7 @@ sub outputCategories {
&Apache::lonnet::put('grading_categories',\%categories,$cdom,$cnum);
}
# new categories loaded now
- &output_category_table($r,$cangrade,$navmap,%categories);
+ &output_category_table($r,$cangrade,$navmap,1,%categories);
#
if ($cangrade) {
$r->print(&Apache::loncommon::resourcebrowser_javascript().
@@ -482,40 +646,6 @@ sub outputCategories {
''.
'');
}
-#
-# Debug
-#
-# my %data=&dumpdata($navmap);
-# foreach (keys(%data)) {
-# $r->print("\n
".$_.'='.$data{$_});
-# }
-# my @debugarray=('5:1','4:3','1:1','5:5','6:7');
-# $r->print("Array: ".join(',',@debugarray).'
');
-# $r->print("0,0,0: ".join(',',&drop(0,0,0,@debugarray)).'
');
-# $r->print("1,0,0: ".join(',',&drop(1,0,0,@debugarray)).'
');
-# $r->print("0,1,0: ".join(',',&drop(0,1,0,@debugarray)).'
');
-# $r->print("1,1,0: ".join(',',&drop(1,1,0,@debugarray)).'
');
-#
-# $r->print("0,0,2: ".join(',',&drop(0,0,2,@debugarray)).'
');
-# $r->print("1,0,2: ".join(',',&drop(1,0,2,@debugarray)).'
');
-# $r->print("0,1,2: ".join(',',&drop(0,1,2,@debugarray)).'
');
-# $r->print("1,1,2: ".join(',',&drop(1,1,2,@debugarray)).'
');
-#
-# $r->print("0,0,4: ".join(',',&drop(0,0,4,@debugarray)).'
');
-# $r->print("1,0,4: ".join(',',&drop(1,0,4,@debugarray)).'
');
-# $r->print("0,1,4: ".join(',',&drop(0,1,4,@debugarray)).'
');
-# $r->print("1,1,4: ".join(',',&drop(1,1,4,@debugarray)).'
');
-#
-# $r->print("0,0,5: ".join(',',&drop(0,0,5,@debugarray)).'
');
-# $r->print("1,0,5: ".join(',',&drop(1,0,5,@debugarray)).'
');
-# $r->print("0,1,5: ".join(',',&drop(0,1,5,@debugarray)).'
');
-# $r->print("1,1,5: ".join(',',&drop(1,1,5,@debugarray)).'
');
-#
-# $r->print("0,0,7: ".join(',',&drop(0,0,7,@debugarray)).'
');
-# $r->print("1,0,7: ".join(',',&drop(1,0,7,@debugarray)).'
');
-# $r->print("0,1,7: ".join(',',&drop(0,1,7,@debugarray)).'
');
-# $r->print("1,1,7: ".join(',',&drop(1,1,7,@debugarray)).'
');
-
}
#
@@ -598,21 +728,23 @@ sub process_category_edits {
#
sub output_category_table {
- my ($r,$cangrade,$navmaps,%categories)=@_;
+ my ($r,$cangrade,$navmaps,$output,%categories)=@_;
my $totalweight=0;
my $totalpoints=0;
- $r->print(&Apache::loncommon::start_data_table());
+ if ($output) {
+ $r->print(&Apache::loncommon::start_data_table());
#
- &output_category_table_header($r,$cangrade);
+ &output_category_table_header($r,$cangrade);
+ }
#
my @order=split(/\,/,$categories{'order'});
#
my %performance=&dumpdata($navmaps);
my $maxpos=$#order;
for (my $i=0;$i<=$maxpos;$i++) {
- my ($correct,$possible,$type,$weight)=&output_and_calc_category($r,$cangrade,$navmaps,$order[$i],$i,$maxpos,\%performance,1,%categories);
+ my ($correct,$possible,$type,$weight)=&output_and_calc_category($r,$cangrade,$navmaps,$order[$i],$i,$maxpos,\%performance,$output,%categories);
unless ($possible) { next; }
$totalpoints+=$weight*$correct/$possible;
$totalweight+=$weight;
@@ -621,9 +753,10 @@ sub output_category_table {
my $perc=0;
if ($totalweight) { $perc=100.*$totalpoints/$totalweight; }
- &bottom_line_category($r,$cangrade,$perc);
-#
- $r->print(&Apache::loncommon::end_data_table());
+ if ($output) {
+ &bottom_line_category($r,$cangrade,$perc);
+ $r->print(&Apache::loncommon::end_data_table());
+ }
return $perc;
}
@@ -649,14 +782,15 @@ sub output_category_table_header {
sub output_and_calc_category {
my ($r,$cangrade,$navmaps,$id,$currentpos,$maxpos,$performance,$output,%categories)=@_;
+
+ if ($output) { $r->print("\n".&Apache::loncommon::start_data_table_row()); }
- my $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
- my %lt=&Apache::lonlocal::texthash(
+ if ($output && $cangrade) {
+ my $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
+ my %lt=&Apache::lonlocal::texthash(
'up' => 'Move Up',
'dw' => 'Move Down');
- if ($output) { $r->print("\n".&Apache::loncommon::start_data_table_row()); }
- if ($output && $cangrade) {
$r->print(<