# TwitGet.pm -- Simple Twitter interface # Copyright 2010-2013 Vincent Lefevre . # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA # To register an application and get a consumer key/secret pair: # https://dev.twitter.com/apps/new # The consumer key and the consumer secret must be stored in # a ~/.twitget file on two lines. # See https://dev.twitter.com/docs for the API. # NOTE. With the v1 API, the following was used: # [...] # traits => ['API::RESTv1_1', 'OAuth', 'RateLimit'], # [...] # my $sleep = $nt->until_rate(1.0); # [...] # but the RateLimit role cannot be used with the v1.1 API: as said in # Net/Twitter/Role/RateLimit.pm, "Rate limiting changed so dramatically # with v1.1 this Role simply won't work with it". package TwitGet; require 5.000; use strict; use Carp; use Net::Twitter; use Storable; our ($VERSION) = '$Id: TwitGet.pm 66588 2014-01-15 08:29:22Z vinc17/xvii $' =~ / (\d{4}-\d\d-\d\d \d\d:\d\d:\d\d)Z/; sub VERSION { croak "TwitGet version $_[1] required -- this is only version $VERSION" if $_[1] gt $VERSION } sub init { my $consfile = "$ENV{HOME}/.twitget"; my $datafile = "$ENV{HOME}/.twitget.dat"; open FILE, '<', $consfile or croak "TwitGet: can't open $consfile ($!)"; my $consumer_key = ; defined $consumer_key or croak "TwitGet: bad $consfile format (line 1)"; chomp $consumer_key; my $consumer_secret = ; defined $consumer_secret or croak "TwitGet: bad $consfile format (line 2)"; chomp $consumer_secret; close FILE or croak "TwitGet: can't close $consfile ($!)"; my $nt = Net::Twitter->new ( traits => ['API::RESTv1_1', 'OAuth'], consumer_key => $consumer_key, consumer_secret => $consumer_secret, ssl => 1, ) or croak "TwitGet: Net::Twitter->new failed"; my $access_tokens = eval { retrieve($datafile) } || []; if (@$access_tokens) { $nt->access_token($access_tokens->[0]); $nt->access_token_secret($access_tokens->[1]); } else { require Term::ReadLine; my $term = Term::ReadLine->new('TwitGet'); $term->ornaments(0); my $pin = $term->readline("Authorize this application at:\n ". $nt->get_authorization_url. "\nThen enter the PIN# "); $pin ne '' or croak "TwitGet: PIN not entered\n"; my @access_tokens = $nt->request_access_token(verifier => $pin); store \@access_tokens, $datafile; chmod 0600, $datafile; } return $nt; } sub loop ($$$) { my $nt = $_[0]; my %param = %{$_[1]}; my $subref = $_[2]; while (1) { my $minid = &$subref(\%param) or return; defined $param{since_id} or return; require Math::BigInt; $minid = Math::BigInt->new($minid); $minid->bdec; $param{max_id} = "$minid"; my $sleep = 1; sleep $sleep; } } 1;