version 1.137, 2002/11/08 20:18:29
|
version 1.148, 2002/11/21 19:50:49
|
Line 53 built-in functions.
|
Line 53 built-in functions.
|
package Apache::lonspreadsheet; |
package Apache::lonspreadsheet; |
|
|
use strict; |
use strict; |
|
use Apache::Constants qw(:common :http); |
|
use Apache::lonnet; |
|
use Apache::lonhtmlcommon; |
|
use Apache::loncoursedata; |
|
use Apache::File(); |
use Safe; |
use Safe; |
use Safe::Hole; |
use Safe::Hole; |
use Opcode; |
use Opcode; |
use Apache::lonnet; |
|
use Apache::Constants qw(:common :http); |
|
use GDBM_File; |
use GDBM_File; |
use HTML::TokeParser; |
use HTML::TokeParser; |
use Apache::lonhtmlcommon; |
|
use Apache::loncoursedata; |
|
use Apache::File(); |
|
use Spreadsheet::WriteExcel; |
use Spreadsheet::WriteExcel; |
|
|
# |
# |
Line 1086 sub geterrorlog {
|
Line 1086 sub geterrorlog {
|
return ${$sheet->{'safe'}->varglob('errorlog')}; |
return ${$sheet->{'safe'}->varglob('errorlog')}; |
} |
} |
|
|
|
sub gettitle { |
|
my $sheet = shift; |
|
if ($sheet->{'sheettype'} eq 'classcalc') { |
|
return $sheet->{'coursedesc'}; |
|
} elsif ($sheet->{'sheettype'} eq 'studentcalc') { |
|
return 'Grades for '.$sheet->{'uname'}.'@'.$sheet->{'udom'}; |
|
} elsif ($sheet->{'sheettype'} eq 'assesscalc') { |
|
if (($sheet->{'usymb'} eq '_feedback') || |
|
($sheet->{'usymb'} eq '_evaluation') || |
|
($sheet->{'usymb'} eq '_discussion') || |
|
($sheet->{'usymb'} eq '_tutoring')) { |
|
my $title = $sheet->{'usymb'}; |
|
$title =~ s/^_//; |
|
$title = ucfirst($title); |
|
return $title; |
|
} |
|
return if (! defined($sheet->{'mapid'}) || |
|
$sheet->{'mapid'} !~ /^\d+$/); |
|
my $mapid = $sheet->{'mapid'}; |
|
return if (! defined($sheet->{'resid'}) || |
|
$sheet->{'resid'} !~ /^\d+$/); |
|
my $resid = $sheet->{'resid'}; |
|
my %course_db; |
|
tie(%course_db,'GDBM_File',$sheet->{'coursefilename'}.'.db', |
|
&GDBM_READER(),0640); |
|
return if (! tied(%course_db)); |
|
my $key = 'title_'.$mapid.'.'.$resid; |
|
my $title = ''; |
|
if (exists($course_db{$key})) { |
|
$title = $course_db{$key}; |
|
} else { |
|
$title = $sheet->{'usymb'}; |
|
} |
|
untie (%course_db); |
|
return $title; |
|
} |
|
} |
|
|
# ----------------------------------------------------- Get value of $f{'A'.$n} |
# ----------------------------------------------------- Get value of $f{'A'.$n} |
sub getfa { |
sub getfa { |
my $sheet = shift; |
my $sheet = shift; |
Line 1111 sub exportdata {
|
Line 1149 sub exportdata {
|
|
|
|
|
sub update_student_sheet{ |
sub update_student_sheet{ |
my $sheet = shift; |
my ($sheet,$r,$c) = @_; |
# Load in the studentcalc sheet |
# Load in the studentcalc sheet |
&readsheet($sheet,'default_studentcalc'); |
&readsheet($sheet,'default_studentcalc'); |
# Determine the structure (contained assessments, etc) of the sheet |
# Determine the structure (contained assessments, etc) of the sheet |
Line 1119 sub update_student_sheet{
|
Line 1157 sub update_student_sheet{
|
# Load in the cached sheets for this student |
# Load in the cached sheets for this student |
&cachedssheets($sheet); |
&cachedssheets($sheet); |
# Load in the (possibly cached) data from the assessment sheets |
# Load in the (possibly cached) data from the assessment sheets |
&loadstudent($sheet); |
&loadstudent($sheet,$r,$c); |
# Compute the sheet |
# Compute the sheet |
&calcsheet($sheet); |
&calcsheet($sheet); |
} |
} |
Line 1148 sub get_row {
|
Line 1186 sub get_row {
|
######################################################################## |
######################################################################## |
sub sort_indicies { |
sub sort_indicies { |
my $sheet = shift; |
my $sheet = shift; |
# |
|
# Sort the rows in some manner |
|
# |
|
my @sortby=(); |
|
my @sortidx=(); |
my @sortidx=(); |
for (my $row=1;$row<=$sheet->{'maxrow'};$row++) { |
# |
push (@sortby, $sheet->{'safe'}->reval('$f{"A'.$row.'"}')); |
if ($sheet->{'sheettype'} eq 'classcalc') { |
push (@sortidx, $row); |
my @sortby=(undef); |
|
# Skip row 0 |
|
for (my $row=1;$row<=$sheet->{'maxrow'};$row++) { |
|
my (undef,$sname,$sdom,$fullname,$section,$id) = |
|
split(':',$sheet->{'rowlabel'}->{$sheet->{'f'}->{'A'.$row}}); |
|
push (@sortby, lc($fullname)); |
|
push (@sortidx, $row); |
|
} |
|
@sortidx = sort { $sortby[$a] cmp $sortby[$b]; } @sortidx; |
|
} elsif ($sheet->{'sheettype'} eq 'studentcalc') { |
|
my @sortby1=(undef); |
|
my @sortby2=(undef); |
|
# Skip row 0 |
|
for (my $row=1;$row<=$sheet->{'maxrow'};$row++) { |
|
my (undef,$symb,$uname,$udom,$mapid,$resid,$title) = |
|
split(':',$sheet->{'rowlabel'}->{$sheet->{'f'}->{'A'.$row}}); |
|
$symb = &Apache::lonnet::unescape($symb); |
|
my ($sequence) = ($symb =~ /\/([^\/]*\.sequence)/); |
|
if ($sequence eq '') { |
|
$sequence = $symb; |
|
} |
|
push (@sortby1, $sequence); |
|
push (@sortby2, $title); |
|
push (@sortidx, $row); |
|
} |
|
@sortidx = sort { $sortby1[$a] cmp $sortby1[$b] || |
|
$sortby2[$a] cmp $sortby2[$b] } @sortidx; |
|
} else { |
|
my @sortby=(undef); |
|
# Skip row 0 |
|
for (my $row=1;$row<=$sheet->{'maxrow'};$row++) { |
|
push (@sortby, $sheet->{'safe'}->reval('$f{"A'.$row.'"}')); |
|
push (@sortidx, $row); |
|
} |
|
@sortidx = sort { $sortby[$a] cmp $sortby[$b]; } @sortidx; |
} |
} |
@sortidx=sort { lc($sortby[$a]) cmp lc($sortby[$b]); } @sortidx; |
|
return @sortidx; |
return @sortidx; |
} |
} |
|
|
Line 1190 sub html_editable_cell {
|
Line 1257 sub html_editable_cell {
|
if ($value =~ /^\s*$/ ) { |
if ($value =~ /^\s*$/ ) { |
$value = '<font color="'.$bgcolor.'">#</font>'; |
$value = '<font color="'.$bgcolor.'">#</font>'; |
} |
} |
|
$formula =~ s/\n/\\n/gs; |
$result .= '<a href="javascript:celledit(\''. |
$result .= '<a href="javascript:celledit(\''. |
$name.'\',\''.$formula.'\');">'.$value.'</a>'; |
$name.'\',\''.$formula.'\');">'.$value.'</a>'; |
return $result; |
return $result; |
Line 1267 END
|
Line 1335 END
|
# Print out summary/export row |
# Print out summary/export row |
#################################### |
#################################### |
my ($rowlabel,@rowdata) = &get_row($sheet,'0'); |
my ($rowlabel,@rowdata) = &get_row($sheet,'0'); |
my $rowcount = 0; |
|
$row_html = '<tr><td>'.&format_html_rowlabel($rowlabel).'</td>'; |
$row_html = '<tr><td>'.&format_html_rowlabel($rowlabel).'</td>'; |
$num_cols_output = 0; |
$num_cols_output = 0; |
foreach my $cell (@rowdata) { |
foreach my $cell (@rowdata) { |
Line 1293 END
|
Line 1360 END
|
foreach my $rownum (@Rows) { |
foreach my $rownum (@Rows) { |
my ($rowlabel,@rowdata) = &get_row($sheet,$rownum); |
my ($rowlabel,@rowdata) = &get_row($sheet,$rownum); |
next if ($rowlabel =~ /^\s*$/); |
next if ($rowlabel =~ /^\s*$/); |
|
next if (($sheet->{'sheettype'} eq 'assesscalc') && |
|
(! $ENV{'form.showall'}) && |
|
($rowdata[0]->{'value'} =~ /^\s*$/)); |
|
if (! $ENV{'form.showall'} && |
|
$sheet->{'sheettype'} =~ /^(studentcalc|classcalc)$/) { |
|
my $row_is_empty = 1; |
|
foreach my $cell (@rowdata) { |
|
if ($cell->{'value'} !~ /^\s*$/) { |
|
$row_is_empty = 0; |
|
last; |
|
} |
|
} |
|
next if ($row_is_empty); |
|
} |
# |
# |
my $defaultbg='#E0FF'; |
my $defaultbg='#E0FF'; |
# |
# |
Line 1449 A link to the spreadsheet will be availa
|
Line 1530 A link to the spreadsheet will be availa
|
END |
END |
$r->rflush(); |
$r->rflush(); |
my $starttime = time; |
my $starttime = time; |
foreach (keys(%f)) { |
foreach my $rownum (&sort_indicies($sheet)) { |
next if ($_!~/^A(\d+)/ || $1 == 0 || ($f{$_}=~/^[!~-]/)); |
|
$count++; |
$count++; |
my ($sname,$sdom) = split(':',$f{$_}); |
my ($sname,$sdom) = split(':',$f{'A'.$rownum}); |
my $student_excel_worksheet=$workbook->addworksheet($sname.'@'.$sdom); |
my $student_excel_worksheet=$workbook->addworksheet($sname.'@'.$sdom); |
# Create a new spreadsheet |
# Create a new spreadsheet |
my $studentsheet = &makenewsheet($sname,$sdom,'studentcalc',undef); |
my $studentsheet = &makenewsheet($sname,$sdom,'studentcalc',undef); |
# Read in the spreadsheet definition |
# Read in the spreadsheet definition |
&update_student_sheet($studentsheet); |
&update_student_sheet($studentsheet,$r,$c); |
# Stuff the sheet into excel |
# Stuff the sheet into excel |
&export_sheet_as_excel($studentsheet,$student_excel_worksheet); |
&export_sheet_as_excel($studentsheet,$student_excel_worksheet); |
my $totaltime = int((time - $starttime) / $count * $sheet->{'maxrow'}); |
my $totaltime = int((time - $starttime) / $count * $sheet->{'maxrow'}); |
Line 1542 sub create_excel_spreadsheet {
|
Line 1622 sub create_excel_spreadsheet {
|
sub export_sheet_as_excel { |
sub export_sheet_as_excel { |
my $sheet = shift; |
my $sheet = shift; |
my $worksheet = shift; |
my $worksheet = shift; |
|
# |
|
my $rows_output = 0; |
|
my $cols_output = 0; |
|
#################################### |
|
# Write an identifying row # |
|
#################################### |
|
my @Headerinfo = ($sheet->{'coursedesc'}); |
|
my $title = &gettitle($sheet); |
|
$cols_output = 0; |
|
if (defined($title)) { |
|
$worksheet->write($rows_output++,$cols_output++,$title); |
|
} |
|
#################################### |
|
# Write the summary/export row # |
|
#################################### |
|
my ($rowlabel,@rowdata) = &get_row($sheet,'0'); |
|
my $label = &format_excel_rowlabel($rowlabel); |
|
$cols_output = 0; |
|
$worksheet->write($rows_output,$cols_output++,$label); |
|
foreach my $cell (@rowdata) { |
|
$worksheet->write($rows_output,$cols_output++,$cell->{'value'}); |
|
} |
|
$rows_output+= 2; # Skip a row, just for fun |
#################################### |
#################################### |
# Prepare to output rows |
# Prepare to output rows |
#################################### |
#################################### |
my @Rows = &sort_indicies($sheet); |
my @Rows = &sort_indicies($sheet); |
# |
# |
# Loop through the rows and output them one at a time |
# Loop through the rows and output them one at a time |
my $rows_output=0; |
|
foreach my $rownum (@Rows) { |
foreach my $rownum (@Rows) { |
my ($rowlabel,@rowdata) = &get_row($sheet,$rownum); |
my ($rowlabel,@rowdata) = &get_row($sheet,$rownum); |
next if ($rowlabel =~ /^\s*$/); |
next if ($rowlabel =~ /^[\s]*$/); |
my $cols_output = 0; |
$cols_output = 0; |
my $label = &format_excel_rowlabel($rowlabel); |
my $label = &format_excel_rowlabel($rowlabel); |
|
if ( ! $ENV{'form.showall'} && |
|
$sheet->{'sheettype'} =~ /^(studentcalc|classcalc)$/) { |
|
my $row_is_empty = 1; |
|
foreach my $cell (@rowdata) { |
|
if ($cell->{'value'} !~ /^\s*$/) { |
|
$row_is_empty = 0; |
|
last; |
|
} |
|
} |
|
next if ($row_is_empty); |
|
} |
$worksheet->write($rows_output,$cols_output++,$label); |
$worksheet->write($rows_output,$cols_output++,$label); |
if (ref($label)) { |
if (ref($label)) { |
$cols_output = (scalar(@$label)); |
$cols_output = (scalar(@$label)); |
} |
} |
foreach my $cell (@rowdata) { |
foreach my $cell (@rowdata) { |
$worksheet->write($rows_output,$cols_output++, |
$worksheet->write($rows_output,$cols_output++,$cell->{'value'}); |
$cell->{'value'}); |
|
} |
} |
$rows_output++; |
$rows_output++; |
} |
} |
Line 1581 sub outsheet_xml {
|
Line 1693 sub outsheet_xml {
|
## Outsheet - calls other outsheet_* functions |
## Outsheet - calls other outsheet_* functions |
## |
## |
sub outsheet { |
sub outsheet { |
my ($r,$sheet)=@_; |
my ($sheet,$r)=@_; |
if (! exists($ENV{'form.output'})) { |
if (! exists($ENV{'form.output'})) { |
$ENV{'form.output'} = 'HTML'; |
$ENV{'form.output'} = 'HTML'; |
} |
} |
Line 1693 sub readsheet {
|
Line 1805 sub readsheet {
|
if ($fh=Apache::File->new($includedir.'/'.$dfn)) { |
if ($fh=Apache::File->new($includedir.'/'.$dfn)) { |
$sheetxml=join('',<$fh>); |
$sheetxml=join('',<$fh>); |
} else { |
} else { |
$sheetxml='<field row="0" col="A">"Error"</field>'; |
# $sheetxml='<field row="0" col="A">"Error"</field>'; |
|
$sheetxml='<field row="0" col="A"></field>'; |
} |
} |
%f=%{&parse_sheet(\$sheetxml)}; |
%f=%{&parse_sheet(\$sheetxml)}; |
} elsif($fn=~/\/*\.spreadsheet$/) { |
} elsif($fn=~/\/*\.spreadsheet$/) { |
Line 1729 sub makenewsheet {
|
Line 1842 sub makenewsheet {
|
$sheet->{'udom'} = $udom; |
$sheet->{'udom'} = $udom; |
$sheet->{'sheettype'} = $stype; |
$sheet->{'sheettype'} = $stype; |
$sheet->{'usymb'} = $usymb; |
$sheet->{'usymb'} = $usymb; |
|
$sheet->{'mapid'} = $ENV{'form.mapid'}; |
|
$sheet->{'resid'} = $ENV{'form.resid'}; |
$sheet->{'cid'} = $ENV{'request.course.id'}; |
$sheet->{'cid'} = $ENV{'request.course.id'}; |
$sheet->{'csec'} = $Section{$uname.':'.$udom}; |
$sheet->{'csec'} = $Section{$uname.':'.$udom}; |
$sheet->{'coursefilename'} = $ENV{'request.course.fn'}; |
$sheet->{'coursefilename'} = $ENV{'request.course.fn'}; |
Line 1736 sub makenewsheet {
|
Line 1851 sub makenewsheet {
|
$sheet->{'cdom'} = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
$sheet->{'cdom'} = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
$sheet->{'chome'} = $ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
$sheet->{'chome'} = $ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
$sheet->{'coursedesc'} = $ENV{'course.'.$ENV{'request.course.id'}. |
$sheet->{'coursedesc'} = $ENV{'course.'.$ENV{'request.course.id'}. |
'description'}; |
'.description'}; |
$sheet->{'uhome'} = &Apache::lonnet::homeserver($uname,$udom); |
$sheet->{'uhome'} = &Apache::lonnet::homeserver($uname,$udom); |
# |
# |
# |
# |
Line 1942 sub format_html_rowlabel {
|
Line 2057 sub format_html_rowlabel {
|
my ($type,$labeldata) = split(':',$rowlabel,2); |
my ($type,$labeldata) = split(':',$rowlabel,2); |
my $result = ''; |
my $result = ''; |
if ($type eq 'symb') { |
if ($type eq 'symb') { |
my ($symb,$uname,$udom,$title) = split(':',$labeldata); |
my ($symb,$uname,$udom,$mapid,$resid,$title) = split(':',$labeldata); |
$symb = &Apache::lonnet::unescape($symb); |
$symb = &Apache::lonnet::unescape($symb); |
$result = '<a href="/adm/assesscalc?usymb='.$symb. |
$result = '<a href="/adm/assesscalc?usymb='.$symb. |
'&uname='.$uname.'&udom='.$udom.'">'.$title.'</a>'; |
'&uname='.$uname.'&udom='.$udom. |
|
'&mapid='.$mapid.'&resid='.$resid.'">'.$title.'</a>'; |
} elsif ($type eq 'student') { |
} elsif ($type eq 'student') { |
my ($sname,$sdom,$fullname,$section,$id) = split(':',$labeldata); |
my ($sname,$sdom,$fullname,$section,$id) = split(':',$labeldata); |
|
if ($fullname =~ /^\s*$/) { |
|
$fullname = $sname.'@'.$sdom; |
|
} |
$result ='<a href="/adm/studentcalc?uname='.$sname. |
$result ='<a href="/adm/studentcalc?uname='.$sname. |
'&udom='.$sdom.'">'; |
'&udom='.$sdom.'">'; |
$result.=$section.' '.$id." ".$fullname.'</a>'; |
$result.=$section.' '.$id." ".$fullname.'</a>'; |
Line 1965 sub format_csv_rowlabel {
|
Line 2084 sub format_csv_rowlabel {
|
my ($type,$labeldata) = split(':',$rowlabel,2); |
my ($type,$labeldata) = split(':',$rowlabel,2); |
my $result = ''; |
my $result = ''; |
if ($type eq 'symb') { |
if ($type eq 'symb') { |
my ($symb,$uname,$udom,$title) = split(':',$labeldata); |
my ($symb,$uname,$udom,$mapid,$resid,$title) = split(':',$labeldata); |
$symb = &Apache::lonnet::unescape($symb); |
$symb = &Apache::lonnet::unescape($symb); |
$result = $title; |
$result = $title; |
} elsif ($type eq 'student') { |
} elsif ($type eq 'student') { |
Line 1986 sub format_excel_rowlabel {
|
Line 2105 sub format_excel_rowlabel {
|
my ($type,$labeldata) = split(':',$rowlabel,2); |
my ($type,$labeldata) = split(':',$rowlabel,2); |
my $result = ''; |
my $result = ''; |
if ($type eq 'symb') { |
if ($type eq 'symb') { |
my ($symb,$uname,$udom,$title) = split(':',$labeldata); |
my ($symb,$uname,$udom,$mapid,$resid,$title) = split(':',$labeldata); |
$symb = &Apache::lonnet::unescape($symb); |
$symb = &Apache::lonnet::unescape($symb); |
$result = $title; |
$result = $title; |
} elsif ($type eq 'student') { |
} elsif ($type eq 'student') { |
Line 2024 sub updateclasssheet {
|
Line 2143 sub updateclasssheet {
|
foreach my $student (keys(%$classlist)) { |
foreach my $student (keys(%$classlist)) { |
my ($studentDomain,$studentName,$end,$start,$id,$studentSection, |
my ($studentDomain,$studentName,$end,$start,$id,$studentSection, |
$fullname,$status) = @{$classlist->{$student}}; |
$fullname,$status) = @{$classlist->{$student}}; |
|
$Section{$studentName.':'.$studentDomain} = $studentSection; |
if ($ENV{'form.Status'} eq $status || $ENV{'form.Status'} eq 'Any') { |
if ($ENV{'form.Status'} eq $status || $ENV{'form.Status'} eq 'Any') { |
$currentlist{$student}=join(':',('student',$studentName, |
$currentlist{$student}=join(':',('student',$studentName, |
$studentDomain,$fullname, |
$studentDomain,$fullname, |
Line 2097 sub get_student_rowlabels {
|
Line 2217 sub get_student_rowlabels {
|
my %assesslist; |
my %assesslist; |
foreach ('Feedback','Evaluation','Tutoring','Discussion') { |
foreach ('Feedback','Evaluation','Tutoring','Discussion') { |
my $symb = '_'.lc($_); |
my $symb = '_'.lc($_); |
$assesslist{$symb} = join(':',('symb',$symb,$uname,$udom,$_)); |
$assesslist{$symb} = join(':',('symb',$symb,$uname,$udom,0,0,$_)); |
} |
} |
# |
# |
while (my ($key,$srcf) = each(%course_db)) { |
while (my ($key,$srcf) = each(%course_db)) { |
Line 2110 sub get_student_rowlabels {
|
Line 2230 sub get_student_rowlabels {
|
&Apache::lonnet::declutter($course_db{'map_id_'.$mapid}). |
&Apache::lonnet::declutter($course_db{'map_id_'.$mapid}). |
'___'.$resid.'___'.&Apache::lonnet::declutter($srcf); |
'___'.$resid.'___'.&Apache::lonnet::declutter($srcf); |
$assesslist{$symb}='symb:'.&Apache::lonnet::escape($symb).':' |
$assesslist{$symb}='symb:'.&Apache::lonnet::escape($symb).':' |
.$uname.':'.$udom.':'.$course_db{'title_'.$id}; |
.$uname.':'.$udom.':'.$mapid.':'.$resid.':'. |
|
$course_db{'title_'.$id}; |
} |
} |
} |
} |
untie(%course_db); |
untie(%course_db); |
Line 2198 sub updatestudentassesssheet {
|
Line 2319 sub updatestudentassesssheet {
|
$sheet->{'maxrow'} = 0; |
$sheet->{'maxrow'} = 0; |
my %existing=(); |
my %existing=(); |
# Now obsolete rows |
# Now obsolete rows |
while (my ($cell, $formula) = each (%f)) { |
foreach my $cell (keys(%f)) { |
|
my $formula = $f{$cell}; |
next if ($cell !~ /^A(\d+)/); |
next if ($cell !~ /^A(\d+)/); |
$sheet->{'maxrow'} = $1 if ($1 > $sheet->{'maxrow'}); |
$sheet->{'maxrow'} = $1 if ($1 > $sheet->{'maxrow'}); |
my ($usy,$ufn)=split(/__&&&\__/,$formula); |
my ($usy,$ufn)=split(/__&&&\__/,$formula); |
Line 2231 sub updatestudentassesssheet {
|
Line 2353 sub updatestudentassesssheet {
|
# ------------------------------------------------ Load data for one assessment |
# ------------------------------------------------ Load data for one assessment |
|
|
sub loadstudent{ |
sub loadstudent{ |
my ($sheet)=@_; |
my ($sheet,$r,$c)=@_; |
my %c=(); |
my %constants=(); |
my %f=&getformulas($sheet); |
my %formulas=&getformulas($sheet); |
$cachedassess=$sheet->{'uname'}.':'.$sheet->{'udom'}; |
$cachedassess=$sheet->{'uname'}.':'.$sheet->{'udom'}; |
# Get ALL the student preformance data |
# Get ALL the student preformance data |
my @tmp = &Apache::lonnet::dump($sheet->{'cid'}, |
my @tmp = &Apache::lonnet::dump($sheet->{'cid'}, |
Line 2246 sub loadstudent{
|
Line 2368 sub loadstudent{
|
undef @tmp; |
undef @tmp; |
# |
# |
my @assessdata=(); |
my @assessdata=(); |
while (my ($cell,$value) = each (%f)) { |
foreach my $cell (keys(%formulas)) { |
|
my $value = $formulas{$cell}; |
|
if(defined($c) && ($c->aborted())) { |
|
last; |
|
} |
next if ($cell !~ /^A(\d+)/); |
next if ($cell !~ /^A(\d+)/); |
my $row=$1; |
my $row=$1; |
next if (($value =~ /^[!~-]/) || ($row==0)); |
next if (($value =~ /^[!~-]/) || ($row==0)); |
my ($usy,$ufn)=split(/__&&&\__/,$value); |
my ($usy,$ufn)=split(/__&&&\__/,$value); |
@assessdata=&exportsheet($sheet,$sheet->{'uname'}, |
@assessdata=&exportsheet($sheet,$sheet->{'uname'}, |
$sheet->{'udom'}, |
$sheet->{'udom'}, |
'assesscalc',$usy,$ufn); |
'assesscalc',$usy,$ufn,$r); |
my $index=0; |
my $index=0; |
foreach ('A','B','C','D','E','F','G','H','I','J','K','L','M', |
foreach my $col ('A','B','C','D','E','F','G','H','I','J','K','L','M', |
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z') { |
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z') { |
if (defined($assessdata[$index])) { |
if (defined($assessdata[$index])) { |
my $col=$_; |
|
if ($assessdata[$index]=~/\D/) { |
if ($assessdata[$index]=~/\D/) { |
$c{$col.$row}="'".$assessdata[$index]."'"; |
$constants{$col.$row}="'".$assessdata[$index]."'"; |
} else { |
} else { |
$c{$col.$row}=$assessdata[$index]; |
$constants{$col.$row}=$assessdata[$index]; |
} |
|
unless ($col eq 'A') { |
|
$f{$col.$row}='import'; |
|
} |
} |
|
$formulas{$col.$row}='import' if ($col ne 'A'); |
} |
} |
$index++; |
$index++; |
} |
} |
} |
} |
$cachedassess=''; |
$cachedassess=''; |
undef %cachedstores; |
undef %cachedstores; |
$sheet->{'f'} = \%f; |
$sheet->{'f'} = \%formulas; |
&setformulas($sheet); |
&setformulas($sheet); |
&setconstants($sheet,\%c); |
&setconstants($sheet,\%constants); |
} |
} |
|
|
# --------------------------------------------------- Load data for one student |
# --------------------------------------------------- Load data for one student |
# |
# |
sub loadcourse { |
sub loadcourse { |
my ($sheet,$r)=@_; |
my ($sheet,$r,$c)=@_; |
# |
# |
my %c=(); |
my %constants=(); |
my %f=&getformulas($sheet); |
my %formulas=&getformulas($sheet); |
# |
# |
my $total=0; |
my $total=0; |
foreach (keys(%f)) { |
foreach (keys(%formulas)) { |
if ($_=~/^A(\d+)/) { |
if ($_=~/^A(\d+)/) { |
unless ($f{$_}=~/^[\!\~\-]/) { $total++; } |
unless ($formulas{$_}=~/^[\!\~\-]/) { $total++; } |
} |
} |
} |
} |
my $now=0; |
my $now=0; |
Line 2306 sub loadcourse {
|
Line 2429 sub loadcourse {
|
</script> |
</script> |
ENDPOP |
ENDPOP |
$r->rflush(); |
$r->rflush(); |
foreach (keys(%f)) { |
foreach (keys(%formulas)) { |
|
if(defined($c) && ($c->aborted())) { |
|
last; |
|
} |
next if ($_!~/^A(\d+)/); |
next if ($_!~/^A(\d+)/); |
my $row=$1; |
my $row=$1; |
next if (($f{$_}=~/^[\!\~\-]/) || ($row==0)); |
next if (($formulas{$_}=~/^[\!\~\-]/) || ($row==0)); |
my ($sname,$sdom) = split(':',$f{$_}); |
my ($sname,$sdom) = split(':',$formulas{$_}); |
my @studentdata=&exportsheet($sheet,$sname,$sdom,'studentcalc'); |
my @studentdata=&exportsheet($sheet,$sname,$sdom,'studentcalc', |
|
undef,undef,$r); |
undef %userrdatas; |
undef %userrdatas; |
$now++; |
$now++; |
$r->print('<script>popwin.document.popremain.remaining.value="'. |
$r->print('<script>popwin.document.popremain.remaining.value="'. |
Line 2325 ENDPOP
|
Line 2452 ENDPOP
|
if (defined($studentdata[$index])) { |
if (defined($studentdata[$index])) { |
my $col=$_; |
my $col=$_; |
if ($studentdata[$index]=~/\D/) { |
if ($studentdata[$index]=~/\D/) { |
$c{$col.$row}="'".$studentdata[$index]."'"; |
$constants{$col.$row}="'".$studentdata[$index]."'"; |
} else { |
} else { |
$c{$col.$row}=$studentdata[$index]; |
$constants{$col.$row}=$studentdata[$index]; |
} |
} |
unless ($col eq 'A') { |
unless ($col eq 'A') { |
$f{$col.$row}='import'; |
$formulas{$col.$row}='import'; |
} |
} |
} |
} |
$index++; |
$index++; |
} |
} |
} |
} |
$sheet->{'f'}=\%f; |
$sheet->{'f'}=\%formulas; |
&setformulas($sheet); |
&setformulas($sheet); |
&setconstants($sheet,\%c); |
&setconstants($sheet,\%constants); |
$r->print('<script>popwin.close()</script>'); |
$r->print('<script>popwin.close()</script>'); |
$r->rflush(); |
$r->rflush(); |
} |
} |
Line 2346 ENDPOP
|
Line 2473 ENDPOP
|
# ------------------------------------------------ Load data for one assessment |
# ------------------------------------------------ Load data for one assessment |
# |
# |
sub loadassessment { |
sub loadassessment { |
my ($sheet)=@_; |
my ($sheet,$r,$c)=@_; |
|
|
my $uhome = $sheet->{'uhome'}; |
my $uhome = $sheet->{'uhome'}; |
my $uname = $sheet->{'uname'}; |
my $uname = $sheet->{'uname'}; |
Line 2510 sub updatesheet {
|
Line 2637 sub updatesheet {
|
|
|
sub loadrows { |
sub loadrows { |
my ($sheet,$r)=@_; |
my ($sheet,$r)=@_; |
|
my $c = $r->connection; |
my $stype=$sheet->{'sheettype'}; |
my $stype=$sheet->{'sheettype'}; |
if ($stype eq 'classcalc') { |
if ($stype eq 'classcalc') { |
&loadcourse($sheet,$r); |
&loadcourse($sheet,$r,$c); |
} elsif ($stype eq 'studentcalc') { |
} elsif ($stype eq 'studentcalc') { |
&loadstudent($sheet); |
&loadstudent($sheet,$r,$c); |
} else { |
} else { |
&loadassessment($sheet); |
&loadassessment($sheet,$r,$c); |
} |
} |
} |
} |
|
|
Line 2524 sub loadrows {
|
Line 2652 sub loadrows {
|
|
|
sub checkthis { |
sub checkthis { |
my ($keyname,$time)=@_; |
my ($keyname,$time)=@_; |
return ($time<$expiredates{$keyname}); |
if (! exists($expiredates{$keyname})) { |
|
return 0; |
|
} else { |
|
return ($time<$expiredates{$keyname}); |
|
} |
} |
} |
|
|
sub forcedrecalc { |
sub forcedrecalc { |
Line 2557 sub forcedrecalc {
|
Line 2689 sub forcedrecalc {
|
# returns the export row for a spreadsheet. |
# returns the export row for a spreadsheet. |
# |
# |
sub exportsheet { |
sub exportsheet { |
my ($sheet,$uname,$udom,$stype,$usymb,$fn)=@_; |
my ($sheet,$uname,$udom,$stype,$usymb,$fn,$r)=@_; |
|
my $flag = 0; |
$uname = $uname || $sheet->{'uname'}; |
$uname = $uname || $sheet->{'uname'}; |
$udom = $udom || $sheet->{'udom'}; |
$udom = $udom || $sheet->{'udom'}; |
$stype = $stype || $sheet->{'sheettype'}; |
$stype = $stype || $sheet->{'sheettype'}; |
Line 2611 sub exportsheet {
|
Line 2744 sub exportsheet {
|
my ($newsheet)=&makenewsheet($uname,$udom,$stype,$usymb); |
my ($newsheet)=&makenewsheet($uname,$udom,$stype,$usymb); |
&readsheet($newsheet,$fn); |
&readsheet($newsheet,$fn); |
&updatesheet($newsheet); |
&updatesheet($newsheet); |
&loadrows($newsheet); |
&loadrows($newsheet,$r); |
&calcsheet($newsheet); |
&calcsheet($newsheet); |
@exportarr=&exportdata($newsheet); |
@exportarr=&exportdata($newsheet); |
## |
## |
Line 2626 sub exportsheet {
|
Line 2759 sub exportsheet {
|
[$key], |
[$key], |
$sheet->{'cdom'},$sheet->{'cnum'}); |
$sheet->{'cdom'},$sheet->{'cnum'}); |
if ($tmp[0]!~/^error/) { |
if ($tmp[0]!~/^error/) { |
%currentlystored = @tmp; |
# We only got one key, so we will access it directly. |
|
foreach (split('___&___',$tmp[1])) { |
|
my ($key,$value) = split('___=___',$_); |
|
$key = '' if (! defined($key)); |
|
$currentlystored{$key} = $value; |
|
} |
} |
} |
} else { |
} else { |
my @tmp = &Apache::lonnet::get('nohist_calculatedsheets_'. |
my @tmp = &Apache::lonnet::get('nohist_calculatedsheets_'. |
$sheet->{'cid'},[$key], |
$sheet->{'cid'},[$key], |
$sheet->{'udom'},$sheet->{'uname'}); |
$sheet->{'udom'},$sheet->{'uname'}); |
if ($tmp[0]!~/^error/) { |
if ($tmp[0]!~/^error/) { |
%currentlystored = @tmp; |
# We only got one key, so we will access it directly. |
|
foreach (split('___&___',$tmp[1])) { |
|
my ($key,$value) = split('___=___',$_); |
|
$key = '' if (! defined($key)); |
|
$currentlystored{$key} = $value; |
|
} |
} |
} |
} |
} |
# |
# |
Line 2652 sub exportsheet {
|
Line 2795 sub exportsheet {
|
# |
# |
# Store away the new value |
# Store away the new value |
# |
# |
|
my $timekey = $key.'.time'; |
if ($stype eq 'studentcalc') { |
if ($stype eq 'studentcalc') { |
&Apache::lonnet::put('nohist_calculatedsheets', |
my $result = &Apache::lonnet::put('nohist_calculatedsheets', |
{ $key => $newstore, |
{ $key => $newstore, |
$key.time => $now }, |
$timekey => $now }, |
$sheet->{'cdom'},$sheet->{'cnum'}); |
$sheet->{'cdom'}, |
} else { |
$sheet->{'cnum'}); |
&Apache::lonnet::put('nohist_calculatedsheets_'.$sheet->{'cid'}, |
} else { |
{ $key => $newstore, |
my $result = &Apache::lonnet::put('nohist_calculatedsheets_'.$sheet->{'cid'}, |
$key.time => $now }, |
{ $key => $newstore, |
$sheet->{'udom'}, |
$timekey => $now }, |
$sheet->{'uname'}) |
$sheet->{'udom'}, |
|
$sheet->{'uname'}); |
} |
} |
return @exportarr; |
return @exportarr; |
} |
} |
Line 2677 sub load_spreadsheet_expirationdates {
|
Line 2822 sub load_spreadsheet_expirationdates {
|
my @tmp = &Apache::lonnet::dump('nohist_expirationdates', |
my @tmp = &Apache::lonnet::dump('nohist_expirationdates', |
$ENV{'course.'.$cid.'.domain'}, |
$ENV{'course.'.$cid.'.domain'}, |
$ENV{'course.'.$cid.'.num'}); |
$ENV{'course.'.$cid.'.num'}); |
if (lc($tmp[0])!~/^error/){ |
if (lc($tmp[0]) !~ /^error/){ |
%expiredates = @tmp; |
%expiredates = @tmp; |
} |
} |
} |
} |
Line 2785 sub handler {
|
Line 2930 sub handler {
|
# |
# |
# Get query string for limited number of parameters |
# Get query string for limited number of parameters |
# |
# |
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, |
&Apache::loncommon::get_unprocessed_cgi |
['uname','udom','usymb','ufn']); |
($ENV{'QUERY_STRING'},['uname','udom','usymb','ufn','mapid','resid']); |
# |
# |
# Deal with restricted student permissions |
# Deal with restricted student permissions |
# |
# |
Line 2828 sub handler {
|
Line 2973 sub handler {
|
# Header.... |
# Header.... |
# |
# |
$r->print('<html><head><title>LON-CAPA Spreadsheet</title>'); |
$r->print('<html><head><title>LON-CAPA Spreadsheet</title>'); |
|
my $nothing = "''"; |
|
if ($ENV{'browser.type'} eq 'explorer') { |
|
$nothing = "'javascript:void(0);'"; |
|
} |
|
|
if ($ENV{'request.role'} !~ /^st\./) { |
if ($ENV{'request.role'} !~ /^st\./) { |
$r->print(<<ENDSCRIPT); |
$r->print(<<ENDSCRIPT); |
<script language="JavaScript"> |
<script language="JavaScript"> |
|
|
function celledit(cn,cf) { |
var editwin; |
var cnf=prompt(cn,cf); |
|
if (cnf!=null) { |
function celledit(cellname,cellformula) { |
document.sheet.unewfield.value=cn; |
var edit_text = ''; |
document.sheet.unewformula.value=cnf; |
edit_text +='<html><head><title>Cell Edit Window</title></head><body>'; |
document.sheet.submit(); |
edit_text += '<form name="editwinform">'; |
|
edit_text += '<center><h3>Cell '+cellname+'</h3>'; |
|
edit_text += '<textarea name="newformula" cols="40" rows="6"'; |
|
edit_text += ' wrap="off" >'+cellformula+'</textarea>'; |
|
edit_text += '</br>'; |
|
edit_text += '<input type="button" name="accept" value="Accept"'; |
|
edit_text += ' onClick=\\\'javascript:'; |
|
edit_text += 'opener.document.sheet.unewfield.value='; |
|
edit_text += '"'+cellname+'";'; |
|
edit_text += 'opener.document.sheet.unewformula.value='; |
|
edit_text += 'document.editwinform.newformula.value;'; |
|
edit_text += 'opener.document.sheet.submit();'; |
|
edit_text += 'self.close()\\\' />'; |
|
edit_text += ' '; |
|
edit_text += '<input type="button" name="abort" '; |
|
edit_text += 'value="Discard Changes"'; |
|
edit_text += ' onClick="javascript:self.close()" />'; |
|
edit_text += '</center></body></html>'; |
|
|
|
if (editwin != null && !(editwin.closed) ) { |
|
editwin.close(); |
} |
} |
|
|
|
editwin = window.open($nothing,'CellEditWin','height=200,width=350,scrollbars=no,resizeable=yes,alwaysRaised=yes,dependent=yes',true); |
|
editwin.document.write(edit_text); |
} |
} |
|
|
function changesheet(cn) { |
function changesheet(cn) { |
Line 2857 sub handler {
|
Line 3030 sub handler {
|
ENDSCRIPT |
ENDSCRIPT |
} |
} |
$r->print('</head>'.&Apache::loncommon::bodytag('Grades Spreadsheet'). |
$r->print('</head>'.&Apache::loncommon::bodytag('Grades Spreadsheet'). |
'<form action="'.$r->uri.'" name=sheet method=post>'); |
'<form action="'.$r->uri.'" name="sheet" method="post">'); |
$r->print(&hiddenfield('uname',$ENV{'form.uname'}). |
$r->print(&hiddenfield('uname',$ENV{'form.uname'}). |
&hiddenfield('udom',$ENV{'form.udom'}). |
&hiddenfield('udom',$ENV{'form.udom'}). |
&hiddenfield('usymb',$ENV{'form.usymb'}). |
&hiddenfield('usymb',$ENV{'form.usymb'}). |
Line 2878 ENDSCRIPT
|
Line 3051 ENDSCRIPT
|
# Read new sheet or modified worksheet |
# Read new sheet or modified worksheet |
my ($sheet)=&makenewsheet($aname,$adom,$sheettype,$ENV{'form.usymb'}); |
my ($sheet)=&makenewsheet($aname,$adom,$sheettype,$ENV{'form.usymb'}); |
# |
# |
|
# Check user permissions |
|
if (($sheet->{'sheettype'} eq 'classcalc' ) || |
|
($sheet->{'uname'} ne $ENV{'user.name'} ) || |
|
($sheet->{'udom'} ne $ENV{'user.domain'})) { |
|
unless (&Apache::lonnet::allowed('vgr',$sheet->{'cid'})) { |
|
$r->print('<h1>Access Permission Denied</h1>'. |
|
'</form></body></html>'); |
|
return OK; |
|
} |
|
} |
|
# Print out user information |
|
$r->print('<h2>'.$sheet->{'coursedesc'}.'</h2>'); |
|
if ($sheet->{'sheettype'} ne 'classcalc') { |
|
$r->print('<h2>'.&gettitle($sheet).'</h2><p>'); |
|
} |
|
if ($sheet->{'sheettype'} eq 'assesscalc') { |
|
$r->print('<b>User:</b> '.$sheet->{'uname'}. |
|
'<br /><b>Domain:</b> '.$sheet->{'udom'}.'<br />'); |
|
} |
|
if ($sheet->{'sheettype'} eq 'studentcalc' || |
|
$sheet->{'sheettype'} eq 'assesscalc') { |
|
$r->print('<b>Section/Group:</b>'.$sheet->{'csec'}.'</p>'); |
|
} |
|
# |
# If a new formula had been entered, go from work copy |
# If a new formula had been entered, go from work copy |
if ($ENV{'form.unewfield'}) { |
if ($ENV{'form.unewfield'}) { |
$r->print('<h2>Modified Workcopy</h2>'); |
$r->print('<h2>Modified Workcopy</h2>'); |
Line 2892 ENDSCRIPT
|
Line 3089 ENDSCRIPT
|
} else { |
} else { |
&readsheet($sheet,$ENV{'form.ufn'}); |
&readsheet($sheet,$ENV{'form.ufn'}); |
} |
} |
# Print out user information |
|
if ($sheet->{'sheettype'} ne 'classcalc') { |
|
$r->print('<p><b>User:</b> '.$sheet->{'uname'}. |
|
'<br><b>Domain:</b> '.$sheet->{'udom'}); |
|
$r->print('<br><b>Section/Group:</b> '.$sheet->{'csec'}); |
|
if ($ENV{'form.usymb'}) { |
|
$r->print('<br><b>Assessment:</b> <tt>'. |
|
$ENV{'form.usymb'}.'</tt>'); |
|
} |
|
} |
|
# |
|
# Check user permissions |
|
if (($sheet->{'sheettype'} eq 'classcalc' ) || |
|
($sheet->{'uname'} ne $ENV{'user.name'} ) || |
|
($sheet->{'udom'} ne $ENV{'user.domain'})) { |
|
unless (&Apache::lonnet::allowed('vgr',$sheet->{'cid'})) { |
|
$r->print('<h1>Access Permission Denied</h1>'. |
|
'</form></body></html>'); |
|
return OK; |
|
} |
|
} |
|
# Additional options |
# Additional options |
$r->print('<br />'. |
|
'<input type="submit" name="forcerecalc" '. |
|
'value="Completely Recalculate Sheet"><p>'); |
|
if ($sheet->{'sheettype'} eq 'assesscalc') { |
if ($sheet->{'sheettype'} eq 'assesscalc') { |
$r->print('<p><font size=+2>'. |
$r->print('<p><font size=+2>'. |
'<a href="/adm/studentcalc?'. |
'<a href="/adm/studentcalc?'. |
'uname='.$sheet->{'uname'}. |
'uname='.$sheet->{'uname'}. |
'&udom='.$sheet->{'udom'}.'">'. |
'&udom='.$sheet->{'udom'}.'">'. |
'Level up: Student Sheet</a></font><p>'); |
'Level up: Student Sheet</a></font></p>'); |
} |
} |
if (($sheet->{'sheettype'} eq 'studentcalc') && |
if (($sheet->{'sheettype'} eq 'studentcalc') && |
(&Apache::lonnet::allowed('vgr',$sheet->{'cid'}))) { |
(&Apache::lonnet::allowed('vgr',$sheet->{'cid'}))) { |
$r->print ('<p><font size=+2><a href="/adm/classcalc">'. |
$r->print ('<p><font size=+2><a href="/adm/classcalc">'. |
'Level up: Course Sheet</a></font><p>'); |
'Level up: Course Sheet</a></font></p>'); |
} |
} |
|
# Recalc button |
|
$r->print('<br />'. |
|
'<input type="submit" name="forcerecalc" '. |
|
'value="Completely Recalculate Sheet"></p>'); |
# Save dialog |
# Save dialog |
if (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'})) { |
if (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'})) { |
my $fname=$ENV{'form.ufn'}; |
my $fname=$ENV{'form.ufn'}; |
Line 3008 ENDSCRIPT
|
Line 3185 ENDSCRIPT
|
} |
} |
# |
# |
# Write the modified worksheet |
# Write the modified worksheet |
$r->print('<b>Current sheet:</b> '.$sheet->{'filename'}.'<p>'); |
$r->print('<b>Current sheet:</b> '.$sheet->{'filename'}.'</p>'); |
&tmpwrite($sheet); |
&tmpwrite($sheet); |
if ($sheet->{'sheettype'} eq 'studentcalc') { |
if ($sheet->{'sheettype'} eq 'assesscalc') { |
$r->print('<br>Show rows with empty A column: '); |
$r->print('<p>Show rows with empty A column: '); |
} else { |
} else { |
$r->print('<br>Show empty rows: '); |
$r->print('<p>Show empty rows: '); |
} |
} |
# |
# |
$r->print(&hiddenfield('userselhidden','true'). |
$r->print(&hiddenfield('userselhidden','true'). |
Line 3066 ENDSCRIPT
|
Line 3243 ENDSCRIPT
|
#value='Insert Row Bottom'><br> |
#value='Insert Row Bottom'><br> |
#ENDINSERTBUTTONS |
#ENDINSERTBUTTONS |
# Print out sheet |
# Print out sheet |
&outsheet($r,$sheet); |
&outsheet($sheet,$r); |
$r->print('</form></body></html>'); |
$r->print('</form></body></html>'); |
# Done |
# Done |
return OK; |
return OK; |