昨今の blog サービスで画像を貼り付けられないところはありません。ない。たぶんない。
もちろん我らがはてなダイアリーも、画像を余裕で貼り付けることができます。とてもよかった。これで老後も多い日も安心です。
はてなダイアリーははてなフォトライフと連動しており、はてなフォトライフにアップロードした画像は、はてな記法で記述することにより、クソ簡単にはてなダイアリーから参照することができます。とっても簡単だ。人生もこのくらい簡単だったら良いのにね!!!!!
f:id:kiririmode:20100407141723p:image
しかし、はてなフォトライフへのアップロードはメンドい。フォトライフのページを開いて、いろいろクリックして、アップロードする画像を選択して、アップロードボタンを押す必要がある。これは苦行です。あまりにもメンドい。人生と同じくらいメンドい。さらに、スクリーンショットを撮ってフォトライフにアップロードしようと思うと、そのメンドくささはスゴみを増す。こわい。もう戦えない。
なんとかしないと負け組です。人生と同じだ。なんとかしなければならない。なんか API でもないものかと思ってたら、そういえば AtomPub の API があった。これを使えばいいです。これを使えば全ての苦しみから解放される。
以上、ぼくの人生からわずかでも苦しみを解放するために、スクリーンキャプチャ→はてなフォトライフへのアップロードを半自動化する capturelife っていうスクリプトを組んだ。
fotmat を指定して (指定しなければ jpeg)、キャプチャーモードを指定して(指定しなければ、ウィンドウキャプチャを実行)、あとはフォトライフ上のフォルダとタイトルを指定する(指定なしでも良い)と、フォトライフ上に自動でアップロードされる。
[kiririmode@mbp(job:0)]% capturelife -h Usage: capturelife --area capturelife --format jpg capturelife --format jpg --name title capturelife --format jpg --name title --dir dir
実際にキャプチャしてみると以下のような感じ。これはウィンドウモードでのキャプチャになる。これで下記の画像のように、「スクリーンショット…」というような画像ファイルがデスクトップに出現することもなくなる。
$ capturelife
キャプチャは、スクリプト内部で screencapture コマンドを起動することで実行するので、Mac 限定。
http://github.com/kiririmode/capturelife
#!/usr/bin/perl # -*- cperl -*- use strict; use warnings; use Getopt::Long; use Pod::Usage; use File::Temp; use IPC::Cmd; use XML::Atom::Client; use XML::Atom::Entry; use Config::Pit; # Hatena Fotolife Post URI my $post_uri = 'http://f.hatena.ne.jp/atom/post'; # allowed formats for Hatena Fotolife my $re_format = qr/jpe?g|gif|png|bmp/; GetOptions(\my %opts, 'monitor|m', 'area|a', 'window|w', 'format|f=s', 'name|n=s', 'dir|d=s', 'help' ) or pod2usage(2); run(\%opts); sub run { my $opts = shift; if ( $opts->{help} ) { pod2usage(0); } check_options($opts); my $file = capture($opts); my $conf = pit_get( 'hatena.ne.jp', require => { user => 'hatena user id', pass => 'hatena password', }); upload($file, $conf, $opts); } sub check_options { my $opts = shift; # capture mode check my $modes = grep defined, @{$opts}{qw/monitor area window/}; if ($modes > 1) { die "-monitor, -area, and -window options are mutually exclusive.\n"; } # format check $opts->{format} ||= 'jpeg'; $opts->{format} = 'jpeg' if $opts->{format} eq 'jpg'; $opts->{format} =~ s/^\.//; unless ( $opts->{format} =~ $re_format ) { die "allowed formats are jpeg, gif, png, and bmp\n"; } } sub capture { my $opts = shift; my $mode = defined($opts->{monitor})? "-m" : defined($opts->{area})? "-s" : defined($opts->{windows})? "-w" : "-w"; my $path; unless ( $path = IPC::Cmd::can_run( 'screencapture' ) ) { die "screencapture is not installed\n"; } my $file = File::Temp->new( SUFFIX => ".$opts->{format}" ); $file->unlink_on_destroy( 0 ); my ($ok, $msg) = IPC::Cmd::run( command => "$path $mode $file" ); unless( $ok ) { die "$msg\n"; } return $file->filename; } sub upload { my ($filename, $conf, $opts) = @_; my $api = XML::Atom::Client->new; $api->username( $conf->{user} ); $api->password( $conf->{pass} ); open my $fh, '<', $filename or die $!; binmode $fh; my $image = do { local $/; <$fh> }; my $entry = XML::Atom::Entry->new; $entry->content( $image ); $entry->content->type('image/' . $opts->{format}); $entry->title( $opts->{name} ); if ($opts{dir}) { my $dc = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/'); $entry->set($dc, 'subject', $opts{dir}); } $api->createEntry( $post_uri, $entry ) or die $api->errstr; } __END__ =head1 NAME capturelife - captures a screenshot, and uploads it to Hatena Fotolife =head1 SYNOPSIS capturelife --area capturelife --format jpg capturelife --format jpg --name file capturelife --format jpg --name file --dir dir =head1 DESCRIPTION See L<README> for details. =head1 AUTHOR Yuichi Kiri (kiririmode) =cut