mixi 日記が空っぽなのはさみしいけどこっちの blog エントリをコピペで投稿するのはめんどくさい、という必要に駆られて自作した MT 用の mixi 日記投稿プラグイン。
しばらく blog もさぼってたのでいつからかはわかりませんが、プラグイン経由で投稿した mixi 日記が豪快に文字化けするようになってしまってました。
ちょっと前までは問題なく使えていたので mixi 側の仕様が変わったんだと思いますが、詳しく調べてないので原因は謎。
これまでは WWW::Mechanize で Web ブラウザ同様に mixi にログインして投稿フォームから送信、というわりとめんどい手順を踏んでたんですが、OpenID にも対応しているきょうび REST 使えないとかありえないよねー、と調べてみたら非公式ながら API があることが判明。
それ使ったらこれまでよりずっと簡単に mixi 日記が投稿できるようになりました。
ざっと調べて見つけた Web サイトでは LWP::UserAgent で直に API 叩いてましたが、せっかく CPAN Module があるんだからそっちを使う感じに。といってもたいしたことはしてません、XML::Atom でちょろちょろっと書いただけです。
参考にしたサイトは次のような感じ。
たけまる / mixi station API
http://teahut.sakura.ne.jp/b/2007-07-01-1.html
mixi for iPhoneから発掘されたmixi日記投稿用API « ku
http://ido.nu/kuma/2008/07/30/digging-mixi-for-iphone-application-and-new-api-for-posting-a-diary-with-a-photo/
いくら非公開とはいえネット使う API は簡単に解析されるわねぇ。
なんとなくプラグインのソース貼ってみますが、テンプレートとかないと動作しないのであしからず。
# $Id: mt-mixi_link.pl 8 2009-03-19 09:53:33Z mocel $ package MT::Plugin::mixiLink; use strict; use base 'MT::Plugin'; use MT 4; use Encode (); use Encode::Guess; use Time::HiRes qw/sleep/; use XML::Atom::Client; use XML::Atom::Entry; our $PLUGIN_NAME = 'mixiLink'; our $VERSION = '0.04'; #@MT::Plugin::mixiLink::ISA = qw(MT::Plugin); my $APP; my $plugin = MT::Plugin::mixiLink->new({ name => $PLUGIN_NAME, version => $VERSION, description => "", doc_link => 'mt-plugins/mt-mixi_link/docs/mt-mixi_link.html', author_name => 'Mocel', author_link => 'http://archive.guma.jp/', l10n_class => 'mixiLink::L10N', blog_config_template => 'mixi_link.tmpl', settings => new MT::PluginSettings([ ['mixi_id', { Default => '', Scope => 'blog' }], ['mixi_uid', { Default => 0, Scope => 'blog' }], ['mixi_passwd', { Default => '', Scope => 'blog' }], ]), }); MT->add_plugin($plugin); sub instance { $plugin } sub load_config { my $plugin = shift; my ($args, $scope) = @_; $plugin->SUPER::load_config(@_); if ($scope =~ /blog:(\d+)/) { my $blog_id = $1; $args->{blog_id} = $blog_id; } } sub init_registry { my $plugin = shift; $plugin->registry({ applications => { cms => { list_actions => { entry => { mixi_link => { label => 'Submit mixi', code => \&itemset_mixi_link, permissions => 'can_edit_entry', dialog => 1, }, }, }, }, }, } ); } sub doLog { my ($msg) = @_; return unless defined($msg); use MT::Log; my $log = MT::Log->new; $log->message($msg) ; $log->save or die $log->errstr; } sub apply_default_settings { my $app = shift; my ($data, $scope) = @_; if ($scope ne 'system') { my $sys = $app->get_config_obj('system'); my $sysdata = $sys->data(); if ($app->{settings} && $sysdata) { foreach (keys %$sysdata) { $data->{$_} = $sysdata->{$_} if !exists $data->{$_}; } } } else { $app->SUPER::apply_default_settings(@_); } } sub __decode { my $stuff = shift; my $enc = guess_encoding($stuff, qw/euc-jp cp932 utf8/); if ($enc && ref($enc)) { return $enc->decode($stuff); } else { return Encode::decode_utf8($stuff); } } #----- Transformer sub itemset_mixi_link { my $app = shift; $APP = $app; my $user = $app->user; return $app->error($app->translate("Permission denied.")) unless $user->can_edit_entry; my $str = ''; use MT::Blog; my $blog_id = $app->param('blog_id'); my $scope = "blog:$blog_id"; my $blog = MT::Blog->load($blog_id); my $blog_url = __decode($blog->site_url); $str = qq{Blog ID $blog_id: $blog_url\n}; use MT::Util; my $blog_name = __decode($blog->name); $str .= qq{Blog Title $blog_name\n}; my $mixi_id = $plugin->get_config_value('mixi_id', $scope) || 0; my $mixi_passwd = $plugin->get_config_value('mixi_passwd', $scope) || 0; my $mixi_uid = $plugin->get_config_value('mixi_uid', $scope) || 0; return $app->error($plugin->translate("No settings")) if !$mixi_id or !$mixi_passwd or !$mixi_uid; $app->{no_print_body} = 1; $app->send_http_header; my $html_head = <<'SCRIPT'; <script type="text/javascript"> function progress(str, id) { val el = getByID(id); if (el) el.innerHTML = str; } </script> SCRIPT $app->print($app->build_page('dialog/header.tmpl', { page_title => 'mixiLink', html_head => $html_head })); $app->print($plugin->translate_templatized(<<"HTML")); <__trans phrase="Posting your diary to mixi '[_1]'..." params="$blog_name"> <div class="modal_width" id="dialog-mixilink-weblog"> <div id="msg-conatiner" style="height:310px;overflow:scroll;overflow-x:auto"> HTML # Create Atom API Client my $mixi_uri = 'http://mixi.jp/atom/diary/member_id=' . $mixi_uid; my $mixi_api = XML::Atom::Client->new; $mixi_api->username($mixi_id); $mixi_api->password($mixi_passwd); $app->print("Created Atom API Client.\n"); use MT::Entry; foreach my $id (sort { $a <=> $b } $app->param('id')) { my $entry = MT::Entry->load( { blog_id => $blog_id, id => $id, status => MT::Entry::RELEASE, } ); if ($entry) { my $title = __decode($entry->title); my $text = __decode(MT::Util::encode_html($entry->text)); $app->print(qq{Found the diary entry "$title"\n}); # if "More" exists add the link to entry. if ( $entry->text_more ne '' ) { $text .= Encode::decode_utf8("\n\n続きは " . $entry->permalink() . ' で。'); } # Create Atom Entry my $mixi_entry = XML::Atom::Entry->new; $mixi_entry->title($title); $mixi_entry->summary($text); $app->print(qq{Created a Atom Entry.\n}); # POST $app->print(qq{Submit entry => $title\n}); my $edit_uri = $mixi_api->createEntry($mixi_uri, $mixi_entry); if ($edit_uri =~ m{/member_id=(\d+)/entry_id=(\d+)}) { # Success my $entry_id = $2; $app->print(qq{Completed "$title"\n}); #" } else { $app->print( qq{Confirm error: "$title"\n} ); } } } my $return_url = $app->return_uri; $app->print($plugin->translate_templatized(<<"HTML")); <form action="GET"> <div class="actions-bar"> <div class="actions-bar-inner pkg actions"> <button onclick="closeDialog('$return_url'); return false" type="submit" class="primary-button"><__trans phrase="Close"> HTML $app->print($app->build_page('dialog/footer.tmpl')); } sub mixi_abort { $APP->error(@_); } 1;
コメント