はてなダイアリーコマンドライン

gistpのコードを参考にしてコマンドラインからはてなダイアリーにポストするコードを書いてみた(ただ、ポストするだけ)。
任意のファイルの中身を読み込んでそのままポストできる。
echoなどを使って、一行テキストなどもポストできる。
複数ファイルを一気にダイアリーにアップしたりもできたりする。
デフォルトは下書き投稿となっている。投稿後にはてなインタフェースで校正確認後に公開というフローでもいいかも。

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use File::Slurp qw(slurp);
use FindBin;
use File::Spec;
use YAML ();
use DateTime;
use XML::Atom::Entry;
use XML::Atom::Client;
use Data::Dumper;

my $api_base = "http://d.hatena.ne.jp/";
my $dt = DateTime->now( time_zone => 'Asia/Tokyo' ); 
my $config = YAML::LoadFile(File::Spec->catfile($FindBin::Bin, 'config.yaml'))
		or die "Can't load config file: $!";
my %options;
GetOptions(\%options, "--title=s", "--blog");

run(\%options, @ARGV);

sub run {
	my($opts, @args) = @_;
	my @files = setup_files($opts, @args);
	
	my %fields;
	$fields{mode} = 'blog' if $opts->{blog};

	foreach my $file (@files) {
		$fields{title} = $file->{title};
		$fields{content} = $file->{content};
		&post(\%fields, $config);
	}
}

sub setup_files {
	my($opts, @args) = @_;
	my @files;
	if (@args == 0 or $args[0] eq '-') {
		my $content = join '', do{ local $/; <STDIN>};
		@files = ({ title => $opts->{title} || "$dt", content => $content });
	} else {
		for my $arg (@args) {
			push @files, {
				title => $arg,
				content => scalar slurp($arg),
			};
		}

	}
	return @files;
}

sub post {
	my($fields, $config) = @_;
	my $username = $config->{hatena_user};
	my $password = $config->{hatena_pass};
	my $client = XML::Atom::Client->new;
	   $client->username($username);
	   $client->password($password);
	my $entry = XML::Atom::Entry->new;
	   $entry->title($fields->{title});
	   $entry->content($fields->{content});
    my ($edit_url);		
	if ($fields->{mode} && $fields->{mode} eq 'blog') {
		my $api_url = $api_base. $username. '/atom/blog';
		$edit_url = $client->createEntry($api_url, $entry)
				or die $client->errstr;
		$edit_url =~ s/(\/atom\/blog)//i;
		print $edit_url."\n";
	} else {
		my $api_url = $api_base. $username. '/atom/draft';
		$edit_url = $client->createEntry($api_url, $entry)
				or die $client->errstr;
		my $id = ($edit_url =~ /(\d+)$/)[0];
		my $res_url = $api_base. $username. "/draft?epoch=". $id;
		print $res_url."\n";
	}
}