File Coverage

blib/lib/WebService/Connpass.pm
Criterion Covered Total %
statement 104 118 88.1
branch 24 36 66.6
condition 8 20 40.0
subroutine 18 18 100.0
pod 4 4 100.0
total 158 196 80.6


line stmt bran cond sub pod time code
1             package WebService::Connpass;
2              
3 3     3   64968 use warnings;
  3         6  
  3         72  
4 3     3   21 use strict;
  3         6  
  3         69  
5 3     3   16 use Carp;
  3         8  
  3         237  
6 3     3   907 use utf8;
  3         14  
  3         12  
7              
8 3     3   2258 use version;
  3         6041  
  3         21  
9             our $VERSION = qv('0.0.1');
10              
11 3     3   245 use base qw/Class::Accessor/;
  3         5  
  3         121687  
12 3     3   8153 use Data::Recursive::Encode;
  3         45790  
  3         104  
13 3     3   2753 use DateTime::Format::ISO8601;
  3         921438  
  3         227  
14 3     3   3362 use Hash::AsObject;
  3         2833  
  3         19  
15 3     3   3171 use JSON;
  3         42590  
  3         19  
16 3     3   3583 use LWP::UserAgent;
  3         158602  
  3         121  
17 3     3   34 use URI;
  3         8  
  3         3690  
18              
19             # Accessors
20             __PACKAGE__->mk_accessors( qw/ iter / );
21              
22             # Constructor
23             sub new {
24 2     2 1 60641 my ($class, %param) = @_;
25 2         28 my $self = bless({}, $class);
26              
27             # Parameter - Base URL (API Endpoint)
28 2 100       28 if(defined($param{baseurl})){
29 1         25 $self->{baseurl} = $param{baseurl};
30 1         4 delete $param{baseurl};
31             }else{
32 1         10 $self->{baseurl} = 'http://connpass.com/api/v1/';
33             }
34              
35             # Parameter - Encoding (Char-set)
36 2 50       20 if(defined($param{encoding})){
37 0         0 $self->{encoding} = $param{encoding};
38 0         0 delete $param{encoding};
39             }
40              
41             # Parameter - Automatic next page fetch
42 2 50 33     26 if(defined($param{disable_nextpage_fetch}) && $param{disable_nextpage_fetch}){
43 0         0 $self->{nextpage_fetch} = 0;
44 0         0 delete $param{disable_nextpage_fetch};
45             }else{
46 2         9 $self->{nextpage_fetch} = 1;
47             }
48              
49             # Parameter - Timeout
50 2   50     62 $param{timeout} = $param{timeout} || 10;
51              
52             # Parameter - UserAgent string
53 2   33     55 $param{agent} = $param{agent} || __PACKAGE__.'/'.$VERSION;
54              
55             # ----------
56              
57             # Prepare a LWP::UA instance
58 2         68 $self->{ua} = LWP::UserAgent->new(%param);
59              
60             # Prepare a Date parser instance
61 2         10198 $self->{datetime_parser} = DateTime::Format::ISO8601->new();
62              
63             # Prepare events store array
64 2         418 $self->{events} = [];
65              
66 2         16 $self->{current_request_path} = '';
67 2         7 $self->{current_query} = ();
68 2         13 return $self;
69             }
70              
71             # Fetch events
72             sub fetch {
73 2     2 1 45 my ($self, $request_path, %query) = @_;
74              
75 2         12 my $is_auto_fetch = 0;
76 2 50       14 if(defined($query{_is_auto_fetch})){
77 0         0 $is_auto_fetch = 1;
78 0         0 delete $query{_is_auto_fetch};
79             }
80              
81 2         6 $self->{current_request_path} = $request_path;
82 2   50     156 $self->{current_query} = \%query || {};
83 2   50     57 $self->{current_query}->{count} = $self->{current_query}->{count} || 10; # Each fetch num of item
84              
85             # Request
86 2         8 my $url = $self->_generate_get_url($self->{baseurl}.$request_path.'/', %{$self->{current_query}});
  2         34  
87 2         67 my $response = $self->{ua}->get($url);
88 2 50       820197 unless($response->is_success){
89 0         0 die 'Fetch error: '.$response->status_line;
90             }
91              
92             # Decode JSON
93 2         191 my $js_hash = JSON->new->utf8->decode($response->content);
94              
95             # Encoding
96 2 50       371 if(defined($self->{encoding})){
97 0         0 $js_hash = Data::Recursive::Encode->encode($self->{encoding}, $js_hash);
98             }
99              
100             # Initialize the events store array
101 2 50       12 unless($is_auto_fetch){ # If not auto-fetch...
102 2         10 $self->{events} = [];
103             }
104              
105             # Store events
106 2         7 foreach my $item(@{$js_hash->{events}}){
  2         13  
107 3         10 my $item_id = $item->{event_id};
108 3         6 push(@{$self->{events}}, $item);
  3         11  
109             }
110              
111             # Reset iterator
112 2 50       14 unless($is_auto_fetch){
113 2         19 $self->iter(0);
114             }
115              
116 2         198 return;
117             }
118              
119             # Put to next a Iterator
120             sub next {
121 6     6 1 22972 my $self = shift;
122 6   50     71 my $_is_disable_autofetch = shift || 0;
123              
124 6         32 my $i = $self->iter();
125 6 50       96 if($i < 0){ $i = 0; }
  0         0  
126              
127 6 100       12 if($i < @{$self->{events}}){
  6         29  
128             # Next one
129 4         29 $self->iter($i + 1);
130             # Return one event object
131 4         59 return $self->_generate_event_object($self->{events}->[$i]);
132             }else{
133             # Fetch next page automatically
134 2 50 33     39 if($self->{nextpage_fetch} == 1 && $_is_disable_autofetch == 0 && @{$self->{events}} % $self->{current_query}->{count} == 0){
  2   33     23  
135 0         0 $self->{current_query}->{start} = $i;
136 0         0 $self->{current_query}->{_is_auto_fetch} = 1;
137             # Auto fetch
138 0         0 $self->fetch($self->{current_request_path}, %{$self->{current_query}});
  0         0  
139 0         0 return $self->next(1);
140             }
141             }
142 2         8 return;
143             }
144              
145             # prev a Iterator
146             sub prev {
147 6     6 1 22045 my $self = shift;
148              
149 6         30 my $i = $self->iter() - 1;
150              
151 6 100       75 if(0 <= $i){
152             # Prev one
153 4         14 $self->iter($i);
154             # Return one event object
155 4         57 return $self->_generate_event_object($self->{events}->[$i]);
156             }
157 2         5 return;
158             }
159              
160             # Generate Event object from Hash
161             sub _generate_event_object {
162 8     8   17 my ($self, $hash) = @_;
163            
164             # Date parse
165 8 100       30 unless(defined($hash->{started})){
166 3 50       48 $hash->{started} = defined($hash->{started_at}) ? $self->{datetime_parser}->parse_datetime($hash->{started_at}) : undef;
167             }
168              
169 8 100       3490 unless(defined($hash->{ended})){
170 3 50       26 $hash->{ended} = defined($hash->{ended_at}) ? $self->{datetime_parser}->parse_datetime($hash->{ended_at}) : undef;
171             }
172              
173 8 100       2874 unless(defined($hash->{updated})){
174 3 50       28 $hash->{updated} = defined($hash->{updated_at}) ? $self->{datetime_parser}->parse_datetime($hash->{updated_at}) : undef;
175             }
176              
177 8         1481 return Hash::AsObject->new($hash);
178             }
179              
180             # Generate URL from URL And Query parameters
181             sub _generate_get_url {
182 2     2   7 my ($self, $url, %params) = @_;
183 2         37 my $uri = URI->new($url);
184 2         23079 $uri->query_form(\%params);
185 2         758 return $uri->as_string();
186             }
187              
188             1;
189             __END__
190             =head1 NAME
191              
192             WebService::Connpass - connpass API (v1) wrapper module for perl5
193              
194             =head1 SYNOPSIS
195              
196             use WebService::Connpass;
197            
198             my $connpass = WebService::Connpass->new( encoding => 'utf8' );
199            
200             # Request event
201             $connpass->fetch( 'event', keyword => 'perl' );
202            
203             # Print each events information
204             while ( my $event = $connpass->next ){
205             # Title and Event ID
206             print $event->title . " (" . $event->event_id . ")";
207             # Date (started_at)
208             print " - ".$event->started if $event->started;
209             print "\n";
210             }
211              
212             =head1 INSTALLATION (from GitHub)
213              
214             $ git clone git://github.com/mugifly/p5-WebService-Connpass.git
215             $ cpanm ./p5-WebService-Connpass
216              
217             =head1 METHODS
218              
219             =head2 new ( [%params] )
220              
221             Create an instance of WebService::Connpass.
222              
223             %params = (optional) LWP::UserAgent options, and encoding (example: encoding => 'utf8').
224              
225             =head2 fetch ( $api_path [, %params] )
226              
227             Send request to Connpass API.
228             Also, this method has supported a fetch like 'Auto-Pager'.
229              
230             =over 4
231              
232             =item * $api_path = Path of request to Connpass API. Currently available: "event" only.
233              
234             =item * %params = Query parameter.
235              
236             =back
237              
238             About the query, please see: http://connpass.com/about/api/
239              
240             =head3 About the fetch like 'AutoPager'
241              
242             You can fetch all search results, by such as this code:
243              
244             # Request event
245             $connpass->fetch( 'event' );
246            
247             # Print each events title
248             while ( my $event = $connpass->next ){
249             print $event->title . "\n";
250             }
251              
252             In the case of default, you can fetch max 10 items by single request to Connpass API.
253             However, this module is able to fetch all results by repeat request, automatically.
254              
255             Also, you can disable this function, by specifying an option(disable_nextpage_fetch => 1) when call a constructor:
256              
257             my $connpass = WebService::Connpass->new(disable_nextpage_fetch => 1);
258              
259             # Request event
260             $connpass->fetch( 'event' );
261            
262             # Print each events title
263             while ( my $event = $connpass->next ){
264             print $event->title . ."\n";
265             }
266              
267             In this case, you can fetch max 10 items.
268              
269             But also, you can fetch more items by causing a 'fetch' method again with 'start' parameter:
270              
271             # Request the event of the remaining again
272             $connpass->fetch( 'event', start => 10 ); # Fetch continue after 10th items.
273              
274             =head2 next
275              
276             Get a next item, from the fetched items in instance.
277              
278             The item that you got is an object.
279              
280             You can use the getter-methods (same as a API response fields name, such as: 'title', 'event_id', 'catch', etc...)
281              
282             my $event = $conpass->next; # Get a next one item
283             print $event->title . "\n"; # Output a 'title' (included in this item)
284              
285             In addition, you can also use a following getter-methods : 'started', 'ended', 'updated'.
286             So, these methods return the each object as the 'DateTime::Format::ISO8601', from 'started_at', 'ended_at' and 'updated_at' field.
287              
288             =head2 prev
289              
290             Get a previous item, from the fetched items in instance.
291              
292             =head2 iter
293              
294             Set or get a position of iterator.
295              
296             =head1 SEE ALSO
297              
298             L<https://github.com/mugifly/p5-WebService-Connpass/> - Your feedback is highly appreciated.
299              
300             L<WebService::Zussar> - https://github.com/mugifly/WebService-Zussar/
301              
302             L<DateTime::Format::ISO8601>
303              
304             L<Hash::AsObject>
305              
306             L<LWP::UserAgent>
307              
308             =head1 COPYRIGHT AND LICENSE
309              
310             Copyright (C) 2013, Masanori Ohgita (http://ohgita.info/).
311              
312             This library is free software; you can redistribute it and/or modify
313             it under the same terms as Perl itself.
314              
315             Thanks, Perl Mongers & CPAN authors.