This is an old revision of the document!
If XML-RPC is enabled, an external program written in many different programming languages can communicate with POPFile to use its services. The POPFile API is exposed via the UI::XMLRPC module which was first shipped with the 0.22.0 release. The UI::XMLRPC module requires some extra Perl components not used by a standard POPFile installation.
Full details of the API and methods can be found here: POPFile's XML-RPC
General information about XML-RPC can be found here: XMLRPC.com
The Windows installer offers the UI::XMLRPC module as an optional component (it is not part of the default installation). When the optional UI::XMLRPC module is installed, the Windows installer will also install the extra Perl components the module requires.
Your XMLRPC client can be run on any machine and can be written in any language. The client is not supplied, you must supply your own. Sample Perl, Python, Delphi and NSBasic/CE clients are provided below.
The XML-RPC listen port can be configured on POPFile's Configuration page in the Module Options section. Note that the configuration option will not be displayed unless the UI::XMLRPC.pm module is installed and POPFile has been restarted to recognize the module's presence.
When installed, the module will add a new security option to the POPFile UI's Security Page under the server section. The option “Accept XML-RPC connections from remote machines (requires POPFile restart)” will appear. To permit access from non-localhost machines, you must set this option to yes.
Note: If you use the Windows installer to install the UI::XMLRPC module then these Perl components will automatically be installed for you.
The following Perl modules must be installed on the machine running POPFile. Additionally, the SOAP::Lite module would be required on any client machine using a Perl client to access POPFile via XMLRPC.
ppm >install SOAP-Lite
use strict; use XMLRPC::Lite; my $sk = XMLRPC::Lite ->proxy('http://localhost:8081/RPC2') -> call('POPFile/API.get_session_key','admin',//) -> result; print XMLRPC::Lite ->proxy('http://localhost:8081/RPC2') -> call('POPFile/API.classify',$sk,'spam.txt') -> result; XMLRPC::Lite ->proxy('http://localhost:8081/RPC2') -> call('POPFile/API.release_session_key',$sk);
Saving the above as testxml.pl and running it with test message 'spam.txt' with a properly configured system will result in the following output:
perl testxml.pl spam
from xmlrpclib import ServerProxy POPFile = ServerProxy("http://localhost:8081") pf = POPFile.POPFile.API # naming shortcut to make things easier key = pf.get_session_key("admin","") print pf.classify(key, "spam.txt") pf.release_session_key(key)
Saving the above as testxml.py and running it with test message 'spam.txt' with a properly configured system will result in the following output:
python testxml.py spam
program popdelphi; {$APPTYPE CONSOLE} uses sysutils, xmlrpctypes, xmlrpcclient; var caller: TCaller; func: TFunction; rslt: TResult; SessionKey: String; MessageBucket: String; begin caller := TCaller.Create; caller.EndPoint := '/RPC2'; caller.HostName := '127.0.0.1'; caller.HostPort := 8081; func := TFunction.Create; func.ObjectMethod := 'POPFile/API.get_session_key'; func.AddParam('admin'); func.AddParam(//); rslt := caller.Execute(func); SessionKey := rslt.GetString; func.ObjectMethod := 'POPFile/API.classify'; func.AddParam(SessionKey); func.AddParam(ExpandFileName(ParamStr(1))); rslt := caller.Execute(func); MessageBucket := rslt.GetString; Writeln(MessageBucket); func.ObjectMethod := 'POPFile/API.release_session_key'; func.AddParam(SessionKey); caller.Free; func.Free; end.
This implementation uses xmlrpctypes and xmlrpcclient which are available in Delphi XML-RPC library. You will also need Indy - Internet Direct Components.
Saving and compiling the above will create popdelphi.exe. Running it in a DOS prompt (a default path would be interesting), passing a message file name as argument and using a properly configured system, will result in the following output example:
popdelphi popfile99.msg spam
AddObject "PocketXMLRPC.Factory","xmlrpc" Set popfile = xmlrpc.proxy("http://192.168.200.1:8081/RPC2","POPFile/API.") sessionKey = popfile.get_session_key("admin", "") message = MsgBox("POPFile Session Key is " & sessionKey, vbInformation, "POPFile Message") Print popfile.classify(sessionKey,"C:\spam.txt") popfile.release_session_key(sessionKey)
This implementation uses NS Basic/CE for Windows CE. You will also need **PocketHTTP** and **PocketXML-RPC** COM components.
Remember that, in this example, you are not accessing localhost, you are outside your POPFile default installation. So, you will need to point your mobile device to a valid network IP where your POPFile is running. In this case, 192.168.200.1 is the desktop IP where POPFile is running. Your mobile device will be accessing XMLRPC interface via bluetooth network or WiFI. Considering that, you will also need to Accept XML-RPC connections from remote machines. This may be done using Security tab and setting this feature to Yes.
use strict; use XMLRPC::Lite; my $xml= XMLRPC::Lite -> proxy('http://localhost:8081/RPC2')->on_fault(sub{}); # # Get a session key from POPFile # my $sk = $xml->call("POPFile/API.get_session_key",'admin',//); my $key = $sk->result; my $method = "POPFile/API.$ARGV[0]"; my @params = @ARGV[1..10]; unshift @params,$key; my $can = $xml->can($method); my $res = eval {$xml->call($method,@params)}; if ($@) { print join("\n","syntax error: " ,$@); exit(1); } elsif ($can && !UNIVERSAL::isa($res => 'XMLRPC::SOM')) { print $res; } elsif (defined($res) && $res->fault) { print join ("\n","XMLRPC FAULT: ", @{$res->fault}{'faultCode','faultString'}); exit(1); } elsif (!$xml->transport->is_success) { print join ("\n","TRANSPORT ERROR: ", $xml->transport->status); } else { print join ("\n",$res->paramsall); } # # Release the session key # $xml->call("POPFile/API.release_session_key",$key); # # All Done # exit(0);
Saving the above as testxml.pl and running it with commandline parameters shown returns the result of the API call.
perl testxml.pl get_bucket_parameter spam count 9418 perl testxml.pl get_bucket_parameter spam fpcount 24 perl testxml.pl get_bucket_parameter spam fncount 43 perl testxml.pl get_bucket_color spam red perl testxml.pl get_bucket_word_count spam 37135 perl testxml.pl get_bucket_unique_count spam 9407 perl testxml.pl get_buckets magnet normal spam
Implement pipe.pl as an XMLRPC client
-!/usr/bin/perl use strict; use XMLRPC::Lite; - we want secure temporary files, though this script will usually be run as a user use File::Temp qw/tempfile tempdir/; - a folder we can access that will go away when we exit my $temp_dir = tempdir( CLEANUP => 1); - and a temporary file, with the full path specified my ($fh_in, $filename_in) = tempfile('popfileinXXXXXXX', SUFFIX => ".msg", UNLINK => 1 , DIR => $temp_dir); - act like a pipe, reading from STDIN while (<STDIN>) { print $fh_in $_; } - POPFile expects a closed file close $fh_in; - create a secure output file my ($fh_out, $filename_out) = tempfile('popfileoutXXXXXXX', SUFFIX => ".msg", UNLINK => 1, DIR => $temp_dir); - our XMLRPC proxy my $xmlrpc = XMLRPC::Lite ->proxy('http://localhost:8086/RPC2'); - say hello and get a session key my $sk = $xmlrpc-> call('POPFile/API.get_session_key','admin',//) -> result; - this does the work $xmlrpc-> call('POPFile/API.handle_message',$sk,$filename_in,$filename_out) -> result; - say goodbye $xmlrpc-> call('POPFile/API.release_session_key',$sk); - continue acting like a pipe, and print to STDOUT while (<$fh_out>) { print $_; } - exit, and File::Temp cleans up exit(0);
Full access to POPFile's API (declared in POPFile::API module) through UI::XMLRPC module. For further documentation on API syntax, see the Classifier::Bayes module that ships with POPFile.
Note that you must obtain a session_key using the get_session_key API call in order to use any of the API's. You should release the key using release_session_key when you are finished.
The XML-RPC available methods are:
Subroutine Name | Usage comments | ||
get_session_key |
Should you find anything in the documentation that is incomplete, unclear, outdated or just plain wrong, please let us know and leave a note in the Documentation Forum.