File Coverage

blib/lib/WebService/HackerNews.pm
Criterion Covered Total %
statement 18 35 51.4
branch n/a
condition 0 4 0.0
subroutine 6 11 54.5
pod 5 5 100.0
total 29 55 52.7


line stmt bran cond sub pod time code
1             package WebService::HackerNews;
2             $WebService::HackerNews::VERSION = '0.03';
3 1     1   548 use 5.006;
  1         3  
  1         33  
4 1     1   458 use Moo;
  1         10781  
  1         5  
5 1     1   3445 use HTTP::Tiny;
  1         36776  
  1         41  
6 1     1   8 use JSON qw(decode_json);
  1         1  
  1         8  
7              
8 1     1   539 use WebService::HackerNews::Item;
  1         3  
  1         31  
9 1     1   459 use WebService::HackerNews::User;
  1         2  
  1         365  
10              
11             has ua => (
12             is => 'ro',
13             default => sub {
14             require HTTP::Tiny;
15             HTTP::Tiny->new;
16             },
17             );
18              
19             has base_url => (
20             is => 'ro',
21             default => sub { 'https://hacker-news.firebaseio.com/v0' },
22             );
23              
24             my $get = sub
25             {
26             my ($self, $relpath) = @_;
27             my $url = $self->base_url.'/'.$relpath;
28             my $response = $self->ua->get($url);
29              
30             # This is a hack. Can I use JSON->allow_nonref to handle
31             # the fact that maxitem returns an int rather than [ int ]?
32             return $response->{content} =~ m!^\s*[{[]!
33             ? decode_json($response->{content})
34             : $response->{content}
35             ;
36             };
37              
38             sub top_story_ids
39             {
40 0     0 1   my $self = shift;
41 0           my $result = $self->$get('topstories.json');
42              
43 0           return @$result;
44             }
45              
46             sub item
47             {
48 0     0 1   my $self = shift;
49 0           my $id = shift;
50 0           my $result = $self->$get("item/$id.json");
51              
52 0           return WebService::HackerNews::Item->new($result);
53             }
54              
55             sub user
56             {
57 0     0 1   my $self = shift;
58 0           my $id = shift;
59 0           my $result = $self->$get("user/$id.json");
60              
61 0           return WebService::HackerNews::User->new($result);
62             }
63              
64             sub max_item_id
65             {
66 0     0 1   my $self = shift;
67 0           my $result = $self->$get('maxitem.json');
68              
69 0           return $result;
70             }
71              
72             sub changed_items_and_users
73             {
74 0     0 1   my $self = shift;
75 0           my $result = $self->$get('updates.json');
76 0   0       return ($result->{items} || [], $result->{profiles} || []);
      0        
77             }
78              
79             1;
80              
81             =head1 NAME
82              
83             WebService::HackerNews - interface to the official HackerNews API
84              
85             =head1 SYNOPSIS
86              
87             use WebService::HackerNews;
88             my $hn = WebService::HackerNews->new;
89             my @top100 = $hn->top_story_ids;
90             my $item = $hn->item( $top100[0] );
91             my $user = $hn->user($item->by);
92              
93             printf qq{"%s" by %s (karma: %d)\n},
94             $item->title, $item->by, $user->karma;
95              
96             =head1 DESCRIPTION
97              
98             This module provides an interface to the official
99             L.
100             This is very much a lash-up at the moment, and liable to change.
101             Feel free to hack on it and send me pull requests.
102              
103             It provides a semi object-oriented interface to the API.
104             You start off by creating an instance of C:
105              
106             $hn = WebService::HackerNews->new;
107              
108             You can then call one of the methods to either get information about
109             I or I.
110              
111             An item is either a story, a job, a comment, a poll, or a pollopt.
112             All items live in a single space, and are identified by a unique
113             integer identifier, or B. Given an id, you can get all information
114             for the associated item using the C method.
115              
116             A user is like an item, but represents a registered user of HackerNews.
117             The id for a user isn't an integer, but is a username.
118             Given a username, you can get all information for the associated user
119             with the C method.
120              
121             Items and User are represented with classes, but where the attributes
122             of items and users relate to further items and classes, they are represented
123             as references to arrays of ids, rather than returning references to arrays
124             of other objects.
125              
126             =head1 METHODS
127              
128             As of version 0.02, this implements all of the functions
129             listed in the official documentation for the API.
130              
131             =head2 top_story_ids
132              
133             Returns a list of ids for the current top 100 stories.
134              
135             my @ids = $hn->top_story_ids;
136              
137             You can then call C to get the details for specific items.
138              
139             =head2 item($ID)
140              
141             Takes an item id and returns an instance of L,
142             which has attributes named exactly the same as the properties listed in
143             the official doc.
144              
145             $item = $hn->item($id);
146             printf "item %d has type %s\n", $item->id, $item->type;
147              
148             =head2 user($ID)
149              
150             Takes a user id and returns an instance of L,
151             which has attributes named exactly the same as the
152             L
153             listed in the official doc.
154              
155             $user = $hn->user($username);
156             printf "user %s has %d karma\n", $user->id, $user->karma;
157              
158             =head2 max_item_id
159              
160             Returns the max item id.
161              
162             =head2 changed_items_and_users
163              
164             Returns two array references, which contain IDs for changed items
165             and usernames for changed users:
166              
167             use WebService::HackerNews 0.02;
168              
169             my $hn = WebService::HackerNews->new;
170             my ($items, $users) = $hn->changed_items_and_users;
171              
172             process_changed_items(@$items);
173             process_changed_users(@$users);
174              
175             This method returns "recently changed items and users",
176             without defining 'changed since when?'.
177             If you want to track changes, you'd just have to poll on a regular basis.
178              
179             This method is really aimed at people using Firebase streaming API.
180              
181             This method was added in version 0.02, so you should specify that as the
182             minimum version of the module, as above.
183              
184             =head1 SEE ALSO
185              
186             L.
187              
188             L.
189              
190             =head1 REPOSITORY
191              
192             L
193              
194             =head1 AUTHOR
195              
196             Neil Bowers Eneilb@cpan.orgE
197              
198             =head1 COPYRIGHT AND LICENSE
199              
200             This software is copyright (c) 2014 by Neil Bowers .
201              
202             This is free software; you can redistribute it and/or modify it under
203             the same terms as the Perl 5 programming language system itself.
204              
205             =cut