Fotolifeへアップロード

このエントリーをはてなブックマークに追加

概要

はてなフォトライフへ画像をアップロードするPerlスクリプト

準備

Ubuntu 8.04の場合

  $ apt-get install libxml-atom-perl

h-fotolife.pl

#!/usr/bin/perl
use strict;
use FileHandle;
use XML::Atom::Entry;
use XML::Atom::Client;

my @fotos = <foto/*.{jpg,png}>;
my $username = shift;
my $password = shift;
if (! $username) {
    print "User: ";
    chomp($username = <STDIN>);
    print "\n";
}
if (! $password) {
    print "Password: ";
    chomp($password = <STDIN>);
    print "\n";
}
my $dc = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/');
my $hatena = XML::Atom::Namespace->new(hatena => 'http://www.hatena.ne.jp/info/xmlns#');

foreach my $fotofile (@fotos) {
    my $infofile = $fotofile;
    $infofile =~ s/\.\w+$/.txt/;
    my %info = &load_info($infofile);
    if ($info{"edit"}) {
	next;
    }
    my $type = $info{"type"};
    if ($fotofile =~ /\.jpg$/) {
	$type = "image/jpeg";
    } elsif ($fotofile =~ /\.png$/) {
	$type = "image/png";
    } else {
	print "Unknown image type $fotofile\n";
	next;
    }
    my $title = $info{"title"};
    if (! $title) {
	$title = $infofile;
	$title =~ s|.*?([^/]+)\.\w+$|\1|;
    }
    my ($edit, $res) = &post($fotofile, $type, $title, $info{"folder"});
    $info{"edit"} = $edit;
    my $h = $res->get($hatena, "syntax");
    $info{"hatena"} = $h;
    &save_info($infofile, %info);
    print "$fotofile --> $h\n";
}
exit 0;

sub load_info {
    my ($infofile) = @_;
    my %info = ();
    if (-e $infofile) {
	open(INFO, "<", $infofile) || die "$0: $infofile $!";
	while (<INFO>) {
	    chomp;
	    my ($tag, $value) = split(/\t/);
	    $info{$tag} = $value;
	}
	close(INFO);
    }
    return %info;
}

sub save_info {
    my ($infofile, %info) = @_;
    open(INFO, ">", $infofile) || die "$0: $infofile $!";
    foreach my $tag (sort keys %info) {
	print INFO "$tag\t$info{$tag}\n";
    }
    close(INFO);
}

sub post {
    my ($fotofile, $type, $title, $folder) = @_;
    my $api = XML::Atom::Client->new;
    $api->username($username);
    $api->password($password);
    my $fh = FileHandle->new($fotofile) || die "$0: $fotofile $!";
    my $image = do { local $/; $fh->getline };
    my $entry = XML::Atom::Entry->new;
    $entry->content($image);
    $entry->content->type($type);
    if ($title) {
	$entry->title($title);
    }
    if ($folder && $folder ne "/") {
	$entry->set($dc, 'subject', $folder);
    }
    my $PostURI = 'http://f.hatena.ne.jp/atom/post';
    my $EditURI = $api->createEntry($PostURI, $entry) || die "$0: $fotofile $api->errstr";
    my $res = XML::Atom::Entry->new(Stream => \$api->{response}->content);
    return ($EditURI, $res);
}

使い方

  • fotoフォルダーにアップロードしたい画像ファイルをコピーする
  • ./h-fotolife.pl を実行する
    • ユーザ名とパスワードを入力すると,画像ファイルがアップロードされる
    • 過去にアップロードした画像ファイルはアップロードされない
  • 新しくアップロードした画像ファイルについては imagename.txt 等のファイルが作成され,中にはEditURIおよびfotolife記法が保存される
    • EditURIは,PostURIで画像をポストした時にレスポンスとして返されるLocationだが,正しくないようなので注意(hatenaのバグ?)

具体的な使用例

  • 画像を foto/imagename.jpg として保存する.
  • foto/imagename.txt を以下の内容で作成する.
    • 作成しなくても良い.作成しない場合,ファイル名がタイトルとなる.
    • 文字コードUTF-8で,タブ区切り
title	ロカ岬
  • ./h-fotolife.pl を実行する.
  • foto/imagename.txt は以下のような内容に変更される.
edit	http://f.hatena.ne.jp/atom/edit/20091227020024
hatena	f:id:tamura70:20091227020024j:image
title	ロカ岬