| WebService-Hatena-Fotolife documentation | Contained in the WebService-Hatena-Fotolife distribution. |
WebService::Hatena::Fotolife - A Perl interface to the Hatena::Fotolife Atom API
use WebService::Hatena::Fotolife;
my $fotolife = WebService::Hatena::Fotolife->new;
$fotolife->username($username);
$fotolife->password($password);
# create a new entry with image filename
my $EditURI = $fotolife->createEntry(
title => $title,
filename => $filename,
folder => $folder,
);
# or specify the image source as a scalarref
my $EditURI = $fotolife->createEntry(
title => $title,
scalarref => \$image_content,
folder => $folder,
);
# update the entry
$fotolife->updateEntry($EditURI, title => $title);
# delete the entry
$fotolife->deleteEntry($EditURI);
# retrieve the feed
my $feed = $fotolife->getFeed;
my @entries = $feed->entries;
...
WebService::Hatena::Fotolife provides an interface to the Hatena::Fotolife Atom API.
This module is a subclass of XML::Atom::Client, so see also the documentation of the base class for more usage.
my $fotolife = WebService::Hatena::Fotolife->new;
Creates and returns a WebService::Hatena::Fotolife object.
# passing an image by filename
my $EditURI = $fotolife->createEntry(
title => $title,
filename => $filename,
);
# or...
# a scalar ref to the image content
my $EditURI = $fotolife->createEntry(
title => $title,
scalarref => $scalarref,
);
Uploads given image to Hatena::Fotolife. Pass in the image source as a filename or a scalarref to the image content. There're some more options described below:
Title of the image.
Local filename of the image.
Scalar reference to the image content itself.
Place, called "folder" in Hatena::Fotolife, you want to upload your image.
Specifies generator string. Hatena::Fotolife can handle your request along with it. See http://f.hatena.ne.jp/my/config for detail.
my $EditURI = $fotolife->updateEntry(
$EditURI,
title => $title,
);
Updates the title of the entry at $EditURI with given options. Hatena::Fotolife Atom API currently doesn't support to update the image content directly via Atom API.
my $feed = $fotolife->getFeed;
Retrieves the feed. The count of the entries the $feed includes depends on your configuration of Hatena::Fotolife.
See the documentation of the base class, XML::Atom::Client.
http://f.hatena.ne.jp/
http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D5%A5%A9%A5%C8%A5%E9%A5%A4%A5%D5AtomAPI
Kentaro Kuribayashi, <kentarok@gmail.com>
Copyright (C) 2005 - 2010 by Kentaro Kuribayashi
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| WebService-Hatena-Fotolife documentation | Contained in the WebService-Hatena-Fotolife distribution. |
package WebService::Hatena::Fotolife; use 5.008001; use base qw(XML::Atom::Client); use strict; use warnings; use FileHandle; use Encode qw(encode_utf8 is_utf8); use Image::Info qw(image_info); use WebService::Hatena::Fotolife::Entry; our $VERSION = '0.04'; our $PostURI = 'http://f.hatena.ne.jp/atom/post'; our $FeedURI = 'http://f.hatena.ne.jp/atom/feed'; use constant GEORSS => q<http://www.georss.org/georss>; sub new { my $class = shift; my %params = @_; my $headers = delete $params{headers} || []; my $self = $class->SUPER::new(%params) or return $class->error($class->SUPER::errstr); $self->{headers} = $headers; $self->{ua}->agent(__PACKAGE__."/$VERSION"); $self; } sub createEntry { my ($self, %param) = @_; return $self->error('title and image source are both required') unless $param{title} || grep {!$_} @param{qw(filename scalarref)}; my $image = $self->_get_image($param{filename} || $param{scalarref}) or return $self->error($self->errstr); my $entry = WebService::Hatena::Fotolife::Entry->new; $entry->title($param{title}); $entry->content(${$image->{content}}); $entry->content->type($image->{content_type}); $entry->generator($param{generator}) if $param{generator}; if ($param{folder}) { my $dc = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/'); $entry->set($dc, 'subject', $param{folder}); } if ($param{lat} and $param{lon}) { my $georss = XML::Atom::Namespace->new(georss => GEORSS); $entry->set($georss, 'point', $param{lat} . ' ' . $param{lon}); } $self->SUPER::createEntry($PostURI, $entry); } sub updateEntry { my ($self, $EditURI, %param) = @_; return $self->error('EditURI and title are both required') unless $EditURI || $param{title}; my $entry = WebService::Hatena::Fotolife::Entry->new; $entry->title($param{title}); $entry->generator($param{generator}) if $param{generator}; if ($param{folder}) { my $dc = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/'); $entry->set($dc, 'subject', $param{folder}); } if ($param{lat} or $param{lon}) { my $georss = XML::Atom::Namespace->new(georss => GEORSS); $entry->set($georss, 'point', $param{lat} . ' ' . $param{lon}); } $self->SUPER::updateEntry($EditURI, $entry); } sub munge_request { my $self = shift; my $req = shift; my $headers = [@{ $self->{headers} }]; $self->SUPER::munge_request($req); while (my ($key, $value) = splice @$headers, 0, 2) { $req->header($key => $value); } $req; } sub munge_response { my $self = shift; my $res = shift; my $status = $res->header('Status'); if ($status and $status =~ s/^(\d+)\s+(?=.+)//) { $res->code($1); $res->message($status); } $self->SUPER::munge_response($res, @_); } sub getFeed { my $self = shift; $self->SUPER::getFeed($FeedURI); } sub _get_image { my ($self, $image_source) = @_; my $image; if (ref $image_source eq 'SCALAR') { $image = $image_source; } else { $image = do { local $/ = undef; my $fh = FileHandle->new($image_source) or return $self->error("can't open $image_source: $!"); my $content = <$fh>; \$content; }; } my $info = Image::Info::image_info($image); return $self->error($info->{error}) if $info->{error} and $info->{error} !~ /short read/; +{ content => $image, content_type => $info->{file_media_type}, }; } 1; __END__