root/lang/perl/POE-Component-Client-Twitter/trunk/lib/POE/Component/Client/Twitter.pm @ 34014

Revision 34014, 5.0 kB (checked in by mash, 4 years ago)

update since_id only if there is any

Line 
1package POE::Component::Client::Twitter;
2
3use strict;
4use warnings;
5our $VERSION = '0.01';
6
7use HTTP::Request::Common;
8use HTTP::Date ();
9use JSON qw/decode_json/;
10use POE qw( Component::Client::HTTP );
11use URI;
12
13sub spawn {
14    my($class, %args) = @_;
15
16    %args = (
17        apiurl   => 'http://twitter.com/statuses',
18        apihost  => 'twitter.com:80',
19        apirealm => 'Twitter API',
20        alias    => 'twitter',
21        %args
22    );
23    my $self = bless {}, $class;
24
25    $self->{session_id} = POE::Session->create(
26        object_states => [
27            $self => {
28                _start      => '_start',
29                _stop       => '_stop',
30                _unregister => '_unregister',
31
32                # API
33                register   => 'register',
34                unregister => 'unregister',
35                notify     => 'notify',
36                update     => 'update',
37                friend_timeline => 'friend_timeline',
38                update_success  => 'update_success',
39                friend_timeline_success => 'friend_timeline_success',
40                http_response   => 'http_response',
41            },
42        ],
43        args => [ \%args ],
44        heap => { args => \%args },
45    )->ID;
46
47    POE::Component::Client::HTTP->spawn(
48        Agent => __PACKAGE__ . '/' . $VERSION,
49        Alias => $self->ua_alias,
50    );
51
52    $self;
53}
54
55sub ua_alias {
56    my $self = shift;
57    return "twitter_ua_" . $self->session_id;
58}
59
60sub session_id { $_[0]->{session_id} }
61
62sub yield {
63    my $self = shift;
64    $poe_kernel->post($self->session_id, @_);
65}
66
67sub notify {
68    my($kernel, $heap, $name, $args) = @_[KERNEL, HEAP, ARG0, ARG1];
69    $kernel->post($_ => "twitter.$name" => $args) for keys %{$heap->{listeners}};
70}
71
72sub _start {
73    my($kernel, $heap, $args) = @_[KERNEL, HEAP, ARG0];
74    $kernel->alias_set($args->{alias}) if $args->{alias};
75}
76
77sub _stop {}
78
79sub register {
80    my($kernel, $heap, $sender) = @_[KERNEL, HEAP, SENDER];
81    $kernel->refcount_increment($sender->ID, __PACKAGE__);
82    $heap->{listeners}->{$sender->ID} = 1;
83    $kernel->post($sender->ID => "registered" => $_[SESSION]->ID);
84}
85
86
87sub unregister {
88    my($kernel, $heap, $sender) = @_[KERNEL, HEAP, SENDER];
89    $kernel->yield(_unregister => $sender->ID);
90}
91
92sub _unregister {
93    my($kernel, $heap, $session) = @_[KERNEL, HEAP, ARG0];
94    $kernel->refcount_decrement($session, __PACKAGE__);
95    delete $heap->{listeners}->{$session};
96}
97
98sub update {
99    my ($kernel, $heap, $status, $self) = @_[KERNEL,HEAP,ARG0,OBJECT];
100
101    my $req = HTTP::Request::Common::POST(
102        $heap->{args}->{apiurl} . '/update.json',
103        [ status => $status ],
104    );
105    $req->authorization_basic($heap->{args}->{username}, $heap->{args}->{password});
106
107    $kernel->post($self->ua_alias => request => 'http_response', $req);
108}
109
110sub friend_timeline {
111    my ($kernel, $heap, $status, $self) = @_[KERNEL,HEAP,ARG0,OBJECT];
112
113    my $uri = URI->new($heap->{args}->{apiurl} . '/friends_timeline.json');
114    $uri->query_form( since_id => $heap->{since_id} ) if $heap->{since_id};
115
116    my $req = HTTP::Request->new(GET => $uri);
117    $req->authorization_basic($heap->{args}->{username}, $heap->{args}->{password});
118
119    $kernel->post($self->ua_alias => request => 'http_response', $req);
120}
121
122
123sub update_success {
124    my ($kernel,$heap, $response) = @_[KERNEL,HEAP,ARG0];
125    $kernel->yield(notify => 'update_success',
126        decode_json($response->content)
127    );
128}
129
130sub friend_timeline_success {
131   my ($kernel,$heap, $response) = @_[KERNEL,HEAP,ARG0];
132
133   my $data;
134   $data = decode_json($response->content) if $response->is_success;
135   $heap->{since_id} = $data->[0]->{id} if $data->[0]; # save the latest id and use it in next GET request
136
137   $kernel->yield(notify => 'friend_timeline_success', $data);
138}
139
140sub http_response {
141    my($kernel, $heap, $session, $request_packet, $response_packet) = @_[KERNEL, HEAP, SESSION, ARG0, ARG1];
142
143    my $request  = $request_packet->[0];
144    my $response = $response_packet->[0];
145
146    my $uri = $request->uri;
147    if ($uri =~ /update.json/) {
148        unless ($response->is_success) {
149            $kernel->yield(notify => 'response_error', $response);
150            return;
151        }
152        $kernel->yield(update_success => $response);
153    } elsif ($uri =~ /friends_timeline.json/) {
154        $kernel->yield(friend_timeline_success => $response);
155    }
156}
157
1581;
159__END__
160
161=head1 NAME
162
163POE::Component::Client::Twitter - POE chat component for twitter.com
164
165=head1 SYNOPSIS
166
167  use POE::Component::Client::Twitter;
168
169=head1 DESCRIPTION
170
171POE::Component::Client::Twitter is a POE component for Twitter API. See
172L<http://groups.google.com/group/twitter-development-talk/web/api-documentation> for more details about Twitter API.
173
174This module is in its B<beta quality> and the API and implementation will be
175likely changed along with the further development.
176
177=head1 AUTHOR
178
179Kazuhiro Osawa E<lt>ko@yappo.ne.jpE<gt>
180
181=head1 SEE ALSO
182
183L<POE>, L<http://groups.google.com/group/twitter-development-talk/web/api-documentation>
184
185=head1 LICENSE
186
187This library is free software; you can redistribute it and/or modify
188it under the same terms as Perl itself.
189
190=cut
Note: See TracBrowser for help on using the browser.