version 1.94, 2002/07/04 20:09:31
|
version 1.100.4.1, 2002/09/27 18:43:10
|
Line 71 use Apache::lonnet;
|
Line 71 use Apache::lonnet;
|
use Apache::Constants qw(:common :http); |
use Apache::Constants qw(:common :http); |
use GDBM_File; |
use GDBM_File; |
use HTML::TokeParser; |
use HTML::TokeParser; |
|
use Apache::lonhtmlcommon; |
# |
# |
# Caches for previously calculated spreadsheets |
# Caches for previously calculated spreadsheets |
# |
# |
Line 106 my %courseopt;
|
Line 106 my %courseopt;
|
my %useropt; |
my %useropt; |
my %parmhash; |
my %parmhash; |
|
|
|
# |
|
# Some hashes for stats on timing and performance |
|
# |
|
|
|
my %starttimes; |
|
my %usedtimes; |
|
my %numbertimes; |
|
|
# Stuff that only the screen handler can know |
# Stuff that only the screen handler can know |
|
|
my $includedir; |
my $includedir; |
Line 122 sub initsheet {
|
Line 130 sub initsheet {
|
$safeeval->permit("sort"); |
$safeeval->permit("sort"); |
$safeeval->deny(":base_io"); |
$safeeval->deny(":base_io"); |
$safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT'); |
$safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT'); |
|
$safeeval->share('$@'); |
my $code=<<'ENDDEFS'; |
my $code=<<'ENDDEFS'; |
# ---------------------------------------------------- Inside of the safe space |
# ---------------------------------------------------- Inside of the safe space |
|
|
Line 165 $cfn='';
|
Line 174 $cfn='';
|
|
|
$usymb=''; |
$usymb=''; |
|
|
|
# error messages |
|
|
|
$errormsg=''; |
|
|
sub mask { |
sub mask { |
my ($lower,$upper)=@_; |
my ($lower,$upper)=@_; |
|
|
Line 755 sub expandnamed {
|
Line 768 sub expandnamed {
|
} |
} |
if ($#matches == 0) { |
if ($#matches == 0) { |
$returnvalue = '$c{\''.$matches[0].'\'}'; |
$returnvalue = '$c{\''.$matches[0].'\'}'; |
|
} elsif ($#matches > 0) { |
|
# more than one match. Look for a concise one |
|
$returnvalue = "'non-unique parameter name : $expression'"; |
|
foreach (@matches) { |
|
if (/^$expression$/) { |
|
$returnvalue = '$c{\''.$_.'\'}'; |
|
} |
|
} |
} else { |
} else { |
$returnvalue = "'bad parameter name : $expression'"; |
$returnvalue = "'bad parameter name : $expression'"; |
} |
} |
Line 770 sub sett {
|
Line 791 sub sett {
|
} else { |
} else { |
$pattern='[A-Z]'; |
$pattern='[A-Z]'; |
} |
} |
|
|
|
# Deal with the template row |
foreach (keys(%f)) { |
foreach (keys(%f)) { |
if ($_=~/template\_(\w)/) { |
if ($_=~/template\_(\w)/) { |
my $col=$1; |
my $col=$1; |
Line 796 sub sett {
|
Line 819 sub sett {
|
} |
} |
} |
} |
} |
} |
|
|
|
# Deal with the normal cells |
foreach (keys(%f)) { |
foreach (keys(%f)) { |
if (($f{$_}) && ($_!~/template\_/)) { |
if (($f{$_}) && ($_!~/template\_/)) { |
my $matches=($_=~/^$pattern(\d+)/); |
my $matches=($_=~/^$pattern(\d+)/); |
Line 811 sub sett {
|
Line 836 sub sett {
|
} |
} |
} |
} |
} |
} |
|
# For inserted lines, [B-Z] is also valid |
|
|
|
unless ($sheettype eq 'assesscalc') { |
|
foreach (keys(%f)) { |
|
if ($_=~/[B-Z](\d+)/) { |
|
if ($f{'A'.$1}=~/^[\~\-]/) { |
|
$t{$_}=$f{$_}; |
|
$t{$_}=~s/\.\.+/\,/g; |
|
$t{$_}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$v\{\'$2\'\}/g; |
|
$t{$_}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.&expandnamed($2)/ge; |
|
} |
|
} |
|
} |
|
} |
|
|
# For some reason 'A0' gets special treatment... This seems superfluous |
# For some reason 'A0' gets special treatment... This seems superfluous |
# but I imagine it is here for a reason. |
# but I imagine it is here for a reason. |
$t{'A0'}=$f{'A0'}; |
$t{'A0'}=$f{'A0'}; |
Line 820 sub sett {
|
Line 860 sub sett {
|
} |
} |
|
|
sub calc { |
sub calc { |
%v=(); |
undef %v; |
&sett(); |
&sett(); |
my $notfinished=1; |
my $notfinished=1; |
|
my $lastcalc=''; |
my $depth=0; |
my $depth=0; |
while ($notfinished) { |
while ($notfinished) { |
$notfinished=0; |
$notfinished=0; |
foreach (keys(%t)) { |
foreach (keys(%t)) { |
my $old=$v{$_}; |
my $old=$v{$_}; |
$v{$_}=eval($t{$_}); |
$v{$_}=eval $t{$_}; |
if ($@) { |
if ($@) { |
%v=(); |
undef %v; |
return $@; |
return $_.': '.$@; |
} |
} |
if ($v{$_} ne $old) { $notfinished=1; } |
if ($v{$_} ne $old) { $notfinished=1; $lastcalc=$_; } |
} |
} |
$depth++; |
$depth++; |
if ($depth>100) { |
if ($depth>100) { |
%v=(); |
undef %v; |
return 'Maximum calculation depth exceeded'; |
return $lastcalc.': Maximum calculation depth exceeded'; |
} |
} |
} |
} |
return ''; |
return ''; |
Line 956 sub setrowlabels {
|
Line 997 sub setrowlabels {
|
|
|
sub calcsheet { |
sub calcsheet { |
my $safeeval=shift; |
my $safeeval=shift; |
$safeeval->reval('&calc();'); |
return $safeeval->reval('&calc();'); |
} |
} |
|
|
# ------------------------------------------------------------------ Get values |
# ------------------------------------------------------------------ Get values |
Line 973 sub getformulas {
|
Line 1014 sub getformulas {
|
return %{$safeeval->varglob('f')}; |
return %{$safeeval->varglob('f')}; |
} |
} |
|
|
|
# ----------------------------------------------------- Get value of $f{'A'.$n} |
|
|
|
sub getfa { |
|
my ($safeeval,$n)=@_; |
|
return $safeeval->reval('$f{"A'.$n.'"}'); |
|
} |
|
|
# -------------------------------------------------------------------- Get type |
# -------------------------------------------------------------------- Get type |
|
|
sub gettype { |
sub gettype { |
Line 1111 sub rown {
|
Line 1159 sub rown {
|
} |
} |
my $showf=0; |
my $showf=0; |
my $proc; |
my $proc; |
my $maxred; |
my $maxred=1; |
my $sheettype=&gettype($safeeval); |
my $sheettype=&gettype($safeeval); |
if ($sheettype eq 'studentcalc') { |
if ($sheettype eq 'studentcalc') { |
$proc='&outrowassess'; |
$proc='&outrowassess'; |
Line 1124 sub rown {
|
Line 1172 sub rown {
|
} else { |
} else { |
$maxred=26; |
$maxred=26; |
} |
} |
|
if (&getfa($safeeval,$n)=~/^[\~\-]/) { $maxred=1; } |
if ($n eq '-') { $proc='&templaterow'; $n=-1; $dataflag=1; } |
if ($n eq '-') { $proc='&templaterow'; $n=-1; $dataflag=1; } |
foreach ($safeeval->reval($proc.'('.$n.')')) { |
foreach ($safeeval->reval($proc.'('.$n.')')) { |
my $bgcolor=$defaultbg.((($showf-1)/5==int(($showf-1)/5))?'99':'DD'); |
my $bgcolor=$defaultbg.((($showf-1)/5==int(($showf-1)/5))?'99':'DD'); |
Line 1138 sub rown {
|
Line 1187 sub rown {
|
if ($vl eq '') { |
if ($vl eq '') { |
$vl='<font size=+2 color='.$bgcolor.'>#</font>'; |
$vl='<font size=+2 color='.$bgcolor.'>#</font>'; |
} |
} |
$rowdata.= |
$rowdata.='<td bgcolor='.$bgcolor.'>'; |
'<td bgcolor='.$bgcolor.'><a href="javascript:celledit('.$fm.');">'.$vl. |
if ($ENV{'request.role'} =~ /^st\./) { |
'</a></td>'; |
$rowdata.=$vl; |
|
} else { |
|
$rowdata.='<a href="javascript:celledit('.$fm.');">'. |
|
$vl.'</a>'; |
|
} |
|
$rowdata.='</td>'; |
} else { |
} else { |
$rowdata.='<td bgcolor='.$bgcolor.'> '.$vl.' </td>'; |
$rowdata.='<td bgcolor='.$bgcolor.'> '.$vl.' </td>'; |
} |
} |
Line 1490 sub tmpread {
|
Line 1544 sub tmpread {
|
} |
} |
} elsif ($nfield eq 'insertrow') { |
} elsif ($nfield eq 'insertrow') { |
$countrows++; |
$countrows++; |
my $newrow=substr('000000'.$i,-7); |
my $newrow=substr('000000'.$countrows,-7); |
if ($nform eq 'top') { |
if ($nform eq 'top') { |
$fo{'A'.$countrows}='--- '.$newrow; |
$fo{'A'.$countrows}='--- '.$newrow; |
} else { |
} else { |
Line 1611 sub updateclasssheet {
|
Line 1665 sub updateclasssheet {
|
my ($end,$start)=split(/\:/,&Apache::lonnet::unescape($value)); |
my ($end,$start)=split(/\:/,&Apache::lonnet::unescape($value)); |
my $active=1; |
my $active=1; |
if (($end) && ($now>$end)) { $active=0; } |
if (($end) && ($now>$end)) { $active=0; } |
|
$active = 1 if ($ENV{'form.Status'} eq 'Any'); |
|
$active = !$active if ($ENV{'form.Status'} eq 'Expired'); |
if ($active) { |
if ($active) { |
my $rowlabel=''; |
my $rowlabel=''; |
$name=&Apache::lonnet::unescape($name); |
$name=&Apache::lonnet::unescape($name); |
my ($sname,$sdom)=split(/\:/,$name); |
my ($sname,$sdom)=split(/\:/,$name); |
my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid); |
my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid); |
if ($ssec==-1) { |
# if ($ssec==-1) { |
unless ($ENV{'form.showcsv'}) { |
# unless ($ENV{'form.showcsv'}) { |
$rowlabel='<font color=red>Data not available: '.$name. |
# $rowlabel='<font color=red>Data not available: '.$name. |
'</font>'; |
# '</font>'; |
} else { |
# } else { |
$rowlabel='ERROR","'.$name. |
# $rowlabel='ERROR","'.$name. |
'","Data not available","","","'; |
# '","Data not available","","","'; |
} |
# } |
} else { |
# } else { |
my %reply=&Apache::lonnet::idrget($sdom,$sname); |
my %reply=&Apache::lonnet::idrget($sdom,$sname); |
my $reply=&Apache::lonnet::reply('get:'.$sdom.':'.$sname. |
my $reply=&Apache::lonnet::reply('get:'.$sdom.':'.$sname. |
':environment:firstname&middlename&lastname&generation', |
':environment:firstname&middlename&lastname&generation', |
Line 1647 sub updateclasssheet {
|
Line 1703 sub updateclasssheet {
|
unless ($ncount==4) { $rowlabel.=',""'; } |
unless ($ncount==4) { $rowlabel.=',""'; } |
$rowlabel=~s/\"$//; |
$rowlabel=~s/\"$//; |
} |
} |
} |
# } |
$currentlist{&Apache::lonnet::unescape($name)}=$rowlabel; |
$currentlist{&Apache::lonnet::unescape($name)}=$rowlabel; |
} |
} |
} # end of foreach (split(/\&/,$classlst)) |
} # end of foreach (split(/\&/,$classlst)) |
Line 1665 sub updateclasssheet {
|
Line 1721 sub updateclasssheet {
|
if ($_=~/^A(\d+)/) { |
if ($_=~/^A(\d+)/) { |
$maxrow=($1>$maxrow)?$1:$maxrow; |
$maxrow=($1>$maxrow)?$1:$maxrow; |
$existing{$f{$_}}=1; |
$existing{$f{$_}}=1; |
unless ((defined($currentlist{$f{$_}})) || (!$1)) { |
unless ((defined($currentlist{$f{$_}})) || (!$1) || |
|
($f{$_}=~/^(\~\~\~|\-\-\-)/)) { |
$f{$_}='!!! Obsolete'; |
$f{$_}='!!! Obsolete'; |
$changed=1; |
$changed=1; |
} |
} |
Line 1698 sub updatestudentassesssheet {
|
Line 1755 sub updatestudentassesssheet {
|
my $safeeval=shift; |
my $safeeval=shift; |
my %bighash; |
my %bighash; |
my $stype=&gettype($safeeval); |
my $stype=&gettype($safeeval); |
|
my $uname=&getuname($safeeval); |
|
my $udom =&getudom($safeeval); |
my %current=(); |
my %current=(); |
unless ($updatedata{$ENV{'request.course.fn'}.'_'.$stype}) { |
unless ($updatedata{ |
|
$ENV{'request.course.fn'}.'_'.$stype.'_'.$uname.'_'.$udom}) { |
# -------------------------------------------------------------------- Tie hash |
# -------------------------------------------------------------------- Tie hash |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
&GDBM_READER,0640)) { |
&GDBM_READER(),0640)) { |
# --------------------------------------------------------- Get all assessments |
# --------------------------------------------------------- Get all assessments |
|
|
my %allkeys=('timestamp' => |
my %allkeys=('timestamp' => |
Line 1780 sub updatestudentassesssheet {
|
Line 1840 sub updatestudentassesssheet {
|
} elsif ($stype eq 'studentcalc') { |
} elsif ($stype eq 'studentcalc') { |
%current=%allassess; |
%current=%allassess; |
} |
} |
$updatedata{$ENV{'request.course.fn'}.'_'.$stype}= |
$updatedata{$ENV{'request.course.fn'}.'_'.$stype.'_'.$uname.'_'.$udom}= |
join('___;___',%current); |
join('___;___',%current); |
} else { |
} else { |
return 'Could not access course data'; |
return 'Could not access course data'; |
Line 1788 sub updatestudentassesssheet {
|
Line 1848 sub updatestudentassesssheet {
|
# ------------------------------------------------------ Get current from cache |
# ------------------------------------------------------ Get current from cache |
} else { |
} else { |
%current=split(/\_\_\_\;\_\_\_/, |
%current=split(/\_\_\_\;\_\_\_/, |
$updatedata{$ENV{'request.course.fn'}.'_'.$stype}); |
$updatedata{$ENV{'request.course.fn'}.'_'.$stype.'_'.$uname.'_'.$udom}); |
} |
} |
# -------------------- Find discrepancies between the course row table and this |
# -------------------- Find discrepancies between the course row table and this |
# |
# |
Line 1804 sub updatestudentassesssheet {
|
Line 1864 sub updatestudentassesssheet {
|
$maxrow=($1>$maxrow)?$1:$maxrow; |
$maxrow=($1>$maxrow)?$1:$maxrow; |
my ($usy,$ufn)=split(/\_\_\&\&\&\_\_/,$f{$_}); |
my ($usy,$ufn)=split(/\_\_\&\&\&\_\_/,$f{$_}); |
$existing{$usy}=1; |
$existing{$usy}=1; |
unless ((defined($current{$usy})) || (!$1)) { |
unless ((defined($current{$usy})) || (!$1) || |
$f{$_}='!!! Obsolete'; |
($f{$_}=~/^(\~\~\~|\-\-\-)/)){ |
|
$f{$_}='!!! Obsolete'; |
$changed=1; |
$changed=1; |
} elsif ($ufn) { |
} elsif ($ufn) { |
$current{$usy} |
$current{$usy} |
Line 1858 sub loadstudent {
|
Line 1919 sub loadstudent {
|
foreach (keys(%f)) { |
foreach (keys(%f)) { |
if ($_=~/^A(\d+)/) { |
if ($_=~/^A(\d+)/) { |
my $row=$1; |
my $row=$1; |
unless (($f{$_}=~/^\!/) || ($row==0)) { |
unless (($f{$_}=~/^[\!\~\-]/) || ($row==0)) { |
my ($usy,$ufn)=split(/\_\_\&\&\&\_\_/,$f{$_}); |
my ($usy,$ufn)=split(/\_\_\&\&\&\_\_/,$f{$_}); |
@assessdata=&exportsheet(&getuname($safeeval), |
@assessdata=&exportsheet(&getuname($safeeval), |
&getudom($safeeval), |
&getudom($safeeval), |
Line 1897 sub loadcourse {
|
Line 1958 sub loadcourse {
|
my $total=0; |
my $total=0; |
foreach (keys(%f)) { |
foreach (keys(%f)) { |
if ($_=~/^A(\d+)/) { |
if ($_=~/^A(\d+)/) { |
unless ($f{$_}=~/^\!/) { $total++; } |
unless ($f{$_}=~/^[\!\~\-]/) { $total++; } |
} |
} |
} |
} |
my $now=0; |
my $now=0; |
Line 1917 ENDPOP
|
Line 1978 ENDPOP
|
foreach (keys(%f)) { |
foreach (keys(%f)) { |
if ($_=~/^A(\d+)/) { |
if ($_=~/^A(\d+)/) { |
my $row=$1; |
my $row=$1; |
unless (($f{$_}=~/^\!/) || ($row==0)) { |
unless (($f{$_}=~/^[\!\~\-]/) || ($row==0)) { |
my @studentdata=&exportsheet(split(/\:/,$f{$_}), |
my @studentdata=&exportsheet(split(/\:/,$f{$_}), |
'studentcalc'); |
'studentcalc'); |
undef %userrdatas; |
undef %userrdatas; |
Line 2077 sub loadassessment {
|
Line 2138 sub loadassessment {
|
my %c=(); |
my %c=(); |
|
|
if (tie(%parmhash,'GDBM_File', |
if (tie(%parmhash,'GDBM_File', |
&getcfn($safeeval).'_parms.db',&GDBM_READER,0640)) { |
&getcfn($safeeval).'_parms.db',&GDBM_READER(),0640)) { |
my %f=&getformulas($safeeval); |
my %f=&getformulas($safeeval); |
foreach (keys(%f)) { |
foreach (keys(%f)) { |
if ($_=~/^A/) { |
if ($_=~/^A/) { |
unless ($f{$_}=~/^\!/) { |
unless ($f{$_}=~/^[\!\~\-]/) { |
if ($f{$_}=~/^parameter/) { |
if ($f{$_}=~/^parameter/) { |
if ($thisassess{$f{$_}}) { |
if ($thisassess{$f{$_}}) { |
my $val=&parmval($f{$_},$safeeval); |
my $val=&parmval($f{$_},$safeeval); |
Line 2405 sub handler {
|
Line 2466 sub handler {
|
return OK; |
return OK; |
} |
} |
|
|
|
if ($ENV{'request.role'} =~ /^st\./) { |
|
delete $ENV{'form.unewfield'} if (exists($ENV{'form.unewfield'})); |
|
delete $ENV{'form.unewformula'} if (exists($ENV{'form.unewformula'})); |
|
} |
|
|
# ---------------------------------------------------- Global directory configs |
# ---------------------------------------------------- Global directory configs |
|
|
$includedir=$r->dir_config('lonIncludes'); |
$includedir=$r->dir_config('lonIncludes'); |
Line 2450 $tmpdir=$r->dir_config('lonDaemons').'/t
|
Line 2516 $tmpdir=$r->dir_config('lonDaemons').'/t
|
# --------------------------------------------------------------- Screen output |
# --------------------------------------------------------------- Screen output |
|
|
$r->print('<html><head><title>LON-CAPA Spreadsheet</title>'); |
$r->print('<html><head><title>LON-CAPA Spreadsheet</title>'); |
$r->print(<<ENDSCRIPT); |
if ($ENV{'request.role'} !~ /^st\./) { |
|
$r->print(<<ENDSCRIPT); |
<script language="JavaScript"> |
<script language="JavaScript"> |
|
|
function celledit(cn,cf) { |
function celledit(cn,cf) { |
Line 2476 $tmpdir=$r->dir_config('lonDaemons').'/t
|
Line 2543 $tmpdir=$r->dir_config('lonDaemons').'/t
|
|
|
</script> |
</script> |
ENDSCRIPT |
ENDSCRIPT |
|
} |
$r->print('</head><body bgcolor="#FFFFFF">'. |
$r->print('</head><body bgcolor="#FFFFFF">'. |
'<img align=right src=/adm/lonIcons/lonlogos.gif>'. |
'<img align=right src=/adm/lonIcons/lonlogos.gif>'. |
'<h1>LON-CAPA Spreadsheet</h1>'. |
'<h1>LON-CAPA Spreadsheet</h1>'. |
Line 2531 ENDSCRIPT
|
Line 2599 ENDSCRIPT
|
unless (&gettype($asheet) eq 'classcalc') { |
unless (&gettype($asheet) eq 'classcalc') { |
$r->print('<p><b>User:</b> '.&getuname($asheet). |
$r->print('<p><b>User:</b> '.&getuname($asheet). |
'<br><b>Domain:</b> '.&getudom($asheet)); |
'<br><b>Domain:</b> '.&getudom($asheet)); |
if (&getcsec($asheet) eq '-1') { |
# if (&getcsec($asheet) eq '-1') { |
$r->print('<h3><font color=red>'. |
# $r->print('<h3><font color=red>'. |
'Not a student in this course</font></h3>'); |
# 'Not a student in this course</font></h3>'); |
} else { |
# } else { |
$r->print('<br><b>Section/Group:</b> '.&getcsec($asheet)); |
$r->print('<br><b>Section/Group:</b> '.&getcsec($asheet)); |
} |
# } |
if ($ENV{'form.usymb'}) { |
if ($ENV{'form.usymb'}) { |
$r->print('<br><b>Assessment:</b> <tt>'.$ENV{'form.usymb'}.'</tt>'); |
$r->print('<br><b>Assessment:</b> <tt>'.$ENV{'form.usymb'}.'</tt>'); |
} |
} |
Line 2699 ENDSCRIPT
|
Line 2767 ENDSCRIPT
|
} |
} |
|
|
# ------------------------------------------------------------------ Insertrows |
# ------------------------------------------------------------------ Insertrows |
|
$r->print(' Student Status: '. |
|
&Apache::lonhtmlcommon::StatusOptions |
|
($ENV{'form.Status'},'sheet')); |
|
|
$r->print(<<ENDINSERTBUTTONS); |
$r->print(<<ENDINSERTBUTTONS); |
<br> |
<br> |