xml-rpc の勉強 その2
というわけでその2.今回はいきなりレベルアップして
xmlのデータをwordpressにxml-rpc経由でpostする
というプログラムのサンプル。例によって公開できる部分だけ抜き出しているので、このソースはあくまでも雛型です。
以下注意点
- STDINがshiftjisなのはxmlの文字コードが実はshiftjisだったから
- check wordpressの部分はサーバーの設定のよって違うと思うので適宜変更のこと
- for文が降順なのはxmlのデータが生成時間の新しいものから並んでいるのでそれをwordpressでも引き継ぎたかったから
しかし、wordpressには罠が潜んでした・・・。
wordpressは存在しない投稿スラッグを指定した場合、指定された投稿スラッグに近い投稿スラッグがあればそちらにリダイレクトしてくれる。
たとえばこの記事のパーマリンクは
http://www.oganosin.net/blog/programming/xml-rpc-part2/
なんだけど
http://www.oganosin.net/blog/programming/xml-rpc-part/
でもアクセスできるはず。
なので下記のスクリプトの重複チェックには穴があります。
#!/usr/bin/perl
use strict;
use warnings;
use Encode;
use encoding "utf-8", STDIN => "shiftjis", STDOUT => "utf-8";
use LWP::UserAgent;
use HTTP::Request;
use XML::LibXML;
use XMLRPC::Lite;
#use XMLRPC::Lite trace => 'debug' ;
use Data::Dumper;
use File::Basename;
use MIME::Base64;
use MIME::Parser;
use Getopt::Std;
use vars qw($interfaceurl $blogid $username $passwd $target);
BEGIN {
$interfaceurl = "http://www.example.com/wp/xmlrpc.php";
$blogid = 1;
$username = 'xxxxx';
$passwd = 'xxxxx';
$target = '';
}
sub read_bin_file(){
my ($filename) = @_;
#--------------------
# read in the picture
my $fh = IO::Handle->new();
open($fh, $filename) or die "$! $filename";
local($/) = undef; # slurp
binmode($fh);
my $bits = <$fh>;
close($fh);
return $bits;
}
# get XML data
my $ua = new LWP::UserAgent;
my $req = new HTTP::Request(GET =>
"http://www.example.com/data.xml");
my $resp = $ua->request($req);
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($resp->content);
my $rpc = XMLRPC::Lite->new();
my @items = $doc->getElementsByTagName('item');
for(my $i=$#items; $i>=0; $i--){
my ($wp_slug,$description,$excerpt,$img);
# edit data
# check wordpress
my $posturl = "http://www.example.com/wp/uncategorize/"
. $wp_slug
. "/";
my $req = new HTTP::Request(HEAD => $posturl);
my $resp = $ua->request($req);
if($resp->{'_rc'} eq '200'){
print STDERR "Alredy convert URL: $posturl\n";
next;
}
my $rpc = XMLRPC::Lite->new();
$rpc->proxy($interfaceurl);
my $res = $rpc->call("metaWeblog.newMediaObject",
$blogid,
$username,
$passwd,
{
'bits' => XMLRPC::Data->type('base64',
&read_bin_file($img)),
'type' => "image/jpeg",
'name' => basename($img),
}
)->result;
$img = $res->{'url'};
$res = $rpc->call("metaWeblog.newPost",
$blogid,
$username,
$passwd,
{
'title' =>
Encode::encode('utf8', "$title"),
'description' =>
Encode::encode('utf8', "$description"),
'dateCreated' =>
Encode::encode('utf8', "$date"),
'mt_excerpt' =>
Encode::encode('utf8', "$excerpt"),
'wp_slug' => $wp_slug,
'custom_fields'=> [
{
'key' => '',
'value' => '',
},
],
},
1
)->result;
my $postid = $res;
$res = $rpc->call("mt.setPostCategories",
$postid,
$username,
$passwd,
[
{
"categoryId" => 1,
"isPrimary" => 1
}
]
)-> result;
}
exit 1;

