Skip to content

Instantly share code, notes, and snippets.

@maugsburger
Created October 14, 2014 11:10
Show Gist options
  • Save maugsburger/f929be60fe6490e244bd to your computer and use it in GitHub Desktop.
Save maugsburger/f929be60fe6490e244bd to your computer and use it in GitHub Desktop.
print twitter follower and friends
#!/usr/bin/perl
use warnings;
use strict;
use v5.10;
use Data::Dumper;
use Net::Twitter::Lite::WithAPIv1_1;
use Net::Twitter::Lite::Error;
use Storable qw/lock_retrieve lock_store/;
use Log::Log4perl qw/:easy/;
use Getopt::Long;
use Pod::Usage;
Log::Log4perl->easy_init($INFO);
my $logger = Log::Log4perl->get_logger();
$| = 1; # autoflush
# ARGS
my %opts;
GetOptions( \%opts,
'oauthkey:s',
'oauthsecret:s',
'verbose+',
'help',
'man',
'export:s',
) or pod2usage(1);
pod2usage(1) if $opts{help};
pod2usage(-exitval => 0, -verbose => 2) if $opts{man};
$logger->more_logging($opts{verbose}) if defined $opts{verbose};
$logger->debug( sub { Data::Dumper->Dump( [\%opts], ['cli_arguments']); });
# READ OLD DATA, IF AVAILABLE
my $datafile = shift @ARGV || pod2usage(-message=>'Filename missing', -exitval =>2);
my $data;
if ( -f $datafile ) {
$data = lock_retrieve($datafile) || $logger->logdie("coultn't read file ", $datafile);
}
$data->{oauthkey} = $opts{oauthkey} if defined $opts{oauthkey};
$data->{oauthsecret} = $opts{oauthsecret} if defined $opts{oauthsecret};
pod2usage(-message=>'oauthkey missing', -exitval =>1) unless defined $data->{oauthkey};
pod2usage(-message=>'oauthsecret missing', -exitval =>1) unless defined $data->{oauthsecret};
# OAUTH, IF NEEDED
our $nt = Net::Twitter::Lite::WithAPIv1_1->new(
consumer_key => $data->{oauthkey},
consumer_secret => $data->{oauthsecret},
ssl => 1
);
# You'll save the token and secret in cookie, config file or session database
if ( $data->{access_token} && $data->{access_token_secret} ) {
$nt->access_token($data->{access_token});
$nt->access_token_secret($data->{access_token_secret});
}
unless ( $nt->authorized ) {
# The client is not yet authorized: Do it now
print "Authorize this app at ", $nt->get_authorization_url, " and enter the PIN\n#";
my $pin = <STDIN>; # wait for input
chomp $pin;
my($access_token, $access_token_secret, $user_id, $screen_name) =
$nt->request_access_token(verifier => $pin);
$data->{access_token} = $access_token;
$data->{access_token_secret} = $access_token_secret;
$data->{user_id} = $user_id;
}
$logger->debug( sub { Data::Dumper->Dump( [$data], ['data']); });
if (lock_store($data, $datafile)) {
$logger->debug("datafile written");
} else {
$logger->warn('error writing datafile, retry next round');
}
# Everything's ready
# CONNECT TO TWITTER
#my $nt = Net::Twitter::Lite->new(
#);
warn "$@\n" if $@;
# start export if wanted
if (defined $opts{export}) {
open EXPORT, '>>', $opts{export} || $logger->logdie("couldn't open #$opts{export}'");
seek ( EXPORT, 0, 2 ) || $logger->logdie("couldn't seek to end of '$opts{export}'");
$logger->info("logging tweets to '", $opts{export}, "'");
}
my $r;
eval { $r = $nt->friends_ids };
$logger->debug( sub { Data::Dumper->Dump( [$r], ['friends_ids']); });
if ( $@ && $@->isa('Net::Twitter::Lite::Error' ) ) {
$logger->warn('Follower error: ', $@->error);
} elsif ( @{$r->{ids}} > 0 ) {
my %list = ids_to_usernames(@{$r->{ids}});
my $c = keys %list;
say "FRIENDS ($c):";
foreach my $id (sort {$a <=> $b} keys %list) {
printf "%12s %s\n", $id, $list{$id};
}
}
print "\n";
eval { $r = $nt->followers_ids };
$logger->debug( sub { Data::Dumper->Dump( [$r], ['followers_ids']); });
if ( $@ && $@->isa('Net::Twitter::Lite::Error' ) ) {
$logger->warn('Follower error: ', $@->error);
} elsif ( @{$r->{ids}} > 0 ) {
my %list = ids_to_usernames(@{$r->{ids}});
my $c = keys %list;
say "FOLLOWER ($c):";
foreach my $id (sort {$a <=> $b} keys %list) {
printf "%12s %s\n", $id, $list{$id};
}
}
sub ids_to_usernames {
our $nt;
my @ids = @_;
my %map;
# api only allows chunks of 100
while( my @u = splice(@ids, 0, 100 ) ) {
my $l;
eval { $l = $nt->lookup_users({ user_id => \@u }) };
if ( $@ && $@->isa('Net::Twitter::Lite::Error' ) ) {
$logger->warn('Follower name error: ', $@->error);
} else {
foreach( @{$l} ) {
$map{$_->{id}} = $_->{screen_name};
}
}
}
return %map;
}
__END__
=head1 NAME
fdump - print twitter follower and friends
=head1 SYNOPSIS
fdump.pl [options] file
Options:
--oauthkey
--oauthsecret
--verbose
--help
--man
=head1 OPTIONS
=over 8
=item B<--oauthkey=key>
Supply OAuth key, required at first run
=item B<--oauthsecret=secret>
Supply OAuth secret, required at first run
=item B<--verbose>
Increment log level (multiple times)
=item B<help>
Show brief usage hints
=item B<man>
Show manpage
=item B<file>
File settings will be saved to
=back
=head1 DESCRIPTION
B<This program> will read the given input file(s) and do something
useful with the contents thereof.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment