xml-rpc の勉強 その2

by oganosin. 1 Comment

というわけでその2.今回はいきなりレベルアップして
xmlのデータをwordpressにxml-rpc経由でpostする
というプログラムのサンプル。例によって公開できる部分だけ抜き出しているので、このソースはあくまでも雛型です。

以下注意点

  1. STDINがshiftjisなのはxmlの文字コードが実はshiftjisだったから
  2. check wordpressの部分はサーバーの設定のよって違うと思うので適宜変更のこと
  3. 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;

One Response to xml-rpc の勉強 その2

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です