File Coverage

blib/lib/WebService/Hatena/Diary.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package WebService::Hatena::Diary;
2 1     1   7 use strict;
  1         1  
  1         37  
3 1     1   6 use warnings;
  1         2  
  1         29  
4              
5 1     1   518 use XML::Atom::Entry;
  0            
  0            
6             use XML::Atom::Client;
7             use HTTP::Request;
8             use DateTime;
9             use DateTime::Format::W3CDTF;
10             use DateTime::Format::Strptime;
11              
12             our $VERSION = '0.01';
13              
14             sub new {
15             my ($class, $args) = @_;
16              
17             my $self = bless {
18             username => $args->{username},
19             dusername => $args->{dusername} || $args->{username},
20             password => $args->{password},
21             mode => $args->{mode} || 'blog',
22             }, $class;
23              
24             my $client = XML::Atom::Client->new;
25             $client->username($self->{username});
26             $client->password($self->{password});
27             $self->{client} = $client;
28              
29             return $self;
30             }
31              
32             sub api_uri {
33             my ($self) = @_;
34             my $api_uri_base = "http://d.hatena.ne.jp/$self->{dusername}/atom/";
35             return +{
36             blog => $api_uri_base . "blog/",
37             draft => $api_uri_base . "draft/",
38             }->{$self->{mode}};
39             }
40             sub client { shift->{client}; }
41             sub errstr { shift->client->errstr; }
42             sub ua { shift->client->{ua}; }
43              
44             sub list {
45             my ($self) = @_;
46              
47             my @entries = map {
48             _to_result($_);
49             } $self->client->getFeed($self->api_uri)->entries;
50              
51             return @entries;
52             }
53              
54             sub create {
55             my ($self, $args) = @_;
56              
57             my $entry = _to_entry($args);
58              
59             my $edit_uri = $self->client->createEntry($self->api_uri, $entry);
60             return if $self->errstr;
61              
62             return $edit_uri;
63             }
64              
65             sub retrieve {
66             my ($self, $edit_uri) = @_;
67              
68             my $entry = $self->client->getEntry($edit_uri);
69             return if $self->errstr;
70              
71             return _to_result($entry);
72             }
73              
74             sub update {
75             my ($self, $edit_uri, $args) = @_;
76              
77             my $entry = _to_entry($args);
78              
79             $self->client->updateEntry($edit_uri, $entry);
80             return if $self->errstr;
81              
82             return 1;
83             }
84              
85             sub delete {
86             my ($self, $edit_uri) = @_;
87              
88             $self->client->deleteEntry($edit_uri);
89             return if $self->errstr;
90              
91             return 1;
92             }
93              
94             sub publish {
95             my ($self, $edit_uri) = @_;
96             return if $self->{mode} ne 'draft';
97              
98             my $req = HTTP::Request->new(PUT => $edit_uri);
99             $req->header('X-HATENA-PUBLISH' => 1);
100             my $res = $self->client->make_request($req);
101             if ($res->code != 200) {
102             $self->client->error("Error on PUT $edit_uri: " . $res->status_line);
103             return;
104             }
105             return 1;
106             }
107              
108             my $formatter = DateTime::Format::W3CDTF->new;
109             my $parser = DateTime::Format::Strptime->new(
110             pattern => '%F',
111             time_zone => 'local',
112             );
113              
114             sub _to_entry {
115             my ($args) = @_;
116              
117             my $entry = XML::Atom::Entry->new;
118             $entry->title($args->{title}) if $args->{title};
119             $entry->content($args->{content}) if $args->{content};
120             if ($args->{date}) {
121             $entry->updated(
122             $formatter->format_datetime($parser->parse_datetime($args->{date}))
123             );
124             }
125              
126             return $entry;
127             }
128              
129             sub _to_result {
130             my ($entry) = @_;
131              
132             my $result = {};
133              
134             $result->{title} = $entry->title if $entry->title;;
135             $result->{content} = $entry->content->body if $entry->content;
136             $result->{date} = $parser->parse_datetime($entry->updated)->ymd if $entry->updated;
137              
138             my $hatena_syntax = $entry->get('http://www.hatena.ne.jp/info/xmlns#', 'syntax');
139             $result->{hatena_syntax} = $hatena_syntax if $hatena_syntax;
140              
141             my ($link) = grep { $_->rel eq 'edit' } $entry->link;
142             $result->{edit_uri} = $link->href if $link;
143              
144             return $result;
145             }
146              
147             1;
148             __END__