<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
>

<channel>
	<title>oganosin blog&#187; xml-rpc</title>
	<atom:link href="http://www.oganosin.net/blog/tag/xml-rpc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.oganosin.net/blog</link>
	<description>oganosin weblog</description>
	<lastBuildDate>Wed, 29 Sep 2010 03:00:00 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.oganosin.net/blog/tag/xml-rpc/feed/" />
		<item>
		<title>xml-rpc の勉強　その3</title>
		<link>http://www.oganosin.net/blog/programming/xml-rpc-part3/</link>
		<comments>http://www.oganosin.net/blog/programming/xml-rpc-part3/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 02:25:42 +0000</pubDate>
		<dc:creator>oganosin</dc:creator>
				<category><![CDATA[プログラム]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.oganosin.net/blog/?p=37</guid>
		<description><![CDATA[今回はブログのデータ以降をxml-rpc経由でやってみようというサンプル。 wordpressだとDBをまるまる移すのが定番みたいだけど天の邪鬼にperl + xml-rpcでやってみました。 例によって公開できる部分だ [...]]]></description>
			<content:encoded><![CDATA[<p>今回はブログのデータ以降をxml-rpc経由でやってみようというサンプル。<br />
wordpressだとDBをまるまる移すのが定番みたいだけど天の邪鬼にperl + xml-rpcでやってみました。<br />
例によって公開できる部分だけ抜き出しているので、このソースはあくまでも雛型です。</p>
<p>ポイント</p>
<ul>
<li>WordPress用のxml-rpcのメソッド　wp.suggestCategories　を使用</li>
<li>記事の移行だけでメディアデータは持ってきていません</li>
</ul>
<p><a href="http://www.oganosin.net/blog/programming/xml-rpc-part2/">前回と同じく重複チェックには穴がある</a>ので要注意。</p>
<pre>
#!/usr/bin/perl

use strict;
use warnings;
use Encode;
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(%interface $username $passwd $target $postcnt);

BEGIN {
	$interface{'from'}
		= 'http://www.example.com/blog/xmlrpc.php';
	$interface{'to'}
		= 'http://www.example.net/blog/xmlrpc.php';
	$username = 'xxxxxx';
	$passwd  ='xxxxxx';
	$target  = '';
	$postcnt = 100;
}

# get original data
my $rpc = XMLRPC::Lite->new();
$rpc->proxy($interface{'from'});
my $res = $rpc->call("metaWeblog.getRecentPosts",
	1,	# blog ID
	$username,
	$passwd,
	$postcnt,
)->result;

$rpc->proxy($interface{'to'});
foreach my $content (@{$res}) {
	# get posts
	#print Dumper $content;
	my ($title, $description, $date, $excerpt, $wp_slug, $keyword);
	$title = $content->{'title'};
	$description = $content->{'description'};
	$date = $content->{'dateCreated'};
	$excerpt = $content->{'excerpt'};
	$wp_slug = $content->{'wp_slug'};
	$keyword = $content->{'mt_keywords'};

	# check data
	$target = "http://www.example.net/blog/uncategorized/"
		. $wp_slug
		. "/";
	my $ua = new LWP::UserAgent;
	my $req = new HTTP::Request(HEAD => $target);
	my $resp = $ua->request($req);
	if($resp->{'_rc'} eq '200'){
		print STDERR "Alredy convert URL: $target\n";
		next;
	}

	# edit posts

	# get category_id
	$res = $rpc->call("wp.suggestCategories",
		1,
		$username,
		$passwd,
		Encode::encode('utf8', $content->{'categories'}[0]),
	)->result;
	my $category_id = $res->[0]{'category_id'};

	$res = $rpc->call("metaWeblog.newPost",
		1,	# blog ID
		$username,
		$passwd,
		{
		'title'
			=> Encode::encode('utf8', "$title"),
		'description'
			=> Encode::encode('utf8', "$description"),
		'dateCreated'
			=> Encode::encode('utf8', "$date"),
		'mt_excerpt'
			=> Encode::encode('utf8', "$excerpt"),
		'mt_keywords'
			=> Encode::encode('utf8', "$keyword"),
		'wp_slug'
			=> Encode::encode('utf8', "$wp_slug"),
		#'custom_fields'=> [
		#	{
		#	'key'   => '',
		#	'value' => '',
		#	},
		#],
		},
		1
	)->result;
	my $postid = $res;

	$res = $rpc->call("mt.setPostCategories",
		$postid,
		$username,
		$passwd,
		[
			{
				"categoryId" => $category_id,
				"isPrimary"  => 1
			}
		]
	)-> result;
}

exit 1;
</pre>
<div class="amazon"><a href="http://www.amazon.co.jp/Programming-Services-Xml-Rpc-Simon-Laurent/dp/0596001193%3FSubscriptionId%3DAKIAI56TF46UWMULQ7OA%26tag%3Dmusicgear-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596001193"><img src="http://ecx.images-amazon.com/images/I/51qN0sL%2BbAL._SL160_.jpg" class="image" /></a><h4><a href="http://www.amazon.co.jp/Programming-Services-Xml-Rpc-Simon-Laurent/dp/0596001193%3FSubscriptionId%3DAKIAI56TF46UWMULQ7OA%26tag%3Dmusicgear-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596001193">Programming Web Services With Xml-Rpc</a></h4><p><span>著者/訳者：</span>Simon St. Laurent</p><p><span></span></p><p><span>定価：</span>￥ 2,802</p><p><span></span>Oreilly & Associates Inc</p><p><span>EAN：</span>9780596001193</p><hr /></div>
]]></content:encoded>
			<wfw:commentRss>http://www.oganosin.net/blog/programming/xml-rpc-part3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.oganosin.net/blog/programming/xml-rpc-part3/" />
	</item>
		<item>
		<title>xml-rpc の勉強　その2</title>
		<link>http://www.oganosin.net/blog/programming/xml-rpc-part2/</link>
		<comments>http://www.oganosin.net/blog/programming/xml-rpc-part2/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 10:00:34 +0000</pubDate>
		<dc:creator>oganosin</dc:creator>
				<category><![CDATA[プログラム]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.oganosin.net/blog/?p=21</guid>
		<description><![CDATA[というわけでその2．今回はいきなりレベルアップして xmlのデータをwordpressにxml-rpc経由でpostする というプログラムのサンプル。例によって公開できる部分だけ抜き出しているので、このソースはあくまでも [...]]]></description>
			<content:encoded><![CDATA[<p>というわけでその2．今回はいきなりレベルアップして<br />
<strong>xmlのデータをwordpressにxml-rpc経由でpostする</strong><br />
というプログラムのサンプル。例によって公開できる部分だけ抜き出しているので、このソースはあくまでも雛型です。</p>
<p>以下注意点</p>
<ol>
<li>STDINがshiftjisなのはxmlの文字コードが実はshiftjisだったから</li>
<li>check wordpressの部分はサーバーの設定のよって違うと思うので適宜変更のこと</li>
<li>for文が降順なのはxmlのデータが生成時間の新しいものから並んでいるのでそれをwordpressでも引き継ぎたかったから
</ol>
<p>しかし、wordpressには罠が潜んでした・・・。<br />
wordpressは存在しない投稿スラッグを指定した場合、指定された投稿スラッグに近い投稿スラッグがあればそちらにリダイレクトしてくれる。<br />
たとえばこの記事のパーマリンクは<br />
<a href="http://www.oganosin.net/blog/programming/xml-rpc-part2/">http://www.oganosin.net/blog/programming/xml-rpc-part2/</a><br />
なんだけど<br />
<a href="http://www.oganosin.net/blog/programming/xml-rpc-part/">http://www.oganosin.net/blog/programming/xml-rpc-part/</a><br />
でもアクセスできるはず。<br />
なので下記のスクリプトの重複チェックには穴があります。</p>
<pre>
#!/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',
				&#038;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;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.oganosin.net/blog/programming/xml-rpc-part2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.oganosin.net/blog/programming/xml-rpc-part2/" />
	</item>
		<item>
		<title>xml-rpc の勉強　その1</title>
		<link>http://www.oganosin.net/blog/programming/20090415/</link>
		<comments>http://www.oganosin.net/blog/programming/20090415/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 08:51:13 +0000</pubDate>
		<dc:creator>oganosin</dc:creator>
				<category><![CDATA[プログラム]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.oganosin.net/blog/?p=8</guid>
		<description><![CDATA[最近、仕事でxml-rpcを使うことが多いのでログをまとめておく。 まずは基本、xml-rpcで記事の一覧を取得。とってきたデータはDumpすれば何が入っているかわかるよね。 コメントアウトしている部分は必要があれば適宜 [...]]]></description>
			<content:encoded><![CDATA[<p>最近、仕事でxml-rpcを使うことが多いのでログをまとめておく。<br />
まずは基本、xml-rpcで記事の一覧を取得。とってきたデータはDumpすれば何が入っているかわかるよね。<br />
コメントアウトしている部分は必要があれば適宜コメントアウトするなりしてデバッグすべし。<br />
ちなみに公開できる部分だけ抜き出しているので、このソースはあくまでも雛型です。</p>
<pre>
#!/usr/bin/perl

use strict;
use warnings;
use Encode;
use XMLRPC::Lite;
#use XMLRPC::Lite trace =&gt; 'debug' ;
use Data::Dumper;
use vars qw($interface $username $passwd $target $postscnt);

BEGIN {
	$interface = 'http://www.example.com/blog/xmlrpc.php';
	$username  = 'xxxxx';
	$passwd    = 'xxxxx';
	$postscnt  = 100;
}

my $rpc = XMLRPC::Lite-&gt;new();
$rpc-&gt;proxy($interface);
#$rpc-&gt;authorization_basic('id', 'pwd');
my $res = $rpc-&gt;call("metaWeblog.getRecentPosts",
	1,      # blog ID
	$username,
	$passwd,
	$postscnt,
)-&gt;result;
print Dumper $res;
exit 1;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.oganosin.net/blog/programming/20090415/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.oganosin.net/blog/programming/20090415/" />
	</item>
	</channel>
</rss>

