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;
コメント