line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::Twitter::Stream; |
2
|
1
|
|
|
1
|
|
32878
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
42
|
|
3
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
4
|
1
|
|
|
1
|
|
1781
|
use IO::Socket; |
|
1
|
|
|
|
|
100831
|
|
|
1
|
|
|
|
|
4
|
|
5
|
1
|
|
|
1
|
|
1755
|
use MIME::Base64; |
|
1
|
|
|
|
|
967
|
|
|
1
|
|
|
|
|
60
|
|
6
|
1
|
|
|
1
|
|
6542
|
use JSON; |
|
1
|
|
|
|
|
35210
|
|
|
1
|
|
|
|
|
5
|
|
7
|
1
|
|
|
1
|
|
5102
|
use IO::Socket::SSL; |
|
1
|
|
|
|
|
114824
|
|
|
1
|
|
|
|
|
10
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our $VERSION = '0.28'; |
10
|
|
|
|
|
|
|
1; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Using Twitter's streaming api. |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Net::Twitter::Stream; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Net::Twitter::Stream->new ( user => $username, pass => $password, |
21
|
|
|
|
|
|
|
callback => \&got_tweet, |
22
|
|
|
|
|
|
|
track => 'perl,tinychat,emacs', |
23
|
|
|
|
|
|
|
follow => '27712481,14252288,972651' ); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub got_tweet { |
26
|
|
|
|
|
|
|
my ( $tweet, $json ) = @_; # a hash containing the tweet |
27
|
|
|
|
|
|
|
# and the original json |
28
|
|
|
|
|
|
|
print "By: $tweet->{user}{screen_name}\n"; |
29
|
|
|
|
|
|
|
print "Message: $tweet->{text}\n"; |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=head1 DESCRIPTION |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
The Streaming verson of the Twitter API allows near-realtime access to |
35
|
|
|
|
|
|
|
various subsets of Twitter public statuses. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
The /1/status/filter.json api call can be use to track up to 200 keywords |
38
|
|
|
|
|
|
|
and to follow 200 users. |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
HTTP Basic authentication is supported (no OAuth yet) so you will need |
41
|
|
|
|
|
|
|
a twitter account to connect. |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
JSON format is only supported. Twitter may depreciate XML. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
More details at: http://dev.twitter.com/pages/streaming_api |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
Options |
49
|
|
|
|
|
|
|
user, pass: required, twitter account user/password |
50
|
|
|
|
|
|
|
callback: required, a subroutine called on each received tweet |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
perl@redmond5.com |
54
|
|
|
|
|
|
|
@martinredmond |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 UPDATES |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
https fix: iwan standley |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=cut |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub new { |
64
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
65
|
0
|
|
|
|
|
|
my %args = @_; |
66
|
0
|
0
|
0
|
|
|
|
die "Usage: Net::Twitter::Stream->new ( user => 'user', pass => 'pass', callback => \&got_tweet_cb )" unless |
|
|
|
0
|
|
|
|
|
67
|
|
|
|
|
|
|
$args{user} && $args{pass} && $args{callback}; |
68
|
0
|
|
|
|
|
|
my $self = bless {}; |
69
|
0
|
|
|
|
|
|
$self->{user} = $args{user}; |
70
|
0
|
|
|
|
|
|
$self->{pass} = $args{pass}; |
71
|
0
|
|
|
|
|
|
$self->{got_tweet} = $args{callback}; |
72
|
0
|
0
|
|
|
|
|
$self->{connection_closed} = $args{connection_closed_cb} if |
73
|
|
|
|
|
|
|
$args{connection_closed_cb}; |
74
|
|
|
|
|
|
|
|
75
|
0
|
0
|
|
|
|
|
my $content = "follow=$args{follow}" if $args{follow}; |
76
|
0
|
0
|
|
|
|
|
$content = "track=$args{track}" if $args{track}; |
77
|
0
|
0
|
0
|
|
|
|
$content = "follow=$args{follow}&track=$args{track}\r\n" if $args{track} && $args{follow}; |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
my $auth = encode_base64 ( "$args{user}:$args{pass}" ); |
80
|
0
|
|
|
|
|
|
chomp $auth; |
81
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
my $cl = length $content; |
83
|
0
|
|
|
|
|
|
my $req = <
|
84
|
|
|
|
|
|
|
POST /1/statuses/filter.json HTTP/1.1\r |
85
|
|
|
|
|
|
|
Authorization: Basic $auth\r |
86
|
|
|
|
|
|
|
Host: stream.twitter.com\r |
87
|
|
|
|
|
|
|
User-Agent: net-twitter-stream/0.1\r |
88
|
|
|
|
|
|
|
Content-Type: application/x-www-form-urlencoded\r |
89
|
|
|
|
|
|
|
Content-Length: $cl\r |
90
|
|
|
|
|
|
|
\r |
91
|
|
|
|
|
|
|
EOF |
92
|
|
|
|
|
|
|
|
93
|
0
|
|
|
|
|
|
my $sock = IO::Socket::SSL->new ( PeerAddr => 'stream.twitter.com:https' ); |
94
|
0
|
|
|
|
|
|
$sock->print ( "$req$content" ); |
95
|
0
|
|
|
|
|
|
while ( my $l = $sock->getline ) { |
96
|
0
|
0
|
|
|
|
|
last if $l =~ /^\s*$/; |
97
|
|
|
|
|
|
|
} |
98
|
0
|
|
|
|
|
|
while ( my $l = $sock->getline ) { |
99
|
0
|
0
|
|
|
|
|
next if $l =~ /^\s*$/; # skip empty lines |
100
|
0
|
|
|
|
|
|
$l =~ s/[^a-fA-F0-9]//g; # stop hex from compaining about \r |
101
|
0
|
|
|
|
|
|
my $jsonlen = hex ( $l ); |
102
|
0
|
0
|
|
|
|
|
last if $jsonlen == 0; |
103
|
0
|
|
|
|
|
|
eval { |
104
|
0
|
|
|
|
|
|
my $json; |
105
|
0
|
|
|
|
|
|
my $len = $sock->read ( $json, $jsonlen ); |
106
|
0
|
|
|
|
|
|
my $o = from_json ( $json ); |
107
|
0
|
|
|
|
|
|
$self->{got_tweet} ( $o, $json ); |
108
|
|
|
|
|
|
|
}; |
109
|
|
|
|
|
|
|
} |
110
|
0
|
0
|
|
|
|
|
$self->{connection_closed} ( $sock ) if $self->{connection_closed}; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|