X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/055179cb4cc9b8bc9b204e1a9f83b1f59e13824e..b0b87d15843db10b6ff7a4e30ff8bf110e229075:/IkiWiki/Plugin/external.pm?ds=inline diff --git a/IkiWiki/Plugin/external.pm b/IkiWiki/Plugin/external.pm index 8d1baa587..ba6c7d8b9 100644 --- a/IkiWiki/Plugin/external.pm +++ b/IkiWiki/Plugin/external.pm @@ -1,6 +1,6 @@ #!/usr/bin/perl # Support for external plugins written in other languages. -# Communication via XML RPC a pipe. +# Communication via XML RPC to a pipe. # See externaldemo for an example of a plugin that uses this. package IkiWiki::Plugin::external; @@ -29,6 +29,7 @@ sub import { #{{{ $plugins{$plugin}={in => $plugin_read, out => $plugin_write, pid => $pid, accum => ""}; + $RPC::XML::ENCODING="utf-8"; rpc_call($plugins{$plugin}, "import"); } #}}} @@ -58,14 +59,31 @@ sub rpc_call ($$;@) { #{{{ error("XML RPC parser failure: $r") unless ref $r; if ($r->isa('RPC::XML::response')) { my $value=$r->value; - if ($value->isa('RPC::XML::array')) { + if ($r->is_fault($value)) { + # throw the error as best we can + print STDERR $value->string."\n"; + return ""; + } + elsif ($value->isa('RPC::XML::array')) { return @{$value->value}; } elsif ($value->isa('RPC::XML::struct')) { - return %{$value->value}; - } - elsif ($value->isa('RPC::XML::fault')) { - die $value->string; + my %hash=%{$value->value}; + + # XML-RPC v1 does not allow for + # nil/null/None/undef values to be + # transmitted, so until + # XML::RPC::Parser honours v2 + # (), external plugins send + # a hash with one key "null" pointing + # to an empty string. + if (exists $hash{null} && + $hash{null} eq "" && + int(keys(%hash)) == 1) { + return undef; + } + + return %hash; } else { return $value->value; @@ -89,6 +107,14 @@ sub rpc_call ($$;@) { #{{{ error("XML RPC call error, unknown function: $name"); } + # XML-RPC v1 does not allow for nil/null/None/undef + # values to be transmitted, so until XML::RPC::Parser + # honours v2 (), send a hash with one key "null" + # pointing to an empty string. + if (! defined $ret) { + $ret={"null" => ""}; + } + my $string=eval { RPC::XML::response->new($ret)->as_string }; if ($@ && ref $ret) { # One common reason for serialisation to @@ -125,9 +151,10 @@ sub setvar ($$$;@) { #{{{ my $plugin=shift; my $varname="IkiWiki::".shift; my $key=shift; + my $value=shift; no strict 'refs'; - my $ret=$varname->{$key}=@_; + my $ret=$varname->{$key}=$value; use strict 'refs'; return $ret; } #}}} @@ -146,8 +173,22 @@ sub setstate ($$$$;@) { #{{{ my $page=shift; my $id=shift; my $key=shift; + my $value=shift; + + return $IkiWiki::pagestate{$page}{$id}{$key}=$value; +} #}}} + +sub getargv ($) { #{{{ + my $plugin=shift; + + return \@ARGV; +} #}}} + +sub setargv ($@) { #{{{ + my $plugin=shift; + my $array=shift; - return $IkiWiki::pagestate{$page}{$id}{$key}=@_; + @ARGV=@$array; } #}}} sub inject ($@) { #{{{ @@ -176,7 +217,7 @@ sub hook ($@) { #{{{ delete $params{call}; IkiWiki::hook(%params, call => sub { - IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_) + IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_); }); } #}}}