Skip to content

Commit

Permalink
Item12873: making proper use of store interface
Browse files Browse the repository at this point in the history
- attach generated images if possible
- only generate images when required
- delete outdated images 
- lock down image types to gif,jpeg,png and svg ... html5 canvases are pretty different
- allow to generate dynamic size svg images now



git-svn-id: http://svn.foswiki.org/trunk/GnuPlotPlugin@17617 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
MichaelDaum authored and MichaelDaum committed Apr 30, 2014
1 parent cb23ccb commit 2d03547
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 60 deletions.
23 changes: 15 additions & 8 deletions data/System/GnuPlotPlugin.txt
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" comment="reprev" date="1398868193" format="1.1" reprev="15" version="15"}%
%META:TOPICINFO{author="ProjectContributor" comment="reprev" date="1398880089" format="1.1" reprev="16" version="16"}%
---+!! %TOPIC%

%SHORTDESCRIPTION{default=""}%
Expand Down Expand Up @@ -28,49 +28,49 @@ The following images are examples of plots generated by !GnuPlot:

%IF{"context GnuPlotPluginEnabled"
then="$percntGNUPLOT{\"TestInstall\" type=\"svg\"}$percnt"
else="<img src='%ATTACHURLPATH%/TestInstall.svg' alt='TestInstall' width='639' height='517' />"
else="<img src='%ATTACHURLPATH%/gnuplot_655072823f5c098a63bd1bb4b51d43fd_TestInstall.svg' alt='TestInstall' width='639' height='517' />"
}%

---+++ Multi graphs with errorbars, datafile based

%IF{"context GnuPlotPluginEnabled"
then="$percntGNUPLOT{\"MultigraphWithErrorbars\" type=\"svg\"}$percnt"
else="<img src='%ATTACHURLPATH%/MultigraphWithErrorbars.svg' alt="MultigraphWithErrorbars' width='631' height='517' />"
else="<img src='%ATTACHURLPATH%/gnuplot_56c40163966ced3994a99fc1f060f6e1_MultigraphWithErrorbars.svg' alt="MultigraphWithErrorbars' width='631' height='517' />"
}%

---+++ Damped sinus, datafile based

%IF{"context GnuPlotPluginEnabled"
then="$percntGNUPLOT{\"DampedSinus\" type=\"svg\"}$percnt"
else="<img src='%ATTACHURLPATH%/DampedSinus.svg' alt='DampedSinus' width='647' height='516' />"
else="<img src='%ATTACHURLPATH%/gnuplot_c96b576d7a7ff521cf242137e3a73048_DampedSinus.svg' alt='DampedSinus' width='647' height='516' />"
}%

---+++ Map of Denmark, datafile based (data from CIA World Data Bank II)

%IF{"context GnuPlotPluginEnabled"
then="$percntGNUPLOT{\"CIAWorldDataBankIIDenmark\" type=\"svg\"}$percnt"
else="<img src='%ATTACHURLPATH%/CIAWorldDataBankIIDenmark.svg' alt='CIAWorldDataBankIIDenmark' width='635' height='518' />"
else="<img src='%ATTACHURLPATH%/gnuplot_1ac8b9f150aeb9dd95e56ca9e8977a07_CIAWorldDataBankIIDenmark.svg' alt='CIAWorldDataBankIIDenmark' width='635' height='518' />"
}%

---+++ Interlocking Tori (3D)

%IF{"context GnuPlotPluginEnabled"
then="$percntGNUPLOT{\"InterlockingTori\" type=\"svg\"}$percnt"
else="<img src='%ATTACHURLPATH%/InterlockingTori.svg' alt='InterlockingTori' />"
else="<img src='%ATTACHURLPATH%/gnuplot_26c785a639935a588e205850a8744f76_InterlockingTori.svg' alt='InterlockingTori' />"
}%

---+++ Blue Whale (3D), datafile based

%IF{"context GnuPlotPluginEnabled"
then="$percntGNUPLOT{\"BlueWhale\" type=\"svg\"}$percnt"
else="<img src='%ATTACHURLPATH%/BlueWhale.svg' alt='BlueWhale' />"
else="<img src='%ATTACHURLPATH%/gnuplot_0578c5af104caee4c9eefcf4183da270_BlueWhale.svg' alt='BlueWhale' />"
}%

---+++ Alternative <nop>GnuPlot render sizes, Rosenbrock Function

%IF{"context GnuPlotPluginEnabled"
then="$percntGNUPLOT{\"RosenbrockFunction\" type=\"svg\"}$percnt"
else="<img src='%ATTACHURLPATH%/RosenbrockFunction.svg' alt='RosenbrockFunction.svg' width='640' height='480' />"
else="<img src='%ATTACHURLPATH%/gnuplot_dc49080a70cc4879a80c08603cb17eef_RosenbrockFunction.svg' alt='RosenbrockFunction' width='640' height='480' />"
}%

---++ Installation
Expand Down Expand Up @@ -110,3 +110,10 @@ The following images are examples of plots generated by !GnuPlot:
%META:FILEATTACHMENT{name="CIAWorldDataBankIIDenmark.data" attr="" autoattached="1" comment="Data for <nop>CIAWorldDataBankIIDenmark example" date="1146425499" moveby="micha" movedto="System.GnuPlotPlugin.CIAWorldDataBankIIDenmark.data" movedwhen="1398868039" movefrom="System.GnuPlotPlugin.CIAWorldDataBankIIDenmarkData.data" path="CIAWorldDataBankIIDenmarkData.data" size="403115" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="MultigraphWithErrorbars.data" attr="" autoattached="1" comment="Data for <nop>MultigraphWithErrorbarsData example" date="1146425499" moveby="micha" movedto="System.GnuPlotPlugin.MultigraphWithErrorbars.data" movedwhen="1398868055" movefrom="System.GnuPlotPlugin.MultigraphWithErrorbarsData.data" path="MultigraphWithErrorbarsData.data" size="66" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="DampedSinus.data" attr="" autoattached="1" comment="Data for <nop>DampedSinusData example" date="1146425499" moveby="micha" movedto="System.GnuPlotPlugin.DampedSinus.data" movedwhen="1398868061" movefrom="System.GnuPlotPlugin.DampedSinusData.data" path="DampedSinusData.data" size="4091" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="gnuplot_655072823f5c098a63bd1bb4b51d43fd_TestInstall.svg" attachment="gnuplot_655072823f5c098a63bd1bb4b51d43fd_TestInstall.svg" attr="" comment="Auto-attached by GnuPlotPlugin" date="1398880088" size="9949" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="gnuplot_56c40163966ced3994a99fc1f060f6e1_MultigraphWithErrorbars.svg" attachment="gnuplot_56c40163966ced3994a99fc1f060f6e1_MultigraphWithErrorbars.svg" attr="" comment="Auto-attached by GnuPlotPlugin" date="1398880088" size="9527" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="gnuplot_c96b576d7a7ff521cf242137e3a73048_DampedSinus.svg" attachment="gnuplot_c96b576d7a7ff521cf242137e3a73048_DampedSinus.svg" attr="" comment="Auto-attached by GnuPlotPlugin" date="1398880088" size="20924" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="gnuplot_1ac8b9f150aeb9dd95e56ca9e8977a07_CIAWorldDataBankIIDenmark.svg" attachment="gnuplot_1ac8b9f150aeb9dd95e56ca9e8977a07_CIAWorldDataBankIIDenmark.svg" attr="" comment="Auto-attached by GnuPlotPlugin" date="1398880089" size="359423" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="gnuplot_26c785a639935a588e205850a8744f76_InterlockingTori.svg" attachment="gnuplot_26c785a639935a588e205850a8744f76_InterlockingTori.svg" attr="" comment="Auto-attached by GnuPlotPlugin" date="1398880089" size="84516" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="gnuplot_0578c5af104caee4c9eefcf4183da270_BlueWhale.svg" attachment="gnuplot_0578c5af104caee4c9eefcf4183da270_BlueWhale.svg" attr="" comment="Auto-attached by GnuPlotPlugin" date="1398880089" size="67740" user="ProjectContributor" version="1"}%
%META:FILEATTACHMENT{name="gnuplot_dc49080a70cc4879a80c08603cb17eef_RosenbrockFunction.svg" attachment="gnuplot_dc49080a70cc4879a80c08603cb17eef_RosenbrockFunction.svg" attr="" comment="Auto-attached by GnuPlotPlugin" date="1398880089" size="196945" user="ProjectContributor" version="1"}%
4 changes: 4 additions & 0 deletions lib/Foswiki/Plugins/GnuPlotPlugin.pm
Expand Up @@ -45,5 +45,9 @@ sub initPlugin {
return 1;
}

sub beforeSaveHandler {
core->beforeSaveHandler(@_);
}


1;
144 changes: 106 additions & 38 deletions lib/Foswiki/Plugins/GnuPlotPlugin/Core.pm
Expand Up @@ -24,6 +24,7 @@ use Foswiki::Func ();
use Foswiki::Sandbox ();
use Foswiki::Plugins ();
use File::Temp ();
use Digest::MD5 ();
use Assert;

sub new {
Expand Down Expand Up @@ -74,51 +75,105 @@ sub handleGnuPlotTag {
return inlineError("unknown mode '$mode'");
}

my $fileType = $params->{type} || 'png';
# TODO: sanitize fileType
my $type = $params->{type} || 'png';

my $outFile = $this->getPath($web, $topic, $name . '.'. $fileType);
# TODO: support canvas
if ($type =~ /^(gif|jpeg|png|svg)$/) {
$type = $1;
} else {
return inlineError("unsupported type '$type'");
}

my $width = $params->{width} || 640;
$width =~ s/[^\d\.]//g;

my $height = $params->{height} || 480;
$height =~ s/[^\d\.]//g;

$data = $this->expandCommonVariables($web, $topic, $data);
$data = <<"HERE" . $data;
set terminal $fileType size $width,$height
set output "$outFile"
HERE

$this->writeDebug("data=".$data);
my $size = $params->{size};
if (defined $size) {
if ($size =~ /^(\d+)x(\d+)$/) {
$width = $1;
$height = $1;
} elsif ($type eq 'svg' && $size eq 'fixed') {
$size = "$width,$height $size";
} elsif ($type eq 'svg' && $size eq 'dynamic') {
$size = "$width,$height $size";
$width = 'auto';
$height = 'auto';
} else {
return inlineError("invalid size parameter '$size'");
}
} else {
$size = "$width,$height";
$size .= " dynamic" if $type eq 'svg';
}

my $tmpFile = new File::Temp(SUFFIX => '.gnu', UNLINK => ($this->{debug}? 0 : 1));
my $tmpFileName = $tmpFile->filename;
Foswiki::Func::saveFile($tmpFileName, $data);
$data = $this->expandCommonVariables($web, $topic, $data);

$this->writeDebug("tmpFile=".$tmpFileName);
my $digest = Digest::MD5::md5_hex($data, $name, $size);
my $outFile = $this->getImageName($name, $digest, $type);

my $gnuplotCmd = $this->{gnuPlotCmd};
$this->writeDebug("gnuPlotCmd=$gnuplotCmd");

my ($output, $status, $error) = Foswiki::Sandbox->sysCommand(
$gnuplotCmd,
INFILE => $tmpFileName,
);
my $request = Foswiki::Func::getRequestObject();
my $refresh = $request->param("refresh") || '';
$refresh = ($refresh =~ /^(on|gnuplot|image)$/ ? 1:0);

$this->writeDebug("output=$output, status=$status, error=$error");
$this->writeDebug("doing a refresh") if $refresh;

my $result = '';
unless ($error) {
$result = "<img src='%PUBURLPATH%/$web/$topic/$name.$fileType' class='gnuPlotImage' id='gnuplot$name' alt='$name' width='$width' height='$height' />";
if (!$refresh && Foswiki::Func::attachmentExists($web, $topic, $outFile)) {
$this->writeDebug("already found $outFile at $web.$topic ... not generating again");
} else {
my $outPath = File::Temp->new(UNLINK => ($this->{debug}?0:1));

$this->writeDebug("plotting to $outPath");
$data = <<"HERE" . $data;
set terminal $type size $size
set output "$outPath"
HERE

$error =~ s/^".*", line (\d+)/$name, line $1/gm;
$result = "<div class='foswikiAlert'>ERROR: while rendering plot:</div>\n<verbatim>$error</verbatim>";
$this->writeDebug("data=".$data);

my $tmpFile = File::Temp->new(SUFFIX => '.gnu', UNLINK => ($this->{debug}? 0 : 1));
my $tmpFileName = $tmpFile->filename;
Foswiki::Func::saveFile($tmpFileName, $data);

$this->writeDebug("tmpFile=".$tmpFileName);

my $gnuplotCmd = $this->{gnuPlotCmd};
$this->writeDebug("gnuPlotCmd=$gnuplotCmd");

my ($output, $status, $error) = Foswiki::Sandbox->sysCommand(
$gnuplotCmd,
INFILE => $tmpFileName,
);

$this->writeDebug("output=$output, status=$status, error=$error");

if ($error) {
$error =~ s/^".*", line (\d+)/$name, line $1/gm;
return inlineError("can't rendering plot:\n<verbatim>$error</verbatim>");
}

my $size = (stat($outPath))[7];
$this->writeDebug("size=$size");

# attach
my $wikiName = Foswiki::Func::getWikiName();
if (Foswiki::Func::checkAccessPermission("CHANGE", $wikiName, undef, $topic, $web)) {
Foswiki::Func::saveAttachment($web, $topic, $outFile, {
file => $outPath,
filesize => $size,
minor => 1,
dontlog => 1,
comment => 'Auto-attached by GnuPlotPlugin',
});
} else {
return inlineError("can't generate plot: access denied to attach output to $web.$topic");
};
}

return $result;
# TODO: need a differnt template for type=canvas
return "<img src='%PUBURLPATH%/$web/$topic/$outFile' class='gnuPlotImage' id='gnuplot$name' alt='$name' width='$width' height='$height' />";
}

sub getDataFromAttachment {
Expand Down Expand Up @@ -160,8 +215,8 @@ sub expandCommonVariables {
$data =~ s/^\s*set\s+out(put)?.*$//gm;

# some extras
my $attachDir = $this->getPath($web, $topic);
my $pubDir = Foswiki::Func::getPubDir();
my $pubDir = $Foswiki::cfg{PubDir};
my $attachDir = $pubDir . '/' . $web . '/' . $topic;
$data =~ s/\%ATTACHDIR\%/$attachDir/g;
$data =~ s/\%PUBDIR\%/$pubDir/g;

Expand All @@ -178,20 +233,33 @@ sub sanitizeFileName {
return $fileName;
}

sub getPath {
my ($this, $web, $topic, $attachment) = @_;
sub getImageName {
my ($this, $name, $digest, $type) = @_;

$web =~ s/\./\//g;
return 'gnuplot_'.$digest.'_'.$name.'.'.$type;
}

my $path = Foswiki::Func::getPubDir().'/'.$web.'/'.$topic;
sub deleteImages {
my ($this, $web, $topic, $include) = @_;

File::Path::mkpath($path) unless -d $path;
}

$path .= '/'.$attachment if defined $attachment;
sub beforeSaveHandler {
my ($this, undef, $topic, $web, $meta) = @_;

return $path;
$this->writeDebug("called beforeSaveHandler($web, $topic)");

my $it = $meta->eachAttachment();
while ($it->hasNext()) {
my $file = $it->next();
if ($file =~ /^(gnuplot_[0-9a-f]{32}.*)$/) {
$file = $1;
$this->writeDebug("deleting $file from $web.$topic");
$meta->remove('FILEATTACHMENT', $file);
$meta->removeFromStore($file);
}
}
}


1;

14 changes: 7 additions & 7 deletions lib/Foswiki/Plugins/GnuPlotPlugin/MANIFEST
Expand Up @@ -3,20 +3,20 @@ lib/Foswiki/Plugins/GnuPlotPlugin/Config.spec 0644
lib/Foswiki/Plugins/GnuPlotPlugin/Core.pm 0644
lib/Foswiki/Plugins/GnuPlotPlugin.pm 0644
pub/System/GnuPlotPlugin/BlueWhale.gnu 0644
pub/System/GnuPlotPlugin/BlueWhale.svg 0644
pub/System/GnuPlotPlugin/CIAWorldDataBankIIDenmark.data 0644
pub/System/GnuPlotPlugin/CIAWorldDataBankIIDenmark.gnu 0644
pub/System/GnuPlotPlugin/CIAWorldDataBankIIDenmark.svg 0644
pub/System/GnuPlotPlugin/DampedSinus.data 0644
pub/System/GnuPlotPlugin/DampedSinus.gnu 0644
pub/System/GnuPlotPlugin/DampedSinus.svg 0644
pub/System/GnuPlotPlugin/gnuplot_0578c5af104caee4c9eefcf4183da270_BlueWhale.svg 0644
pub/System/GnuPlotPlugin/gnuplot_1ac8b9f150aeb9dd95e56ca9e8977a07_CIAWorldDataBankIIDenmark.svg 0644
pub/System/GnuPlotPlugin/gnuplot_26c785a639935a588e205850a8744f76_InterlockingTori.svg 0644
pub/System/GnuPlotPlugin/gnuplot_56c40163966ced3994a99fc1f060f6e1_MultigraphWithErrorbars.svg 0644
pub/System/GnuPlotPlugin/gnuplot_655072823f5c098a63bd1bb4b51d43fd_TestInstall.svg 0644
pub/System/GnuPlotPlugin/gnuplot_c96b576d7a7ff521cf242137e3a73048_DampedSinus.svg 0644
pub/System/GnuPlotPlugin/gnuplot_dc49080a70cc4879a80c08603cb17eef_RosenbrockFunction.svg 0644
pub/System/GnuPlotPlugin/InterlockingTori.gnu 0644
pub/System/GnuPlotPlugin/InterlockingTori.svg 0644
pub/System/GnuPlotPlugin/MultigraphWithErrorbars.data 0644
pub/System/GnuPlotPlugin/MultigraphWithErrorbars.gnu 0644
pub/System/GnuPlotPlugin/MultigraphWithErrorbars.svg 0644
pub/System/GnuPlotPlugin/RosenbrockFunction.gnu 0644
pub/System/GnuPlotPlugin/RosenbrockFunction.svg 0644
pub/System/GnuPlotPlugin/TestInstall.gnu 0644
pub/System/GnuPlotPlugin/TestInstall.svg 0644
pub/System/GnuPlotPlugin/whale.dat 0644
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2d03547

Please sign in to comment.