# # $Id: classcalc.pm,v 1.23 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/ # # The LearningOnline Network with CAPA # Spreadsheet/Grades Display Handler # # POD required stuff: =head1 NAME classcalc =head1 SYNOPSIS =head1 DESCRIPTION =over 4 =cut ################################################### ### CourseSheet ### ################################################### package Apache::classcalc; use strict; use warnings FATAL=>'all'; no warnings 'uninitialized'; use Apache::Constants qw(:common :http); use Apache::loncoursedata(); use Apache::lonhtmlcommon(); use Apache::Spreadsheet; use Apache::studentcalc; use Apache::lonstatistics(); use HTML::Entities(); use Spreadsheet::WriteExcel; use Apache::lonnet; use Time::HiRes; use Apache::lonlocal; @Apache::classcalc::ISA = ('Apache::Spreadsheet'); ## ## Package variable ## my @Students; sub initialize { &Apache::lonstatistics::clear_classlist_variables(); @Students = &Apache::lonstatistics::get_students(); return; } sub clear_package { undef(@Students); &Apache::studentcalc::clear_package(); } sub html_header { my $self = shift; my ($toprow,$bottomrow); &Apache::lonstatistics::clear_classlist_variables(); foreach (['Sections',&Apache::lonstatistics::SectionSelect('Section','multpile',3)], ['Enrollment Status',&Apache::lonhtmlcommon::StatusOptions(undef,undef,3)], ['Output Format',$self->output_selector()]) { my ($name,$selector) = @{$_}; $toprow .= ''.&mt($name).''; $bottomrow .= ''.$selector.''; } my $status .= ''.&mt('Status: [_1]', '' ).''; return "

\n\n". "".$toprow."\n". "".$bottomrow."\n". "
\n".$status."\n". "

"; } sub get_title { my $self = shift; # Section info should be included my @title = ($self->{'coursedesc'}, &Apache::lonlocal::locallocaltime(time) ); return @title; } sub get_html_title { my $self = shift; my ($classcalc_title,$time) = $self->get_title(); my $title = '

'.$classcalc_title."

\n".'

'.$time."

\n"; return $title; } sub parent_link { return ''; } sub outsheet_html { my $self = shift; my ($r) = @_; #################################### # Report any calculation errors # #################################### $r->print($self->html_report_error()); ################################### # Determine table structure ################################### my $importcolor = '#88FF88'; my $exportcolor = '#BBBBFF'; my $num_uneditable = 26; my $num_left = 52-$num_uneditable; # my %header=&Apache::lonlocal::texthash( 'course' => 'Course', 'import' => 'Import', 'calculations' => 'Calculations', 'student' => 'Student', 'status' => 'Status', 'username' => 'Username', 'domain' => 'Domain', 'section' => 'Section', 'row' => 'Row', ); my $tableheader =<<"END";

END my $label_num = 0; foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){ if ($label_num<$num_uneditable) { $tableheader.='"; $label_num++; } $tableheader.="\n"; # $r->print($tableheader); # # Print out template row $r->print(''. $self->html_template_row($num_uneditable,$importcolor). "\n"); # # Print out summary/export row $r->print(''. $self->html_export_row($exportcolor)."\n"); # # Prepare to output rows $tableheader =<<"END";

$header{'course'} $header{'import'} $header{'calculations'}
'; } else { $tableheader.=''; } $tableheader.="$_
'.&mt('Template').' 
'.&mt('Summary').'0
END foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){ if ($label_num<$num_uneditable) { $tableheader.='"; } # my $num_output = 0; foreach my $student (@Students) { if ($num_output++ % 50 == 0) { $r->print("
$header{'row'} $header{'student'} $header{'username'} $header{'domain'} $header{'section'} $header{'status'}'; } else { $tableheader.=''; } $tableheader.="$_
\n".$tableheader); } my $rownum = $self->get_row_number_from_key ($student->{'username'}.':'.$student->{'domain'}); my $link = ''; $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); $r->print(''.''.$rownum.''. ''.$student->{'fullname'}.''. ''.$link.$student->{'username'}.''. ''.$student->{'domain'} .''. ''.$student->{'section'} .''. ''.$student->{'status'} .''. $self->html_row($num_uneditable,$rownum,$exportcolor, $importcolor). "\n"); } $r->print("

\n"); return; } sub excel_rows { # writes the meat of the spreadsheet to an excel worksheet. Called # by Spreadsheet::outsheet_excel; my $self = shift; my ($connection,$worksheet,$cols_output,$rows_output,$format) = @_; # # Write a header row $cols_output = 0; foreach my $value ('Fullname','Username','Domain','Section','Status','ID') { $worksheet->write($rows_output,$cols_output++,&mt($value),$format->{'h4'}); } $rows_output++; # # Write each students row foreach my $student (@Students) { $cols_output = 0; my $rownum = $self->get_row_number_from_key ($student->{'username'}.':'.$student->{'domain'}); $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); my @studentdata = ($student->{'fullname'}, $student->{'username'}, $student->{'domain'}, $student->{'section'}, $student->{'status'}, $student->{'id'}); $self->excel_output_row($worksheet,$rownum,$rows_output++, @studentdata); } return; } sub csv_rows { # writes the meat of the spreadsheet to an excel worksheet. Called # by Spreadsheet::outsheet_excel; my $self = shift; my ($connection,$filehandle) = @_; # # Write a header row $self->csv_output_row($filehandle,undef, (&mt('Fullname'),&mt('Username'),&mt('Domain'),&mt('Section'),&mt('Status'),&mt('ID'))); # # Write each students row foreach my $student (@Students) { my $rownum = $self->get_row_number_from_key ($student->{'username'}.':'.$student->{'domain'}); $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); my @studentdata = ($student->{'fullname'}, $student->{'username'}, $student->{'domain'}, $student->{'section'}, $student->{'status'}, $student->{'id'}); $self->csv_output_row($filehandle,$rownum,@studentdata); } return; } sub output_options { my $self = shift(); return ({value => 'htmlclasslist', description => 'Student Sheet Links'}, {value => 'html', description => 'HTML'}, {value => 'excel', description => 'Excel'}, {value => 'csv', description => 'Comma Separated Values'}, # {value => 'xml', # description => 'XML'}, ); } sub outsheet_recursive_excel { my $self = shift; my ($r) = @_; } sub outsheet_htmlclasslist { my $self = shift; my ($r) = @_; # # Determine if we should output expire caches links... my $show_expire_link = 0; if (exists($env{'user.role.dc./'.$env{'request.role.domain'}.'/'})){ $show_expire_link = 1; } # if ($show_expire_link) { $r->print(''. &mt('Expire all student spreadsheets').''.$/); } # $r->print('

'. &mt('Click on a student to be taken to their spreadsheet'). '

'); # my %header=&Apache::lonlocal::texthash( 'student' => 'Student', 'status' => 'Status', 'username' => 'Username', 'domain' => 'Domain', 'section' => 'Section', ); # # Prepare to output rows my $tableheader =<<"END";

END if ($show_expire_link) { $tableheader.= ''; } $tableheader.= "\n"; # my $num_output = 0; foreach my $student (@Students) { if ($num_output++ % 50 == 0) { $r->print("
$header{'student'} $header{'username'} $header{'domain'} $header{'section'} $header{'status'} 
\n".$tableheader); } my $link = ''; $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); $r->print(''. ''.$num_output.''. ''.$link.$student->{'fullname'}.''. ''.$link.$student->{'username'}.''. ''.$student->{'domain'} .''. ''.$student->{'section'} .''. ''.$student->{'status'} .''); if ($show_expire_link) { $r->print(''. 'Expire Record'.$/); } $r->print("\n"); } $r->print("

\n"); return; } sub update_status { my ($r,$message) = @_; $r->print(''); $r->rflush(); return; } sub compute { my $self = shift; my ($r) = @_; my $connection = $r->connection(); if ($connection->aborted()) { $self->cleanup(); return; } $self->initialize_safe_space(); my %c = $self->constants(); my %f = $self->formulas(); &update_status($r,'Initializing Course Structure'); &Apache::studentcalc::initialize_package(); my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin ($r,&mt('Spreadsheet Computation Status'), &mt('Spreadsheet Computation'), scalar(@Students),'inline',undef, 'sheet','spreadsheet_status'); &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, &mt('Processing first student')); foreach my $student (@Students) { if ($connection->aborted()) { $self->cleanup(); return; } my $sname = $student->{'username'}.':'.$student->{'domain'}; my $studentsheet = Apache::studentcalc->new ($student->{'username'},$student->{'domain'},undef); if ($connection->aborted()) { $self->cleanup(); return; } my @exportdata = $studentsheet->export_data($r); if ($studentsheet->badcalc()) { $self->set_calcerror($sname.' : '. $studentsheet->calcerror()); } if ($connection->aborted()) { $self->cleanup(); return; } my $rownum = $self->get_row_number_from_key($sname); $f{'A'.$rownum} = $sname; $self->{'row_source'}->{$rownum} = $sname; $c{'A'.$rownum} = shift(@exportdata); foreach (split(//,'BCDEFGHIJKLMNOPQRSTUVWXYZ')) { my $cell = $_.$rownum; my $data = shift(@exportdata); if (defined($data)) { $f{$cell} = 'import'; $c{$cell} = $data; } } &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state, 'last student'); } &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); &update_status($r,'Done computing student sheets'); $r->rflush(); $self->constants(\%c); $self->formulas(\%f); $self->calcsheet(); $self->save() if ($self->need_to_save()); &update_status($r,'Done!'); } 1; __END__