tumblrにポストする

tumblrにポストするのに少し手を入れてみる。前に自分で書いたNet::TumblrとかCPANWWW::Tumblrを使わないで直にAPIたたいてるのは、画像のポストするのにしか使わないからモジュール使うまでもないと思ったから。

use strict;
use warnings;
use version; our $VERSION = qv('1.0.4');
use 5.10.0;

use Encode qw/from_to/;
use Encode::Detect::Detector;
use Getopt::Long;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Response::Encoding;
use HTML::TreeBuilder::XPath;
use Term::Encoding;

my $api = 'http://www.tumblr.com/api/write';

my %opt = (
    agent     => "Tumblrer/$VERSION",
    generator => "Tumblrer/$VERSION",
    term      => Term::Encoding::term_encoding() || 'utf8',
);
my %account = (
    name => 'NAME',
    pass => 'PASSWORD',
    mail => 'MAIL@example.com',
);

GetOptions(
    'local=s' => \$opt{local},
    'uri=s'   => \$opt{uri},
    'page=s'  => \$opt{page},
    'title=s' => \$opt{title},
    'draft'    => \$opt{draft},
);

die "arguments err" if !$opt{uri} == !$opt{local};

my $ua = LWP::UserAgent->new(
    agent => "Mozilla/5.0 (Windows; U; Windows NT 6.1; ja; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 (LWP/$LWP::UserAgent::VERSION; $opt{agent})",
    timeout => 30,
);

if ($opt{page}) {
    if ($opt{title}) {
        $opt{caption} = qq'<a href="$opt{page}">$opt{title}</a>';
        from_to $opt{caption}, $opt{term} => 'utf8';
    }
    else {
        my $res = $ua->get($opt{page});
        if ($res->is_success) {
            my $char = $res->charset || detect $res->content;
            my $title = $res->header('Title')
                || HTML::TreeBuilder::XPath->new->parse($res->content)->eof->findvalue('//title')
                || $opt{page};
            $opt{caption} = qq'<a href="$opt{page}">$title</a>';
            from_to $opt{caption}, $char => 'utf8';
            from_to $opt{title} = $title, $char => $opt{term}, sub{ sprintf "<U+%04X>", shift };
        }
        else {
            warn 'WARN: ', $res->status_line, "\n";
            $opt{caption} = qq'<a href="$opt{page}">$opt{page}</a>';
        }
    }
}

my @content = (
    email     => $account{mail},
    password  => $account{pass},
    type      => 'photo',
    generator => $opt{generator},
);

push @content, caption => $opt{caption} if $opt{caption};
push @content, $opt{local} ? (data => [$opt{local}]) : (source => $opt{uri});
push @content, state => 'draft' if $opt{draft};

my $req = POST $api,
    Content_Type => ($opt{local} ? 'form-data' : 'application/x-www-form-urlencoded'),
    Content => \@content;

my $res = $ua->request($req);

say $res->status_line;

if ($res->is_success) {
    say "http://$account{name}.tumblr.com/post/" . $res->content;
    say "[$opt{title}]" if $opt{title};
    say "* DRAFT *" if $opt{draft};
}
else { say $res->content }