version 1.19, 2003/07/16 16:48:51
|
version 1.44, 2005/05/12 22:42:57
|
Line 48 Spreadsheet
|
Line 48 Spreadsheet
|
package Apache::Spreadsheet; |
package Apache::Spreadsheet; |
|
|
use strict; |
use strict; |
|
#use warnings FATAL=>'all'; |
|
#no warnings 'uninitialized'; |
use Apache::Constants qw(:common :http); |
use Apache::Constants qw(:common :http); |
use Apache::lonnet; |
use Apache::lonnet; |
use Safe; |
use Safe; |
Line 57 use HTML::Entities();
|
Line 59 use HTML::Entities();
|
use HTML::TokeParser; |
use HTML::TokeParser; |
use Spreadsheet::WriteExcel; |
use Spreadsheet::WriteExcel; |
use Time::HiRes; |
use Time::HiRes; |
|
use Apache::lonlocal; |
|
|
## |
## |
## Package Variables |
## Package Variables |
Line 83 sub new {
|
Line 86 sub new {
|
my ($stype) = ($class =~ /Apache::(.*)$/); |
my ($stype) = ($class =~ /Apache::(.*)$/); |
# |
# |
my ($name,$domain,$filename,$usymb)=@_; |
my ($name,$domain,$filename,$usymb)=@_; |
|
if (defined($usymb) && ref($usymb)) { |
|
$usymb = $usymb->symb; |
|
} |
|
if (! defined($name) || $name eq '') { |
|
$name = $env{'user.name'}; |
|
} |
|
if (! defined($domain) || $domain eq '') { |
|
$domain = $env{'user.domain'}; |
|
} |
# |
# |
my $self = { |
my $self = { |
name => $name, |
name => $name, |
Line 90 sub new {
|
Line 102 sub new {
|
type => $stype, |
type => $stype, |
symb => $usymb, |
symb => $usymb, |
errorlog => '', |
errorlog => '', |
maxrow => '', |
maxrow => 0, |
cid => $ENV{'request.course.id'}, |
cid => $env{'request.course.id'}, |
cnum => $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, |
cnum => $env{'course.'.$env{'request.course.id'}.'.num'}, |
cdom => $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, |
cdom => $env{'course.'.$env{'request.course.id'}.'.domain'}, |
chome => $ENV{'course.'.$ENV{'request.course.id'}.'.home'}, |
chome => $env{'course.'.$env{'request.course.id'}.'.home'}, |
coursedesc => $ENV{'course.'.$ENV{'request.course.id'}.'.description'}, |
coursedesc => $env{'course.'.$env{'request.course.id'}.'.description'}, |
coursefilename => $ENV{'request.course.fn'}, |
coursefilename => $env{'request.course.fn'}, |
# |
# |
# Flags |
# Flags |
temporary => 0, # true if this sheet has been modified but not saved |
temporary => 0, # true if this sheet has been modified but not saved |
Line 120 sub new {
|
Line 132 sub new {
|
# |
# |
# Load in the spreadsheet definition |
# Load in the spreadsheet definition |
$self->filename($filename); |
$self->filename($filename); |
if (exists($ENV{'form.workcopy'}) && |
if (exists($env{'form.workcopy'}) && |
$self->{'type'} eq $ENV{'form.workcopy'}) { |
$self->{'type'} eq $env{'form.workcopy'}) { |
$self->load_tmp(); |
$self->load_tmp(); |
} else { |
} else { |
$self->load(); |
$self->load(); |
Line 148 sub filename {
|
Line 160 sub filename {
|
$newfilename !~ /\w/ || $newfilename eq '') { |
$newfilename !~ /\w/ || $newfilename eq '') { |
my $key = 'course.'.$self->{'cid'}.'.spreadsheet_default_'. |
my $key = 'course.'.$self->{'cid'}.'.spreadsheet_default_'. |
$self->{'type'}; |
$self->{'type'}; |
if (exists($ENV{$key}) && $ENV{$key} ne '') { |
if (exists($env{$key}) && $env{$key} ne '') { |
$newfilename = $ENV{$key}; |
$newfilename = $env{$key}; |
} else { |
} else { |
$newfilename = 'default_'.$self->{'type'}; |
$newfilename = 'default_'.$self->{'type'}; |
} |
} |
Line 157 sub filename {
|
Line 169 sub filename {
|
if ($newfilename !~ /\w/ || $newfilename =~ /^\W*$/) { |
if ($newfilename !~ /\w/ || $newfilename =~ /^\W*$/) { |
$newfilename = 'default_'.$self->{'type'}; |
$newfilename = 'default_'.$self->{'type'}; |
} |
} |
if ($newfilename !~ /^default\.$self->{'type'}$/ ) { |
if ($newfilename !~ /^default\.$self->{'type'}$/ && |
|
$newfilename !~ /^\/res\/(.*)spreadsheet$/) { |
if ($newfilename !~ /_$self->{'type'}$/) { |
if ($newfilename !~ /_$self->{'type'}$/) { |
$newfilename =~ s/[\s_]*$//; |
$newfilename =~ s/[\s_]*$//; |
$newfilename .= '_'.$self->{'type'}; |
$newfilename .= '_'.$self->{'type'}; |
Line 229 sub initialize {
|
Line 242 sub initialize {
|
# the descendents of the spreadsheet class. |
# the descendents of the spreadsheet class. |
} |
} |
|
|
|
sub clear_package { |
|
# This method is here to remind you that it will be overridden by |
|
# the descendents of the spreadsheet class. |
|
} |
|
|
|
sub cleanup { |
|
my $self = shift(); |
|
$self->clear_package(); |
|
} |
|
|
sub initialize_spreadsheet_package { |
sub initialize_spreadsheet_package { |
&load_spreadsheet_expirationdates(); |
&load_spreadsheet_expirationdates(); |
&clear_spreadsheet_definition_cache(); |
&clear_spreadsheet_definition_cache(); |
Line 236 sub initialize_spreadsheet_package {
|
Line 259 sub initialize_spreadsheet_package {
|
|
|
sub load_spreadsheet_expirationdates { |
sub load_spreadsheet_expirationdates { |
undef %expiredates; |
undef %expiredates; |
my $cid=$ENV{'request.course.id'}; |
my $cid=$env{'request.course.id'}; |
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 248 sub load_spreadsheet_expirationdates {
|
Line 271 sub load_spreadsheet_expirationdates {
|
sub check_expiration_time { |
sub check_expiration_time { |
my $self = shift; |
my $self = shift; |
my ($time)=@_; |
my ($time)=@_; |
|
return 0 if (! defined($time)); |
my ($key1,$key2,$key3,$key4,$key5); |
my ($key1,$key2,$key3,$key4,$key5); |
# Description of keys |
# Description of keys |
# |
# |
Line 286 Returns the safe space required by a Spr
|
Line 310 Returns the safe space required by a Spr
|
=cut |
=cut |
|
|
###################################################### |
###################################################### |
|
{ |
|
|
|
my $safeeval; |
|
|
sub initialize_safe_space { |
sub initialize_safe_space { |
my $self = shift; |
my $self = shift; |
my $safeeval = new Safe(shift); |
my $usection = &Apache::lonnet::getsection($self->{'domain'}, |
my $safehole = new Safe::Hole; |
$self->{'name'}, |
$safeeval->permit("entereval"); |
$env{'request.course.id'}); |
$safeeval->permit(":base_math"); |
if (! defined($safeeval)) { |
$safeeval->permit("sort"); |
$safeeval = new Safe(shift); |
$safeeval->deny(":base_io"); |
my $safehole = new Safe::Hole; |
$safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT'); |
$safeeval->permit("entereval"); |
$safehole->wrap(\&mask,$safeeval,'&mask'); |
$safeeval->permit(":base_math"); |
$safeeval->share('$@'); |
$safeeval->permit("sort"); |
my $code=<<'ENDDEFS'; |
$safeeval->deny(":base_io"); |
|
$safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&Apache::lonnet::EXT'); |
|
$safehole->wrap(\&mask,$safeeval,'&mask'); |
|
$safehole->wrap(\&Apache::lonnet::logthis,$safeeval,'&logthis'); |
|
$safeeval->share('$@'); |
|
my $code=<<'ENDDEFS'; |
# ---------------------------------------------------- Inside of the safe space |
# ---------------------------------------------------- Inside of the safe space |
# |
# |
# f: formulas |
# f: formulas |
Line 353 $errormsg = '';
|
Line 386 $errormsg = '';
|
|
|
=pod |
=pod |
|
|
|
=item EXT(parameter) |
|
|
|
Calls the system EXT function to determine the value of the given parameter. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
|
sub EXT { |
|
my ($parameter) = @_; |
|
return '' if (! defined($parameter) || $parameter eq ''); |
|
$parameter =~ s/^parameter\./resource\./; |
|
my $value = &Apache::lonnet::EXT($parameter,$symb,$domain,$name,$usection); |
|
return $value; |
|
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=pod |
|
|
=item NUM(range) |
=item NUM(range) |
|
|
returns the number of items in the range. |
returns the number of items in the range. |
Line 361 returns the number of items in the range
|
Line 413 returns the number of items in the range
|
|
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub NUM { |
sub NUM { |
my $mask=&mask(@_); |
my $values=&get_values(@_); |
my $num= $#{@{grep(/$mask/,keys(%sheet_values))}}+1; |
my $num= scalar(@$values); |
return $num; |
return $num; |
} |
} |
|
|
Line 377 sub NUM {
|
Line 429 sub NUM {
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub BIN { |
sub BIN { |
my ($low,$high,$lower,$upper)=@_; |
my ($low,$high,$lower,$upper)=@_; |
my $mask=&mask($lower,$upper); |
my $values=&get_values($lower,$upper); |
my $num=0; |
my $num=0; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
if (($sheet_values{$_}>=$low) && ($sheet_values{$_}<=$high)) { |
if (($_>=$low) && ($_<=$high)) { |
$num++; |
$num++; |
} |
} |
} |
} |
Line 399 returns the sum of items in the range.
|
Line 451 returns the sum of items in the range.
|
|
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub SUM { |
sub SUM { |
my $mask=&mask(@_); |
my $values=&get_values(@_); |
my $sum=0; |
my $sum=0; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
$sum+=$sheet_values{$_}; |
$sum+=$_; |
} |
} |
return $sum; |
return $sum; |
} |
} |
Line 419 compute the average of the items in the
|
Line 471 compute the average of the items in the
|
|
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub MEAN { |
sub MEAN { |
my $mask=&mask(@_); |
my $values=&get_values(@_); |
my $sum=0; |
my $sum=0; |
my $num=0; |
my $num=0; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
$sum+=$sheet_values{$_}; |
$sum+=$_; |
$num++; |
$num++; |
} |
} |
if ($num) { |
if ($num) { |
Line 445 compute the standard deviation of the it
|
Line 497 compute the standard deviation of the it
|
|
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub STDDEV { |
sub STDDEV { |
my $mask=&mask(@_); |
my $values=&get_values(@_); |
my $sum=0; my $num=0; |
my $sum=0; my $num=0; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
$sum+=$sheet_values{$_}; |
$sum+=$_; |
$num++; |
$num++; |
} |
} |
unless ($num>1) { return undef; } |
unless ($num>1) { return undef; } |
my $mean=$sum/$num; |
my $mean=$sum/$num; |
$sum=0; |
$sum=0; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
$sum+=($sheet_values{$_}-$mean)**2; |
$sum+=($_-$mean)**2; |
} |
} |
return sqrt($sum/($num-1)); |
return sqrt($sum/($num-1)); |
} |
} |
Line 472 compute the product of the items in the
|
Line 524 compute the product of the items in the
|
|
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub PROD { |
sub PROD { |
my $mask=&mask(@_); |
my $values=&get_values(@_); |
my $prod=1; |
my $prod=1; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
$prod*=$sheet_values{$_}; |
$prod*=$_; |
} |
} |
return $prod; |
return $prod; |
} |
} |
Line 492 compute the maximum of the items in the
|
Line 544 compute the maximum of the items in the
|
|
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub MAX { |
sub MAX { |
my $mask=&mask(@_); |
my $values=&get_values(@_); |
my $max='-'; |
my $max='-'; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
unless ($max) { $max=$sheet_values{$_}; } |
if (($_>$max) || ($max eq '-')) { |
if (($sheet_values{$_}>$max) || ($max eq '-')) { |
$max=$_; |
$max=$sheet_values{$_}; |
|
} |
} |
} |
} |
return $max; |
return $max; |
Line 515 compute the minimum of the items in the
|
Line 566 compute the minimum of the items in the
|
|
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub MIN { |
sub MIN { |
my $mask=&mask(@_); |
my $values=&get_values(@_); |
my $min='-'; |
my $min='-'; |
foreach (grep /$mask/,keys(%sheet_values)) { |
foreach (@$values) { |
unless ($max) { $max=$sheet_values{$_}; } |
if (($_<$min) || ($min eq '-')) { |
if (($sheet_values{$_}<$min) || ($min eq '-')) { |
$min=$_; |
$min=$sheet_values{$_}; |
|
} |
} |
} |
} |
return $min; |
return $min; |
Line 540 compute the sum of the largest 'num' ite
|
Line 590 compute the sum of the largest 'num' ite
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub SUMMAX { |
sub SUMMAX { |
my ($num,$lower,$upper)=@_; |
my ($num,$lower,$upper)=@_; |
my $mask=&mask($lower,$upper); |
my $values=&get_values($lower,$upper); |
my @inside=(); |
my @inside=sort {$a <=> $b} (@$values); |
foreach (grep /$mask/,keys(%sheet_values)) { |
|
push (@inside,$sheet_values{$_}); |
|
} |
|
@inside=sort(@inside); |
|
my $sum=0; my $i; |
my $sum=0; my $i; |
for ($i=$#inside;(($i>$#inside-$num) && ($i>=0));$i--) { |
for ($i=$#inside;(($i>$#inside-$num) && ($i>=0));$i--) { |
$sum+=$inside[$i]; |
$sum+=$inside[$i]; |
Line 567 compute the sum of the smallest 'num' it
|
Line 613 compute the sum of the smallest 'num' it
|
#------------------------------------------------------- |
#------------------------------------------------------- |
sub SUMMIN { |
sub SUMMIN { |
my ($num,$lower,$upper)=@_; |
my ($num,$lower,$upper)=@_; |
my $mask=&mask($lower,$upper); |
my $values=&get_values($lower,$upper); |
my @inside=(); |
my @inside=sort {$a <=> $b} (@$values); |
foreach (grep /$mask/,keys(%sheet_values)) { |
|
$inside[$#inside+1]=$sheet_values{$_}; |
|
} |
|
@inside=sort(@inside); |
|
my $sum=0; my $i; |
my $sum=0; my $i; |
for ($i=0;(($i<$num) && ($i<=$#inside));$i++) { |
for ($i=0;(($i<$num) && ($i<=$#inside));$i++) { |
$sum+=$inside[$i]; |
$sum+=$inside[$i]; |
Line 595 parametername should be a string such as
|
Line 637 parametername should be a string such as
|
sub MINPARM { |
sub MINPARM { |
my ($expression) = @_; |
my ($expression) = @_; |
my $min = undef; |
my $min = undef; |
study($expression); |
|
foreach $parameter (keys(%c)) { |
foreach $parameter (keys(%c)) { |
next if ($parameter !~ /$expression/); |
next if ($parameter !~ /$expression/); |
if ((! defined($min)) || ($min > $c{$parameter})) { |
if ((! defined($min)) || ($min > $c{$parameter})) { |
Line 620 parametername should be a string such as
|
Line 661 parametername should be a string such as
|
sub MAXPARM { |
sub MAXPARM { |
my ($expression) = @_; |
my ($expression) = @_; |
my $max = undef; |
my $max = undef; |
study($expression); |
|
foreach $parameter (keys(%c)) { |
foreach $parameter (keys(%c)) { |
next if ($parameter !~ /$expression/); |
next if ($parameter !~ /$expression/); |
if ((! defined($min)) || ($max < $c{$parameter})) { |
if ((! defined($min)) || ($max < $c{$parameter})) { |
Line 630 sub MAXPARM {
|
Line 670 sub MAXPARM {
|
return $max; |
return $max; |
} |
} |
|
|
|
sub get_values { |
|
my ($lower,$upper)=@_; |
|
my $mask=&mask(@_); |
|
my @values; |
|
foreach (grep eval("/$mask/"),keys(%sheet_values)) { |
|
push(@values,$sheet_values{$_}); |
|
} |
|
return \@values; |
|
if (0) { |
|
# perhaps creating a list of possible cells and looking if they exist |
|
# would be faster somtimes? |
|
&logthis("mask is ".$mask); |
|
my @alpha; |
|
if (($la eq '*') || ($ua eq '*')) { |
|
@alpha=('A'..'z'); |
|
} else { |
|
if ($la gt $ua) { |
|
my $tmp = $ua; |
|
$ua = $la; |
|
$la = $ua; |
|
} |
|
$alpha=($la..$ua); |
|
} |
|
} |
|
} |
|
|
sub calc { |
sub calc { |
%sheet_values = %t; |
%sheet_values = %t; |
Line 659 sub calc {
|
Line 724 sub calc {
|
return $lastcalc.': Maximum calculation depth exceeded'; |
return $lastcalc.': Maximum calculation depth exceeded'; |
} |
} |
} |
} |
return ''; |
return 'okay'; |
} |
} |
|
|
# ------------------------------------------- End of "Inside of the safe space" |
# ------------------------------------------- End of "Inside of the safe space" |
ENDDEFS |
ENDDEFS |
$safeeval->reval($code); |
$safeeval->reval($code); |
|
} |
$self->{'safe'} = $safeeval; |
$self->{'safe'} = $safeeval; |
$self->{'root'} = $self->{'safe'}->root(); |
$self->{'root'} = $self->{'safe'}->root(); |
# |
# |
# Place some of the %$self items into the safe space except the safe space |
# Place some of the %$self items into the safe space except the safe space |
# itself |
# itself |
my $initstring = ''; |
my $initstring = ''; |
foreach (qw/name domain type usymb cid csec coursefilename |
foreach (qw/name domain type symb cid csec coursefilename |
cnum cdom chome uhome/) { |
cnum cdom chome uhome/) { |
$initstring.= qq{\$$_="$self->{$_}";}; |
$initstring.= qq{\$$_="$self->{$_}";}; |
} |
} |
|
$initstring.=qq{\$usection="$usection";}; |
$self->{'safe'}->reval($initstring); |
$self->{'safe'}->reval($initstring); |
return $self; |
return $self; |
} |
} |
|
|
|
} |
|
|
###################################################### |
###################################################### |
|
|
=pod |
=pod |
Line 691 ENDDEFS
|
Line 761 ENDDEFS
|
|
|
###################################################### |
###################################################### |
|
|
|
=pod |
|
|
|
=item &mask($lower,$upper) |
|
|
|
Inputs: $lower and $upper, cell names ("X12" or "a150") or globs ("X*"). |
|
|
|
Returns: Regular expression matching spreadsheet cells that are within |
|
the rectangle defined by $lower and $upper. Due to the nature of the |
|
regular expression this result must be used inside an eval(). |
|
|
|
=cut |
|
|
###################################################### |
###################################################### |
{ |
{ |
Line 705 sub mask {
|
Line 786 sub mask {
|
} |
} |
$upper = $lower if (! defined($upper)); |
$upper = $lower if (! defined($upper)); |
# |
# |
my ($la,$ld) = ($lower=~/([A-Za-z]|\*)(\d+|\*)/); |
my ($la,$ld) = ($lower=~/([A-z]|\*)(\d+|\*)/); |
my ($ua,$ud) = ($upper=~/([A-Za-z]|\*)(\d+|\*)/); |
my ($ua,$ud) = ($upper=~/([A-z]|\*)(\d+|\*)/); |
# |
# |
my $alpha=''; |
my $alpha=''; |
my $num=''; |
my $num=''; |
# |
# |
|
# Do not put parenthases around $alpha. |
|
# $num depends on the value in $1. |
if (($la eq '*') || ($ua eq '*')) { |
if (($la eq '*') || ($ua eq '*')) { |
$alpha='[A-Za-z]'; |
$alpha='[A-z]'; |
} else { |
} else { |
if (($la=~/[A-Z]/) && ($ua=~/[A-Z]/) || |
if ($la gt $ua) { |
($la=~/[a-z]/) && ($ua=~/[a-z]/)) { |
my $tmp = $ua; |
$alpha='['.$la.'-'.$ua.']'; |
$ua = $la; |
} else { |
$la = $ua; |
$alpha='['.$la.'-Za-'.$ua.']'; |
} |
} |
$alpha=qq/[$la-$ua]/; |
} |
} |
if (($ld eq '*') || ($ud eq '*')) { |
if ($ld ne '*' && $ud ne '*') { |
$num='\d+'; |
# Make sure $ld <= $ud |
|
if ($ld > $ud) { |
|
my $tmp = $ud; |
|
$ud = $ld; |
|
$ld = $tmp; |
|
} |
|
# Here we make a regular expression using some advanced regexp |
|
# abilities. |
|
# (\d+) will match the digits of the cell name and dump them in |
|
# to $1 |
|
# (?(?{ ... code ...} pattern_if_true | pattern_if_false)) will |
|
# choose pattern_if_true if { ... code ... } is true and |
|
# pattern_if_false if { ... code ... } is false. |
|
# In this case, pattern_if_true is empty. pattern_if_false is |
|
# 'donotmatch' and will not match our cells because none of |
|
# them end with donotmatch. |
|
# Unfortunately, the use of this type of regular expression |
|
# requires that each match be wrapped in an eval(). Search for |
|
# $mask in this module for examples |
|
$num = '(\d+)(?(?{$1>= '.$ld.' && $1<='.$ud.'})|donotmatch)'; |
} else { |
} else { |
if (length($ld)!=length($ud)) { |
$num = '(\d+)'; |
$num.='('; |
|
foreach ($ld=~m/\d/g) { |
|
$num.='['.$_.'-9]'; |
|
} |
|
if (length($ud)-length($ld)>1) { |
|
$num.='|\d{'.(length($ld)+1).','.(length($ud)-1).'}'; |
|
} |
|
$num.='|'; |
|
foreach ($ud=~m/\d/g) { |
|
$num.='[0-'.$_.']'; |
|
} |
|
$num.=')'; |
|
} else { |
|
my @lda=($ld=~m/\d/g); |
|
my @uda=($ud=~m/\d/g); |
|
my $i; |
|
my $j=0; |
|
my $notdone=1; |
|
for ($i=0;($i<=$#lda)&&($notdone);$i++) { |
|
if ($lda[$i]==$uda[$i]) { |
|
$num.=$lda[$i]; |
|
$j=$i; |
|
} else { |
|
$notdone=0; |
|
} |
|
} |
|
if ($j<$#lda-1) { |
|
$num.='('.$lda[$j+1]; |
|
for ($i=$j+2;$i<=$#lda;$i++) { |
|
$num.='['.$lda[$i].'-9]'; |
|
} |
|
if ($uda[$j+1]-$lda[$j+1]>1) { |
|
$num.='|['.($lda[$j+1]+1).'-'.($uda[$j+1]-1).']\d{'. |
|
($#lda-$j-1).'}'; |
|
} |
|
$num.='|'.$uda[$j+1]; |
|
for ($i=$j+2;$i<=$#uda;$i++) { |
|
$num.='[0-'.$uda[$i].']'; |
|
} |
|
$num.=')'; |
|
} else { |
|
if ($lda[-1]!=$uda[-1]) { |
|
$num.='['.$lda[-1].'-'.$uda[-1].']'; |
|
} |
|
} |
|
} |
|
} |
} |
my $expression ='^'.$alpha.$num."\$"; |
my $expression = '^'.$alpha.$num.'$'; |
$memoizer{$key} = $expression; |
$memoizer{$key} = $expression; |
return $expression; |
return $expression; |
} |
} |
|
|
|
# |
|
# Debugging routine |
|
sub dump_memoized_values { |
|
while (my ($key,$value) = each(%memoizer)) { |
|
&Apache::lonnet::logthis('memoizer: '.$key.' = '.$value); |
|
} |
|
return; |
|
} |
|
|
} |
} |
|
|
## |
## |
Line 794 sub expandnamed {
|
Line 859 sub expandnamed {
|
my @vars=split(/\W+/,$formula); |
my @vars=split(/\W+/,$formula); |
my %values=(); |
my %values=(); |
foreach my $varname ( @vars ) { |
foreach my $varname ( @vars ) { |
if ($varname=~/\D/) { |
if ($varname=~/^(parameter|stores|timestamp)/) { |
$formula=~s/$varname/'$c{\''.$varname.'\'}'/ge; |
$formula=~s/$varname/'$c{\''.$varname.'\'}'/ge; |
$varname=~s/$var/\([\\w:\\- ]\+\)/g; |
$varname=~s/$var/\([\\w:\\- ]\+\)/g; |
foreach (keys(%{$self->{'constants'}})) { |
foreach (keys(%{$self->{'constants'}})) { |
if ($_=~/$varname/) { |
if ($_=~/$varname/) { |
Line 827 sub expandnamed {
|
Line 892 sub expandnamed {
|
my @matches = (); |
my @matches = (); |
my @values = (); |
my @values = (); |
$#matches = -1; |
$#matches = -1; |
study $expression; |
|
while (my($parameter,$value) = each(%{$self->{'constants'}})) { |
while (my($parameter,$value) = each(%{$self->{'constants'}})) { |
next if ($parameter !~ /$expression/); |
next if ($parameter !~ /$expression/); |
push(@matches,$parameter); |
push(@matches,$parameter); |
Line 889 sub sett {
|
Line 953 sub sett {
|
$t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g; |
$t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g; |
$t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/ge; |
$t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/ge; |
} elsif ( $col =~ /^[A-Z]$/ ) { |
} elsif ( $col =~ /^[A-Z]$/ ) { |
if ($formula !~ /^\!/ && exists($self->{'constants'}->{$cell})) { |
if ($formula !~ /^\!/ && exists($self->{'constants'}->{$cell}) |
|
&& $self->{'constants'}->{$cell} ne '') { |
my $data = $self->{'constants'}->{$cell}; |
my $data = $self->{'constants'}->{$cell}; |
$t{$cell} = $data; |
$t{$cell} = $data; |
} |
} |
Line 1121 sub calcsheet {
|
Line 1186 sub calcsheet {
|
# $self->logthis($self->get_errorlog()); |
# $self->logthis($self->get_errorlog()); |
%{$self->{'values'}} = %{$self->{'safe'}->varglob('sheet_values')}; |
%{$self->{'values'}} = %{$self->{'safe'}->varglob('sheet_values')}; |
# $self->logthis($self->get_errorlog()); |
# $self->logthis($self->get_errorlog()); |
|
if ($result ne 'okay') { |
|
$self->set_calcerror($result); |
|
} |
return $result; |
return $result; |
} |
} |
|
|
|
sub set_badcalc { |
|
my $self = shift(); |
|
$self->{'badcalc'} =1; |
|
return; |
|
} |
|
|
|
sub badcalc { |
|
my $self = shift; |
|
if (exists($self->{'badcalc'}) && $self->{'badcalc'}) { |
|
return 1; |
|
} else { |
|
return 0; |
|
} |
|
} |
|
|
|
sub set_calcerror { |
|
my $self = shift; |
|
if (@_) { |
|
$self->set_badcalc(); |
|
if (exists($self->{'calcerror'})) { |
|
$self->{'calcerror'}.="\n".$_[0]; |
|
} else { |
|
$self->{'calcerror'}.=$_[0]; |
|
} |
|
} |
|
} |
|
|
|
sub calcerror { |
|
my $self = shift; |
|
if ($self->badcalc()) { |
|
if (exists($self->{'calcerror'})) { |
|
return $self->{'calcerror'}; |
|
} |
|
} |
|
return; |
|
} |
|
|
########################################################### |
########################################################### |
## |
## |
## Output Helpers |
## Output Helpers |
Line 1132 sub calcsheet {
|
Line 1237 sub calcsheet {
|
sub display { |
sub display { |
my $self = shift; |
my $self = shift; |
my ($r) = @_; |
my ($r) = @_; |
$self->compute($r); |
|
my $outputmode = 'html'; |
my $outputmode = 'html'; |
if ($ENV{'form.output_format'} =~ /^(html|excel|csv)$/) { |
foreach ($self->output_options()) { |
$outputmode = $ENV{'form.output_format'}; |
if ($env{'form.output_format'} eq $_->{'value'}) { |
|
$outputmode = $_->{'value'}; |
|
last; |
|
} |
} |
} |
if ($outputmode eq 'html') { |
if ($outputmode eq 'html') { |
|
$self->compute($r); |
$self->outsheet_html($r); |
$self->outsheet_html($r); |
|
} elsif ($outputmode eq 'htmlclasslist') { |
|
# No computation neccessary... This is kludgy |
|
$self->outsheet_htmlclasslist($r); |
} elsif ($outputmode eq 'excel') { |
} elsif ($outputmode eq 'excel') { |
|
$self->compute($r); |
$self->outsheet_excel($r); |
$self->outsheet_excel($r); |
} elsif ($outputmode eq 'csv') { |
} elsif ($outputmode eq 'csv') { |
|
$self->compute($r); |
$self->outsheet_csv($r); |
$self->outsheet_csv($r); |
|
} elsif ($outputmode eq 'xml') { |
|
# $self->compute($r); |
|
$self->outsheet_xml($r); |
} |
} |
|
$self->cleanup(); |
return; |
return; |
} |
} |
|
|
############################################ |
############################################ |
## HTML output routines ## |
## HTML output routines ## |
############################################ |
############################################ |
|
sub html_report_error { |
|
my $self = shift(); |
|
my $Str = ''; |
|
if ($self->badcalc()) { |
|
$Str = '<h3 style="color:red">'. |
|
&mt('An error occurred while calculating this spreadsheet'). |
|
"</h3>\n". |
|
'<pre>'.$self->calcerror()."</pre>\n"; |
|
} |
|
return $Str; |
|
} |
|
|
sub html_export_row { |
sub html_export_row { |
my $self = shift(); |
my $self = shift(); |
my ($color) = @_; |
my ($color) = @_; |
$color = '#CCCCFF' if (! defined($color)); |
$color = '#CCCCFF' if (! defined($color)); |
my $allowed = &Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}); |
my $allowed = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); |
my $row_html; |
my $row_html; |
my @rowdata = $self->get_row(0); |
my @rowdata = $self->get_row(0); |
foreach my $cell (@rowdata) { |
foreach my $cell (@rowdata) { |
Line 1171 sub html_export_row {
|
Line 1300 sub html_export_row {
|
|
|
sub html_template_row { |
sub html_template_row { |
my $self = shift(); |
my $self = shift(); |
my $allowed = &Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}); |
my $allowed = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); |
my ($num_uneditable,$importcolor) = @_; |
my ($num_uneditable,$importcolor) = @_; |
my $row_html; |
my $row_html; |
my @rowdata = $self->get_template_row(); |
my @rowdata = $self->get_template_row(); |
Line 1208 sub html_editable_cell {
|
Line 1337 sub html_editable_cell {
|
} elsif ($value =~ /^\s*$/ ) { |
} elsif ($value =~ /^\s*$/ ) { |
$value = '<font color="'.$bgcolor.'">#</font>'; |
$value = '<font color="'.$bgcolor.'">#</font>'; |
} else { |
} else { |
$value = &HTML::Entities::encode($value) if ($value !~/ /); |
$value = &HTML::Entities::encode($value,'<>&"') if ($value !~/ /); |
} |
} |
return $value if (! $allowed); |
return $value if (! $allowed); |
# |
# |
Line 1217 sub html_editable_cell {
|
Line 1346 sub html_editable_cell {
|
# |
# |
# The encoding string "^A-blah" is placed in []'s inside a regexp, so |
# The encoding string "^A-blah" is placed in []'s inside a regexp, so |
# we specify the characters we want left alone by putting a '^' in front. |
# we specify the characters we want left alone by putting a '^' in front. |
$formula = &HTML::Entities::encode($formula,"^A-z0-9 !#\$%-;=?~"); |
$formula = &HTML::Entities::encode($formula,'^A-z0-9 !#$%-;=?~'); |
|
# HTML::Entities::encode does not catch everything - we need '\' encoded |
|
$formula =~ s/\\/&\#092/g; |
# Escape it again - this time the only encodable character is '&' |
# Escape it again - this time the only encodable character is '&' |
$formula =~ s/\&/\&/g; |
$formula =~ s/\&/\&/g; |
# Glue everything together |
# Glue everything together |
Line 1229 sub html_editable_cell {
|
Line 1360 sub html_editable_cell {
|
sub html_uneditable_cell { |
sub html_uneditable_cell { |
my ($cell,$bgcolor) = @_; |
my ($cell,$bgcolor) = @_; |
my $value = (defined($cell) ? $cell->{'value'} : ''); |
my $value = (defined($cell) ? $cell->{'value'} : ''); |
$value = &HTML::Entities::encode($value) if ($value !~/ /); |
$value = &HTML::Entities::encode($value,'<>&"') if ($value !~/ /); |
return ' '.$value.' '; |
return ' '.$value.' '; |
} |
} |
|
|
sub html_row { |
sub html_row { |
my $self = shift(); |
my $self = shift(); |
my ($num_uneditable,$row,$exportcolor,$importcolor) = @_; |
my ($num_uneditable,$row,$exportcolor,$importcolor) = @_; |
my $allowed = &Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}); |
my $allowed = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); |
my @rowdata = $self->get_row($row); |
my @rowdata = $self->get_row($row); |
my $num_cols_output = 0; |
my $num_cols_output = 0; |
my $row_html; |
my $row_html; |
Line 1260 sub html_row {
|
Line 1391 sub html_row {
|
|
|
sub html_header { |
sub html_header { |
my $self = shift; |
my $self = shift; |
return '' if (! $ENV{'request.role.adv'}); |
return '' if (! $env{'request.role.adv'}); |
return "<table>\n". |
return "<table>\n". |
'<tr><th align="center">Output Format</th><tr>'."\n". |
'<tr><th align="center">'.&mt('Output Format').'</th></tr>'."\n". |
'<tr><td>'.&output_selector()."</td></tr>\n". |
'<tr><td>'.$self->output_selector()."</td></tr>\n". |
"</table>\n"; |
"</table>\n"; |
} |
} |
|
|
|
## |
|
## Default output types are HTML, Excel, and CSV |
|
sub output_options { |
|
my $self = shift(); |
|
return ({value => 'html', |
|
description => 'HTML'}, |
|
{value => 'excel', |
|
description => 'Excel'}, |
|
# {value => 'xml', |
|
# description => 'XML'}, |
|
{value => 'csv', |
|
description => 'Comma Separated Values'},); |
|
} |
|
|
sub output_selector { |
sub output_selector { |
|
my $self = shift(); |
my $output_selector = '<select name="output_format" size="3">'."\n"; |
my $output_selector = '<select name="output_format" size="3">'."\n"; |
my $default = 'html'; |
my $default = 'html'; |
if (exists($ENV{'form.output_format'})) { |
if (exists($env{'form.output_format'})) { |
$default = $ENV{'form.output_format'} |
$default = $env{'form.output_format'} |
} else { |
} else { |
$ENV{'form.output_format'} = $default; |
$env{'form.output_format'} = $default; |
} |
} |
foreach (['html','HTML'], |
foreach ($self->output_options()) { |
['excel','Excel'], |
$output_selector.='<option value="'.$_->{'value'}.'"'; |
['csv','Comma Seperated Values']) { |
if ($_->{'value'} eq $default) { |
my ($name,$description) = @{$_}; |
|
$output_selector.=qq{<option value="$name"}; |
|
if ($name eq $default) { |
|
$output_selector .= ' selected'; |
$output_selector .= ' selected'; |
} |
} |
$output_selector .= ">$description</option>\n"; |
$output_selector .= ">".&mt($_->{'description'})."</option>\n"; |
} |
} |
$output_selector .= "</select>\n"; |
$output_selector .= "</select>\n"; |
return $output_selector; |
return $output_selector; |
Line 1307 sub excel_output_row {
|
Line 1450 sub excel_output_row {
|
return; |
return; |
} |
} |
|
|
sub create_excel_spreadsheet { |
# |
|
# This routine is just a stub |
|
sub outsheet_htmlclasslist { |
my $self = shift; |
my $self = shift; |
my ($r) = @_; |
my ($r) = @_; |
my $filename = '/prtspool/'. |
$r->print('<h2>'.&mt("This output is not supported").'</h2>'); |
$ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. |
$r->rflush(); |
time.'_'.rand(1000000000).'.xls'; |
return; |
my $workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename); |
|
if (! defined($workbook)) { |
|
$r->log_error("Error creating excel spreadsheet $filename: $!"); |
|
$r->print("Problems creating new Excel file. ". |
|
"This error has been logged. ". |
|
"Please alert your LON-CAPA administrator"); |
|
return undef; |
|
} |
|
# |
|
# The excel spreadsheet stores temporary data in files, then put them |
|
# together. If needed we should be able to disable this (memory only). |
|
# The temporary directory must be specified before calling 'addworksheet'. |
|
# File::Temp is used to determine the temporary directory. |
|
$workbook->set_tempdir('/home/httpd/perl/tmp'); |
|
# |
|
# Determine the name to give the worksheet |
|
return ($workbook,$filename); |
|
} |
} |
|
|
sub outsheet_excel { |
sub outsheet_excel { |
my $self = shift; |
my $self = shift; |
my ($r) = @_; |
my ($r) = @_; |
$r->print("<h2>Preparing Excel Spreadsheet</h2>"); |
my $connection = $r->connection(); |
|
# |
|
$r->print($self->html_report_error()); |
|
$r->rflush(); |
# |
# |
# Create excel worksheet |
$r->print("<h2>".&mt('Preparing Excel Spreadsheet')."</h2>"); |
my ($workbook,$filename) = $self->create_excel_spreadsheet($r); |
# |
|
# Create excel workbook |
|
my ($workbook,$filename,$format)=&Apache::loncommon::create_workbook($r); |
return if (! defined($workbook)); |
return if (! defined($workbook)); |
# |
# |
# Create main worksheet |
# Create main worksheet |
Line 1349 sub outsheet_excel {
|
Line 1482 sub outsheet_excel {
|
# Write excel header |
# Write excel header |
foreach my $value ($self->get_title()) { |
foreach my $value ($self->get_title()) { |
$cols_output = 0; |
$cols_output = 0; |
$worksheet->write($rows_output++,$cols_output,$value); |
$worksheet->write($rows_output++,$cols_output,$value,$format->{'h1'}); |
} |
} |
$rows_output++; # skip a line |
$rows_output++; # skip a line |
# |
# |
# Write summary/export row |
# Write summary/export row |
$cols_output = 0; |
$cols_output = 0; |
$self->excel_output_row($worksheet,0,$rows_output++,'Summary'); |
$self->excel_output_row($worksheet,0,$rows_output++,'Summary', |
|
$format->{'b'}); |
$rows_output++; # skip a line |
$rows_output++; # skip a line |
# |
# |
$self->excel_rows($worksheet,$cols_output,$rows_output); |
$self->excel_rows($connection,$worksheet,$cols_output,$rows_output, |
|
$format); |
# |
# |
# |
# |
# Close the excel file |
# Close the excel file |
Line 1376 sub outsheet_excel {
|
Line 1511 sub outsheet_excel {
|
sub outsheet_csv { |
sub outsheet_csv { |
my $self = shift; |
my $self = shift; |
my ($r) = @_; |
my ($r) = @_; |
|
my $connection = $r->connection(); |
|
# |
|
$r->print($self->html_report_error()); |
|
$r->rflush(); |
|
# |
my $csvdata = ''; |
my $csvdata = ''; |
my @Values; |
my @Values; |
# |
# |
# Open the csv file |
# Open the csv file |
my $filename = '/prtspool/'. |
my $filename = '/prtspool/'. |
$ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. |
$env{'user.name'}.'_'.$env{'user.domain'}.'_'. |
time.'_'.rand(1000000000).'.csv'; |
time.'_'.rand(1000000000).'.csv'; |
my $file; |
my $file; |
unless ($file = Apache::File->new('>'.'/home/httpd'.$filename)) { |
unless ($file = Apache::File->new('>'.'/home/httpd'.$filename)) { |
$r->log_error("Couldn't open $filename for output $!"); |
$r->log_error("Couldn't open $filename for output $!"); |
$r->print("Problems occured in writing the csv file. ". |
$r->print(&mt("Problems occured in writing the csv file. ". |
"This error has been logged. ". |
"This error has been logged. ". |
"Please alert your LON-CAPA administrator."); |
"Please alert your LON-CAPA administrator.")); |
$r->print("<pre>\n".$csvdata."</pre>\n"); |
$r->print("<pre>\n".$csvdata."</pre>\n"); |
return 0; |
return 0; |
} |
} |
Line 1399 sub outsheet_csv {
|
Line 1539 sub outsheet_csv {
|
} |
} |
# |
# |
# Output the body of the spreadsheet |
# Output the body of the spreadsheet |
$self->csv_rows($file); |
$self->csv_rows($connection,$file); |
# |
# |
# Close the csv file |
# Close the csv file |
close($file); |
close($file); |
$r->print('<br /><br />'. |
$r->print('<br /><br />'. |
'<a href="'.$filename.'">Your CSV spreadsheet.</a>'."\n"); |
'<a href="'.$filename.'">'.&mt('Your CSV spreadsheet.').'</a>'."\n"); |
# |
# |
return 1; |
return 1; |
} |
} |
Line 1440 sub outsheet_xml {
|
Line 1580 sub outsheet_xml {
|
## But not on this day |
## But not on this day |
my $Str = '<spreadsheet type="'.$self->{'type'}.'">'."\n"; |
my $Str = '<spreadsheet type="'.$self->{'type'}.'">'."\n"; |
while (my ($cell,$formula) = each(%{$self->{'formulas'}})) { |
while (my ($cell,$formula) = each(%{$self->{'formulas'}})) { |
if ($cell =~ /^template_(\d+)/) { |
if ($cell =~ /^template_(\w+)/) { |
my $col = $1; |
my $col = $1; |
$Str .= '<template col="'.$col.'">'.$formula.'</template>'."\n"; |
$Str .= '<template col="'.$col.'">'.$formula.'</template>'."\n"; |
} else { |
} else { |
my ($row,$col) = ($cell =~ /^([A-z])(\d+)/); |
my ($col,$row) = ($cell =~ /^([A-z])(\d+)/); |
next if (! defined($row) || ! defined($col)); |
next if (! defined($row) || ! defined($col)); |
$Str .= '<field row="'.$row.'" col="'.$col.'" >'.$formula.'</cell>' |
next if ($row != 0); |
|
$Str .= |
|
'<field row="'.$row.'" col="'.$col.'" >'.$formula.'</field>' |
."\n"; |
."\n"; |
} |
} |
} |
} |
$Str.="</spreadsheet>"; |
$Str.="</spreadsheet>"; |
|
$r->print("<pre>\n\n\n".$Str."\n\n\n</pre>"); |
return $Str; |
return $Str; |
} |
} |
|
|
Line 1477 sub parse_sheet {
|
Line 1620 sub parse_sheet {
|
$formulas{$cell} = $formula; |
$formulas{$cell} = $formula; |
$sources{$cell} = $source if (defined($source)); |
$sources{$cell} = $source if (defined($source)); |
$parser->get_text('/field'); |
$parser->get_text('/field'); |
} |
} elsif ($token->[1] eq 'template') { |
if ($token->[1] eq 'template') { |
|
$formulas{'template_'.$token->[2]->{'col'}}= |
$formulas{'template_'.$token->[2]->{'col'}}= |
$parser->get_text('/template'); |
$parser->get_text('/template'); |
} |
} |
Line 1532 sub load {
|
Line 1674 sub load {
|
# Not cached, need to read |
# Not cached, need to read |
if (! defined($filename)) { |
if (! defined($filename)) { |
$formulas = $self->load_system_default_sheet(); |
$formulas = $self->load_system_default_sheet(); |
} elsif($self->filename() =~ /^\/res\/.*\.spreadsheet$/) { |
} elsif($filename =~ /^\/res\/.*\.spreadsheet$/) { |
# Load a spreadsheet definition file |
# Load a spreadsheet definition file |
my $sheetxml=&Apache::lonnet::getfile |
my $sheetxml=&Apache::lonnet::getfile |
(&Apache::lonnet::filelocation('',$filename)); |
(&Apache::lonnet::filelocation('',$filename)); |
Line 1573 sub load {
|
Line 1715 sub load {
|
sub set_row_sources { |
sub set_row_sources { |
my $self = shift; |
my $self = shift; |
while (my ($cell,$value) = each(%{$self->{'formulas'}})) { |
while (my ($cell,$value) = each(%{$self->{'formulas'}})) { |
next if ($cell !~ /^A(\d+)/ && $1 > 0); |
next if ($cell !~ /^A(\d+)/ || $1 < 1); |
my $row = $1; |
my $row = $1; |
$self->{'row_source'}->{$row} = $value; |
$self->{'row_source'}->{$row} = $value; |
} |
} |
Line 1595 sub set_row_numbers {
|
Line 1737 sub set_row_numbers {
|
## |
## |
sub exportrow { |
sub exportrow { |
my $self = shift; |
my $self = shift; |
|
if (exists($self->{'badcalc'}) && $self->{'badcalc'}) { |
|
return (); |
|
} |
my @exportarray; |
my @exportarray; |
foreach my $column (@UC_Columns) { |
foreach my $column (@UC_Columns) { |
push(@exportarray,$self->value($column.'0')); |
push(@exportarray,$self->value($column.'0')); |
Line 1625 sub save {
|
Line 1770 sub save {
|
my $reply = &Apache::lonnet::put($filename,\%f,$cdom,$cnum); |
my $reply = &Apache::lonnet::put($filename,\%f,$cdom,$cnum); |
return $reply if ($reply ne 'ok'); |
return $reply if ($reply ne 'ok'); |
$reply = &Apache::lonnet::put($stype.'_spreadsheets', |
$reply = &Apache::lonnet::put($stype.'_spreadsheets', |
{$filename => $ENV{'user.name'}.'@'.$ENV{'user.domain'}}, |
{$filename => $env{'user.name'}.'@'.$env{'user.domain'}}, |
$cdom,$cnum); |
$cdom,$cnum); |
return $reply if ($reply ne 'ok'); |
return $reply if ($reply ne 'ok'); |
if ($makedef) { |
if ($makedef) { |
Line 1635 sub save {
|
Line 1780 sub save {
|
return $reply if ($reply ne 'ok'); |
return $reply if ($reply ne 'ok'); |
} |
} |
if ($self->is_default()) { |
if ($self->is_default()) { |
&Apache::lonnet::expirespread('','',$self->{'type'},''); |
if ($self->{'type'} eq 'studentcalc') { |
if ($self->{'type'} eq 'assesscalc') { |
&Apache::lonnet::expirespread('','','studentcalc',''); |
|
} elsif ($self->{'type'} eq 'assesscalc') { |
|
&Apache::lonnet::expirespread('','','assesscalc',''); |
&Apache::lonnet::expirespread('','','studentcalc',''); |
&Apache::lonnet::expirespread('','','studentcalc',''); |
} |
} |
} |
} |
Line 1649 sub save {
|
Line 1796 sub save {
|
|
|
sub save_tmp { |
sub save_tmp { |
my $self = shift; |
my $self = shift; |
my $filename=$ENV{'user.name'}.'_'. |
my $filename=$env{'user.name'}.'_'. |
$ENV{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. |
$env{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. |
$self->{'filename'}; |
$self->{'filename'}; |
$filename=~s/\W/\_/g; |
$filename=~s/\W/\_/g; |
$filename=$Apache::lonnet::tmpdir.$filename.'.tmp'; |
$filename=$Apache::lonnet::tmpdir.$filename.'.tmp'; |
Line 1669 sub save_tmp {
|
Line 1816 sub save_tmp {
|
|
|
sub load_tmp { |
sub load_tmp { |
my $self = shift; |
my $self = shift; |
my $filename=$ENV{'user.name'}.'_'. |
my $filename=$env{'user.name'}.'_'. |
$ENV{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. |
$env{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. |
$self->{'filename'}; |
$self->{'filename'}; |
$filename=~s/\W/\_/g; |
$filename=~s/\W/\_/g; |
$filename=$Apache::lonnet::tmpdir.$filename.'.tmp'; |
$filename=$Apache::lonnet::tmpdir.$filename.'.tmp'; |
Line 1728 sub othersheets {
|
Line 1875 sub othersheets {
|
$self->{'cdom'}, $self->{'cnum'}); |
$self->{'cdom'}, $self->{'cnum'}); |
my ($tmp) = keys(%results); |
my ($tmp) = keys(%results); |
if ($tmp =~ /^(con_lost|error|no_such_host)/i ) { |
if ($tmp =~ /^(con_lost|error|no_such_host)/i ) { |
@alternatives = ('Default'); |
@alternatives = (&mt('Default')); |
} else { |
} else { |
@alternatives = ('Default', sort (keys(%results))); |
@alternatives = (&mt('Default'), sort (keys(%results))); |
} |
} |
return @alternatives; |
return @alternatives; |
} |
} |