File Coverage

blib/lib/Mojo/FriendFeed.pm
Criterion Covered Total %
statement 37 37 100.0
branch 6 8 75.0
condition 3 5 60.0
subroutine 8 8 100.0
pod 1 1 100.0
total 55 59 93.2


line stmt bran cond sub pod time code
1             package Mojo::FriendFeed 0.05;
2              
3 1     1   912605 use Mojo::Base 'Mojo::EventEmitter';
  1         3  
  1         5  
4 1     1   194 use v5.16;
  1         217  
  1         43  
5              
6 1     1   7 use Mojo::UserAgent;
  1         16  
  1         10  
7 1     1   26 use Mojo::URL;
  1         2  
  1         11  
8              
9 1     1   33 use Scalar::Util 'weaken';
  1         2  
  1         66  
10              
11 1     1   4 use constant DEBUG => $ENV{MOJO_FRIENDFEED_DEBUG};
  1         2  
  1         617  
12              
13             has [qw/request username remote_key/] => '';
14              
15             has ua => sub { Mojo::UserAgent->new->inactivity_timeout(0) };
16              
17             has url => sub {
18             my $self = shift;
19             my $req = $self->request || '';
20             my $url =
21             Mojo::URL
22             ->new("http://friendfeed-api.com/v2/updates$req")
23             ->query( updates => 1 );
24             if ($self->username) {
25             $url->userinfo($self->username . ':' . $self->remote_key);
26             }
27             return $url;
28             };
29              
30             sub listen {
31 5     5 1 1655826 my $self = shift;
32 5         174 my $ua = $self->ua;
33 5         283 my $url = $self->url->clone;
34 5         551 warn "Subscribing to: $url\n" if DEBUG;
35              
36 5         24 weaken $self;
37              
38             $ua->get( $url => sub {
39 9     9   3236299 my ($ua, $tx) = @_;
40              
41 9 100       165 return unless $self;
42              
43 6         12 warn "Received message: @{[$tx->res->body]}" if DEBUG;
44              
45 6         254 my $json = $tx->res->json;
46 6 100 66     1936 unless ($tx->success and $json) {
47 2   50     170 $self->emit( error => $tx, ($json || {})->{errorCode} );
48 1         3220 return;
49             }
50              
51 4         381 $self->emit( entry => $_ ) for @{ $json->{entries} };
  4         44  
52              
53 4 50       199 return unless $self;
54              
55 4 50       15 if ($json->{realtime}) {
56 4         97 my $url = $self->url->clone->query(cursor => $json->{realtime}{cursor});
57 4         790 $ua->get( $url => __SUB__ );
58             }
59 5         60 });
60             }
61              
62             1;
63              
64             =head1 NAME
65              
66             Mojo::FriendFeed - A non-blocking FriendFeed listener for Mojolicious
67              
68             =head1 SYNOPSIS
69              
70             use Mojo::Base -strict;
71             use Mojo::IOLoop;
72             use Mojo::FriendFeed;
73             use Data::Dumper;
74              
75             my $ff = Mojo::FriendFeed->new( request => '/feed/cpan' );
76             $ff->on( entry => sub { say Dumper $_[1] } );
77             $ff->listen;
78              
79             Mojo::IOLoop->start;
80              
81             =head1 DESCRIPTION
82              
83             A simple non-blocking FriendFeed listener for use with the Mojolicious toolkit.
84             Its code is highly influenced by Miyagawa's L.
85              
86             =head1 EVENTS
87              
88             Mojo::FriendFeed inherits all events from L and implements the following new ones.
89              
90             =head2 entry
91              
92             $ff->on( entry => sub {
93             my ($ff, $entry) = @_;
94             ...
95             });
96              
97             Emitted when a new entry has been received, once for each entry.
98             It is passed the instance and the data decoded from the JSON response.
99              
100             =head2 error
101              
102             $ff->on( error => sub {
103             my ($ff, $tx, $ff_error) = @_;
104             ...
105             });
106              
107             Emitted for transaction errors.
108             Fatal if not handled.
109             It is passed the instance, the transaction object, and the "errorCode" sent from FriendFeed if available.
110             Note that after emitting the error event, the C method exits, though you may use this hook to re-attach if desired.
111             Note also that the transaction object's C method is likely to be useful, though note that its behavior changes slightly in Mojolicious 5.0.
112              
113             $ff->on( error => sub { shift->listen } );
114              
115             =head1 ATTRIBUTES
116              
117             Mojo::FriendFeed inherits all attributes from L and implements the following new ones.
118              
119             =head2 request
120              
121             The feed to request. Default is an empty string.
122              
123             =head2 ua
124              
125             An instance of L for making the feed request.
126              
127             =head2 url
128              
129             The (generated) url of the feed. Using the default value is recommended.
130              
131             =head2 username
132              
133             Your FriendFeed username. If set, authentication will be used.
134              
135             =head2 remote_key
136              
137             Your FriendFeed API key. Unused unless C is set.
138              
139             =head1 METHODS
140              
141             Mojo::FriendFeed inherits all methods from L and implements the following new ones.
142              
143             =head2 listen
144              
145             Connects to the feed and attaches events. Note that this does not start an IOLoop and will not block.
146              
147             =head1 SEE ALSO
148              
149             =over
150              
151             =item *
152              
153             L - High performance non-blocking web framework and toolkit for Perl
154              
155             =item *
156              
157             L - IRC interaction for use with the Mojolicious' L
158              
159             =item *
160              
161             L - The inspiration for this module, useful when using L
162              
163             =back
164              
165             =head1 SOURCE REPOSITORY
166              
167             L
168              
169             =head1 AUTHOR
170              
171             Joel Berger, Ejoel.a.berger@gmail.comE
172              
173             =head1 COPYRIGHT AND LICENSE
174              
175             Copyright (C) 2014 by Joel Berger
176              
177             This library is free software; you can redistribute it and/or modify
178             it under the same terms as Perl itself.
179              
180             =cut