diff --git a/data/System/GnuPlotPlugin.txt b/data/System/GnuPlotPlugin.txt index 3ee3245..e7da895 100644 --- a/data/System/GnuPlotPlugin.txt +++ b/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=""}% @@ -28,49 +28,49 @@ The following images are examples of plots generated by !GnuPlot: %IF{"context GnuPlotPluginEnabled" then="$percntGNUPLOT{\"TestInstall\" type=\"svg\"}$percnt" - else="TestInstall" + else="TestInstall" }% ---+++ Multi graphs with errorbars, datafile based %IF{"context GnuPlotPluginEnabled" then="$percntGNUPLOT{\"MultigraphWithErrorbars\" type=\"svg\"}$percnt" - else="MultigraphWithErrorbars' width='631' height='517' />" }% ---+++ Damped sinus, datafile based %IF{"context GnuPlotPluginEnabled" then="$percntGNUPLOT{\"DampedSinus\" type=\"svg\"}$percnt" - else="DampedSinus" + else="DampedSinus" }% ---+++ Map of Denmark, datafile based (data from CIA World Data Bank II) %IF{"context GnuPlotPluginEnabled" then="$percntGNUPLOT{\"CIAWorldDataBankIIDenmark\" type=\"svg\"}$percnt" - else="CIAWorldDataBankIIDenmark" + else="CIAWorldDataBankIIDenmark" }% ---+++ Interlocking Tori (3D) %IF{"context GnuPlotPluginEnabled" then="$percntGNUPLOT{\"InterlockingTori\" type=\"svg\"}$percnt" - else="InterlockingTori" + else="InterlockingTori" }% ---+++ Blue Whale (3D), datafile based %IF{"context GnuPlotPluginEnabled" then="$percntGNUPLOT{\"BlueWhale\" type=\"svg\"}$percnt" - else="BlueWhale" + else="BlueWhale" }% ---+++ Alternative GnuPlot render sizes, Rosenbrock Function %IF{"context GnuPlotPluginEnabled" then="$percntGNUPLOT{\"RosenbrockFunction\" type=\"svg\"}$percnt" - else="RosenbrockFunction.svg" + else="RosenbrockFunction" }% ---++ Installation @@ -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 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 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 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"}% diff --git a/lib/Foswiki/Plugins/GnuPlotPlugin.pm b/lib/Foswiki/Plugins/GnuPlotPlugin.pm index f630ac2..08de3fb 100644 --- a/lib/Foswiki/Plugins/GnuPlotPlugin.pm +++ b/lib/Foswiki/Plugins/GnuPlotPlugin.pm @@ -45,5 +45,9 @@ sub initPlugin { return 1; } +sub beforeSaveHandler { + core->beforeSaveHandler(@_); +} + 1; diff --git a/lib/Foswiki/Plugins/GnuPlotPlugin/Core.pm b/lib/Foswiki/Plugins/GnuPlotPlugin/Core.pm index 5cda8df..2bc1a24 100644 --- a/lib/Foswiki/Plugins/GnuPlotPlugin/Core.pm +++ b/lib/Foswiki/Plugins/GnuPlotPlugin/Core.pm @@ -24,6 +24,7 @@ use Foswiki::Func (); use Foswiki::Sandbox (); use Foswiki::Plugins (); use File::Temp (); +use Digest::MD5 (); use Assert; sub new { @@ -74,10 +75,14 @@ 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; @@ -85,40 +90,90 @@ sub handleGnuPlotTag { 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 = "$name"; + 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 = "
ERROR: while rendering plot:
\n$error"; + $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$error"); + } + + 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 "$name"; } sub getDataFromAttachment { @@ -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; @@ -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; diff --git a/lib/Foswiki/Plugins/GnuPlotPlugin/MANIFEST b/lib/Foswiki/Plugins/GnuPlotPlugin/MANIFEST index a5cb0a6..81236c3 100644 --- a/lib/Foswiki/Plugins/GnuPlotPlugin/MANIFEST +++ b/lib/Foswiki/Plugins/GnuPlotPlugin/MANIFEST @@ -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 diff --git a/pub/System/GnuPlotPlugin/BlueWhale.svg b/pub/System/GnuPlotPlugin/gnuplot_0578c5af104caee4c9eefcf4183da270_BlueWhale.svg similarity index 99% rename from pub/System/GnuPlotPlugin/BlueWhale.svg rename to pub/System/GnuPlotPlugin/gnuplot_0578c5af104caee4c9eefcf4183da270_BlueWhale.svg index d2ed9d0..03e0b05 100644 --- a/pub/System/GnuPlotPlugin/BlueWhale.svg +++ b/pub/System/GnuPlotPlugin/gnuplot_0578c5af104caee4c9eefcf4183da270_BlueWhale.svg @@ -1,7 +1,7 @@ - diff --git a/pub/System/GnuPlotPlugin/CIAWorldDataBankIIDenmark.svg b/pub/System/GnuPlotPlugin/gnuplot_1ac8b9f150aeb9dd95e56ca9e8977a07_CIAWorldDataBankIIDenmark.svg similarity index 99% rename from pub/System/GnuPlotPlugin/CIAWorldDataBankIIDenmark.svg rename to pub/System/GnuPlotPlugin/gnuplot_1ac8b9f150aeb9dd95e56ca9e8977a07_CIAWorldDataBankIIDenmark.svg index e21e1d8..f11623d 100644 --- a/pub/System/GnuPlotPlugin/CIAWorldDataBankIIDenmark.svg +++ b/pub/System/GnuPlotPlugin/gnuplot_1ac8b9f150aeb9dd95e56ca9e8977a07_CIAWorldDataBankIIDenmark.svg @@ -1,7 +1,7 @@ - diff --git a/pub/System/GnuPlotPlugin/InterlockingTori.svg b/pub/System/GnuPlotPlugin/gnuplot_26c785a639935a588e205850a8744f76_InterlockingTori.svg similarity index 99% rename from pub/System/GnuPlotPlugin/InterlockingTori.svg rename to pub/System/GnuPlotPlugin/gnuplot_26c785a639935a588e205850a8744f76_InterlockingTori.svg index ca3c7ce..dc8e9d3 100644 --- a/pub/System/GnuPlotPlugin/InterlockingTori.svg +++ b/pub/System/GnuPlotPlugin/gnuplot_26c785a639935a588e205850a8744f76_InterlockingTori.svg @@ -1,7 +1,7 @@ - diff --git a/pub/System/GnuPlotPlugin/MultigraphWithErrorbars.svg b/pub/System/GnuPlotPlugin/gnuplot_56c40163966ced3994a99fc1f060f6e1_MultigraphWithErrorbars.svg similarity index 99% rename from pub/System/GnuPlotPlugin/MultigraphWithErrorbars.svg rename to pub/System/GnuPlotPlugin/gnuplot_56c40163966ced3994a99fc1f060f6e1_MultigraphWithErrorbars.svg index 09e9755..4702480 100644 --- a/pub/System/GnuPlotPlugin/MultigraphWithErrorbars.svg +++ b/pub/System/GnuPlotPlugin/gnuplot_56c40163966ced3994a99fc1f060f6e1_MultigraphWithErrorbars.svg @@ -1,7 +1,7 @@ - diff --git a/pub/System/GnuPlotPlugin/TestInstall.svg b/pub/System/GnuPlotPlugin/gnuplot_655072823f5c098a63bd1bb4b51d43fd_TestInstall.svg similarity index 99% rename from pub/System/GnuPlotPlugin/TestInstall.svg rename to pub/System/GnuPlotPlugin/gnuplot_655072823f5c098a63bd1bb4b51d43fd_TestInstall.svg index 261072f..bcc66f1 100644 --- a/pub/System/GnuPlotPlugin/TestInstall.svg +++ b/pub/System/GnuPlotPlugin/gnuplot_655072823f5c098a63bd1bb4b51d43fd_TestInstall.svg @@ -1,7 +1,7 @@ - diff --git a/pub/System/GnuPlotPlugin/DampedSinus.svg b/pub/System/GnuPlotPlugin/gnuplot_c96b576d7a7ff521cf242137e3a73048_DampedSinus.svg similarity index 99% rename from pub/System/GnuPlotPlugin/DampedSinus.svg rename to pub/System/GnuPlotPlugin/gnuplot_c96b576d7a7ff521cf242137e3a73048_DampedSinus.svg index 28dba8e..6305dbf 100644 --- a/pub/System/GnuPlotPlugin/DampedSinus.svg +++ b/pub/System/GnuPlotPlugin/gnuplot_c96b576d7a7ff521cf242137e3a73048_DampedSinus.svg @@ -1,7 +1,7 @@ - diff --git a/pub/System/GnuPlotPlugin/RosenbrockFunction.svg b/pub/System/GnuPlotPlugin/gnuplot_dc49080a70cc4879a80c08603cb17eef_RosenbrockFunction.svg similarity index 99% rename from pub/System/GnuPlotPlugin/RosenbrockFunction.svg rename to pub/System/GnuPlotPlugin/gnuplot_dc49080a70cc4879a80c08603cb17eef_RosenbrockFunction.svg index 0502d4f..57752e4 100644 --- a/pub/System/GnuPlotPlugin/RosenbrockFunction.svg +++ b/pub/System/GnuPlotPlugin/gnuplot_dc49080a70cc4879a80c08603cb17eef_RosenbrockFunction.svg @@ -1,7 +1,7 @@ -