version 1.17, 2003/06/23 19:58:18
|
version 1.25, 2003/09/12 18:59:48
|
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 90 sub new {
|
Line 92 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'}, |
Line 229 sub initialize {
|
Line 231 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 248 sub load_spreadsheet_expirationdates {
|
Line 260 sub load_spreadsheet_expirationdates {
|
sub check_expiration_time { |
sub check_expiration_time { |
my $self = shift; |
my $self = shift; |
my ($time)=@_; |
my ($time)=@_; |
my ($key1,$key2,$key3,$key4); |
return 0 if (! defined($time)); |
|
my ($key1,$key2,$key3,$key4,$key5); |
|
# Description of keys |
|
# |
|
# key1: all sheets of this type have expired |
|
# key2: all sheets of this type for this student |
|
# key3: all sheets of this type in this map for this student |
|
# key4: this assessment sheet for this student |
|
# key5: this assessment sheet for all students |
$key1 = '::'.$self->{'type'}.':'; |
$key1 = '::'.$self->{'type'}.':'; |
$key2 = $self->{'name'}.':'.$self->{'domain'}.':'.$self->{'type'}.':'; |
$key2 = $self->{'name'}.':'.$self->{'domain'}.':'.$self->{'type'}.':'; |
$key3 = $key2.$self->{'container'} if (defined($self->{'container'})); |
$key3 = $key2.$self->{'container'} if (defined($self->{'container'})); |
$key4 = $key2.$self->{'usymb'} if (defined($self->{'usymb'})); |
$key4 = $key2.$self->{'symb'} if (defined($self->{'symb'})); |
foreach my $key ($key1,$key2,$key3,$key4) { |
$key5 = $key1.$self->{'symb'} if (defined($self->{'symb'})); |
|
my $returnvalue = 1; # default to okay |
|
foreach my $key ($key1,$key2,$key3,$key4,$key5) { |
next if (! defined($key)); |
next if (! defined($key)); |
if (exists($expiredates{$key}) &&$expiredates{$key} > $time) { |
if (exists($expiredates{$key}) && $expiredates{$key} > $time) { |
return 0; |
$returnvalue = 0; # need to recompute |
} |
} |
} |
} |
return 1; |
return $returnvalue; |
} |
} |
|
|
###################################################### |
###################################################### |
Line 277 Returns the safe space required by a Spr
|
Line 299 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); |
if (! defined($safeeval)) { |
my $safehole = new Safe::Hole; |
$safeeval = new Safe(shift); |
$safeeval->permit("entereval"); |
my $safehole = new Safe::Hole; |
$safeeval->permit(":base_math"); |
$safeeval->permit("entereval"); |
$safeeval->permit("sort"); |
$safeeval->permit(":base_math"); |
$safeeval->deny(":base_io"); |
$safeeval->permit("sort"); |
$safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT'); |
$safeeval->deny(":base_io"); |
$safehole->wrap(\&mask,$safeeval,'&mask'); |
$safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT'); |
$safeeval->share('$@'); |
$safehole->wrap(\&mask,$safeeval,'&mask'); |
my $code=<<'ENDDEFS'; |
$safeeval->share('$@'); |
|
my $code=<<'ENDDEFS'; |
# ---------------------------------------------------- Inside of the safe space |
# ---------------------------------------------------- Inside of the safe space |
# |
# |
# f: formulas |
# f: formulas |
Line 655 sub calc {
|
Line 682 sub calc {
|
|
|
# ------------------------------------------- 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(); |
# |
# |
Line 669 ENDDEFS
|
Line 697 ENDDEFS
|
$self->{'safe'}->reval($initstring); |
$self->{'safe'}->reval($initstring); |
return $self; |
return $self; |
} |
} |
|
|
|
} |
|
|
###################################################### |
###################################################### |
|
|
=pod |
=pod |
Line 785 sub expandnamed {
|
Line 816 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 1135 sub display {
|
Line 1166 sub display {
|
} elsif ($outputmode eq 'csv') { |
} elsif ($outputmode eq 'csv') { |
$self->outsheet_csv($r); |
$self->outsheet_csv($r); |
} |
} |
|
$self->cleanup(); |
return; |
return; |
} |
} |
|
|
Line 1202 sub html_editable_cell {
|
Line 1234 sub html_editable_cell {
|
$value = &HTML::Entities::encode($value) if ($value !~/ /); |
$value = &HTML::Entities::encode($value) if ($value !~/ /); |
} |
} |
return $value if (! $allowed); |
return $value if (! $allowed); |
# Make the formula safe for outputting |
# |
$formula =~ s/\'/\"/g; |
|
# The formula will be parsed by the browser twice before being |
# The formula will be parsed by the browser twice before being |
# displayed to the user for editing. |
# displayed to the user for editing. |
$formula = &HTML::Entities::encode(&HTML::Entities::encode($formula)); |
# |
# Escape newlines so they make it into the edit window |
# The encoding string "^A-blah" is placed in []'s inside a regexp, so |
$formula =~ s/\n/\\n/gs; |
# we specify the characters we want left alone by putting a '^' in front. |
|
$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 '&' |
|
$formula =~ s/\&/\&/g; |
# Glue everything together |
# Glue everything together |
$result .= "<a href=\"javascript:celledit(\'". |
$result .= "<a href=\"javascript:celledit(\'". |
$name."','".$formula."');\">".$value."</a>"; |
$name."','".$formula."');\">".$value."</a>"; |
Line 1324 sub create_excel_spreadsheet {
|
Line 1360 sub create_excel_spreadsheet {
|
sub outsheet_excel { |
sub outsheet_excel { |
my $self = shift; |
my $self = shift; |
my ($r) = @_; |
my ($r) = @_; |
|
my $connection = $r->connection(); |
$r->print("<h2>Preparing Excel Spreadsheet</h2>"); |
$r->print("<h2>Preparing Excel Spreadsheet</h2>"); |
# |
# |
# Create excel worksheet |
# Create excel worksheet |
Line 1347 sub outsheet_excel {
|
Line 1384 sub outsheet_excel {
|
$self->excel_output_row($worksheet,0,$rows_output++,'Summary'); |
$self->excel_output_row($worksheet,0,$rows_output++,'Summary'); |
$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); |
# |
# |
# |
# |
# Close the excel file |
# Close the excel file |
Line 1365 sub outsheet_excel {
|
Line 1402 sub outsheet_excel {
|
sub outsheet_csv { |
sub outsheet_csv { |
my $self = shift; |
my $self = shift; |
my ($r) = @_; |
my ($r) = @_; |
|
my $connection = $r->connection(); |
my $csvdata = ''; |
my $csvdata = ''; |
my @Values; |
my @Values; |
# |
# |
Line 1388 sub outsheet_csv {
|
Line 1426 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); |
Line 1562 sub load {
|
Line 1600 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 1624 sub save {
|
Line 1662 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 1639 sub save {
|
Line 1679 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->{'usymb'}.'_'. |
$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 1659 sub save_tmp {
|
Line 1699 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->{'usymb'}.'_'. |
$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'; |