* change structure of return value from or_search, mentions_ids
[lab.git] / twitter / user_timeline.pl
1 #! /usr/bin/perl -w
2
3 use strict;
4 use warnings;
5 use utf8;
6
7 ## IMPORTANT ##
8 # When Net::Twitter::Lite encounters a Twitter API error or a network error, 
9 # it throws a Net::Twitter::Lite::Error object. 
10 # You can catch and process these exceptions by using eval blocks and testing $@
11 ## from http://search.cpan.org/perldoc?Net::Twitter::Lite#ERROR_HANDLING
12 use Net::Twitter::Lite;
13 use FindBin qw($Bin);
14 use YAML::Tiny;
15 use Data::Dumper;
16 use Encode;
17
18 if (@ARGV < 1) {
19     die "usage: $0 screen_name [number_of_pages|all [dump]]\n";
20 }
21 my $screen_name = $ARGV[0];
22 my $pages = $ARGV[1] || 1;
23 if ($pages eq 'all') {
24     $pages = -1;
25 }
26 my $dump = $ARGV[2] || 0;
27
28 my $conf = loadconf("$Bin/config.yml");
29 if (! defined $conf) {
30     die "$0: cannot parse config file.\n";
31 }
32
33 my $bot = login($conf);
34 if (! $bot->authorized) {
35     die "$0: this client is not yet authorized.\n";
36 }
37
38
39 eval {
40     my $page = 0;
41     while ($pages - $page && $page <= 160) {
42         $page++;
43         my $res = $bot->user_timeline(
44             {
45                 screen_name => $screen_name,
46                 page        => $page,
47             }
48         );
49         
50         if ($dump) {
51             foreach my $line (split /\n/, Dumper $res) {
52                 if ($line =~ /undef/) { next; }
53                 print $line, "\n";
54             }
55         }
56         else {
57             foreach my $status (@{$res}) {
58                 my $text = "";
59                 $text .= $status->{user}{name};
60                 $text .= " [" . $status->{created_at} . "]";
61                 $text .= " (". $status->{id} . ")";
62                 $text .= " ". encode('utf8', $status->{text});
63                 $text =~ s/\n//;
64                 print $text, "\n";
65             }
66         }
67     }
68 };
69 if ($@) {
70     evalrescue($@);
71 }
72 print "done\n";
73
74
75 sub loadconf {
76     # load configration data from yaml formatted file
77     #   param   => scalar string of filename
78     #   ret     => hash object of yaml data
79     
80     my $file = shift @_;
81     
82     my $yaml = YAML::Tiny->read($file);
83     
84     if ($!) {
85         warn "$0: '$file' $!\n";
86     }
87     
88     return $yaml->[0];
89 }
90
91 sub login {
92     # make Net::Twitter::Lite object and login
93     #   param   => hash object of configration
94     #   ret     => Net::Twitter::Lite object
95     
96     my $conf = shift @_;
97     
98     my $bot = Net::Twitter::Lite->new(
99         consumer_key    => $conf->{consumer_key},
100         consumer_secret => $conf->{consumer_secret},
101     );
102     
103     $bot->access_token($conf->{access_token});
104     $bot->access_token_secret($conf->{access_token_secret});
105     
106     return $bot;
107 }
108
109 sub evalrescue {
110     # output error message at eval error
111     
112     use Scalar::Util qw(blessed);
113     
114     if (blessed $@ && $@->isa('Net::Twitter::Lite::Error')) {
115         warn $@->error;
116         if ($@->twitter_error) {
117             my %twitter_error = %{$@->twitter_error};
118             map {
119                 $twitter_error{"$_ => "} = $twitter_error{$_} . "\n";
120                 delete $twitter_error{$_}
121             } keys %twitter_error;
122             warn join("", %twitter_error);
123         }
124     }
125     else {
126         warn $@;
127     }
128 }