Skip to content
Browse files

Merge pull request #32 from jphpsf/favorites-max

Add support for getting more than 200 favorites
  • Loading branch information...
2 parents 5262168 + d705c79 commit c037e12954ce2250a1dc929c88dc4eeca4e05018 @sferik committed May 5, 2012
Showing with 212 additions and 27 deletions.
  1. +8 −7 lib/t/cli.rb
  2. +26 −0 lib/t/collectable.rb
  3. +2 −2 lib/t/list.rb
  4. +2 −2 lib/t/search.rb
  5. +138 −12 spec/cli_spec.rb
  6. +18 −2 spec/list_spec.rb
  7. +18 −2 spec/search_spec.rb
View
15 lib/t/cli.rb
@@ -40,6 +40,7 @@ class CLI < Thor
DEFAULT_NUM_RESULTS = 20
MAX_SCREEN_NAME_SIZE = 20
MAX_USERS_PER_REQUEST = 100
+ MAX_NUM_RESULTS = 200
check_unknown_options!
@@ -129,7 +130,7 @@ def block(user, *users)
method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
def direct_messages
count = options['number'] || DEFAULT_NUM_RESULTS
- direct_messages = client.direct_messages(:count => count)
+ direct_messages = collect_with_count(:direct_messages, count)
direct_messages.reverse! if options['reverse']
if options['csv']
say ["ID", "Posted at", "Screen name", "Text"].to_csv unless direct_messages.empty?
@@ -163,7 +164,7 @@ def direct_messages
method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
def direct_messages_sent
count = options['number'] || DEFAULT_NUM_RESULTS
- direct_messages = client.direct_messages_sent(:count => count)
+ direct_messages = collect_with_count(:direct_messages_sent, count)
direct_messages.reverse! if options['reverse']
if options['csv']
say ["ID", "Posted at", "Screen name", "Text"].to_csv unless direct_messages.empty?
@@ -327,7 +328,7 @@ def favorites(user=nil)
end
end
count = options['number'] || DEFAULT_NUM_RESULTS
- statuses = client.favorites(user, :count => count)
+ statuses = collect_with_count(:favorites, count, {:args => [user]})
print_statuses(statuses)
end
map %w(faves favourites) => :favorites
@@ -515,7 +516,7 @@ def lists(user=nil)
method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
def mentions
count = options['number'] || DEFAULT_NUM_RESULTS
- statuses = client.mentions(:count => count)
+ statuses = collect_with_count(:mentions, count)
print_statuses(statuses)
end
map %w(replies) => :mentions
@@ -610,7 +611,7 @@ def retweets(user=nil)
end
end
count = options['number'] || DEFAULT_NUM_RESULTS
- statuses = client.retweeted_by(user, :count => count)
+ statuses = collect_with_count(:retweeted_by, count, {:args => [user]})
print_statuses(statuses)
end
map %w(rts) => :retweets
@@ -695,9 +696,9 @@ def timeline(user=nil)
else
user.strip_ats
end
- statuses = client.user_timeline(user, :count => count)
+ statuses = collect_with_count(:user_timeline, count, {:args => [user]})
else
- statuses = client.home_timeline(:count => count)
+ statuses = collect_with_count(:home_timeline, count)
end
print_statuses(statuses)
end
View
26 lib/t/collectable.rb
@@ -1,6 +1,8 @@
module T
module Collectable
+ MAX_NUM_RESULTS = 200
+
def collect_with_cursor(collection=[], cursor=-1, &block)
object = yield cursor
collection += object.collection
@@ -9,9 +11,33 @@ def collect_with_cursor(collection=[], cursor=-1, &block)
def collect_with_max_id(collection=[], max_id=nil, &block)
array = yield max_id
+ return collection unless !array.nil?
collection += array
array.empty? ? collection : collect_with_max_id(collection, array.last.id - 1, &block)
end
+ def collect_with_count(method, count, opts = {})
+ # Most of the APIs use :count to request a specific count. For the few that don't, this allows
+ # to specify a different count parameter (e.g. search uses :rpp and recommendations uses :limit)
+ count_key = opts[:count_key].nil? ? :count : opts[:count_key]
+ params = {}
+ params[count_key] = MAX_NUM_RESULTS
+ statuses = collect_with_max_id do |max_id|
+ params[:max_id] = max_id unless max_id.nil?
+ params[count_key] = count unless count >= MAX_NUM_RESULTS
+ if count > 0
+ count -= MAX_NUM_RESULTS
+ retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
+ if opts[:args].nil? || !opts[:args].is_a?(Array) || opts[:args].empty?
+ client.send(method, params)
+ elsif opts[:args].length === 1
+ client.send(method, opts[:args][0], params)
+ elsif opts[:args].length === 2
+ client.send(method, opts[:args][0], opts[:args][1], params)
+ end
+ end
+ end
+ end.flatten.compact
+ end
end
end
View
4 lib/t/list.rb
@@ -173,8 +173,8 @@ def timeline(list)
owner.strip_ats
end
end
- per_page = options['number'] || DEFAULT_NUM_RESULTS
- statuses = client.list_timeline(owner, list, :per_page => per_page)
+ count = options['number'] || DEFAULT_NUM_RESULTS
+ statuses = collect_with_count(:list_timeline, count, {:args => [owner, list], :count_key => :per_page})
print_statuses(statuses)
end
map %w(tl) => :timeline
View
4 lib/t/search.rb
@@ -33,8 +33,8 @@ def initialize(*)
method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
def all(query)
- rpp = options['number'] || DEFAULT_NUM_RESULTS
- statuses = client.search(query, :rpp => rpp)
+ count = options['number'] || DEFAULT_NUM_RESULTS
+ statuses = collect_with_count(:search, count, {:args => [query], :count_key => :rpp})
if options['csv']
say ["ID", "Posted at", "Screen name", "Text"].to_csv unless statuses.empty?
statuses.each do |status|
View
150 spec/cli_spec.rb
@@ -171,17 +171,33 @@
end
context "--number" do
before do
- @cli.options = @cli.options.merge("number" => 1)
stub_get("/1/direct_messages.json").
with(:query => {:count => "1"}).
to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/direct_messages.json").
+ with(:query => {:count => "200"}).
+ to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/direct_messages.json").
+ with(:query => {:count => "145", :max_id => "1624782205"}).
+ to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results to 1" do
+ @cli.options = @cli.options.merge("number" => 1)
@cli.direct_messages
a_get("/1/direct_messages.json").
with(:query => {:count => "1"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @cli.options = @cli.options.merge("number" => 345)
+ @cli.direct_messages
+ a_get("/1/direct_messages.json").
+ with(:query => {:count => "200"}).
+ should have_been_made
+ a_get("/1/direct_messages.json").
+ with(:query => {:count => "145", :max_id => "1624782205"}).
+ should have_been_made
+ end
end
context "--reverse" do
before do
@@ -276,17 +292,33 @@
end
context "--number" do
before do
- @cli.options = @cli.options.merge("number" => 1)
stub_get("/1/direct_messages/sent.json").
with(:query => {:count => "1"}).
to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/direct_messages/sent.json").
+ with(:query => {:count => "200"}).
+ to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/direct_messages/sent.json").
+ with(:query => {:count => "145", :max_id => "1624782205"}).
+ to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results 1" do
+ @cli.options = @cli.options.merge("number" => 1)
@cli.direct_messages_sent
a_get("/1/direct_messages/sent.json").
with(:query => {:count => "1"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @cli.options = @cli.options.merge("number" => 345)
+ @cli.direct_messages_sent
+ a_get("/1/direct_messages/sent.json").
+ with(:query => {:count => "200"}).
+ should have_been_made
+ a_get("/1/direct_messages/sent.json").
+ with(:query => {:count => "145", :max_id => "1624782205"}).
+ should have_been_made
+ end
end
context "--reverse" do
before do
@@ -809,17 +841,33 @@
end
context "--number" do
before do
- @cli.options = @cli.options.merge("number" => 1)
stub_get("/1/favorites.json").
with(:query => {:count => "1"}).
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/favorites.json").
+ with(:query => {:count => "200"}).
+ to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/favorites.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results to 1" do
+ @cli.options = @cli.options.merge("number" => 1)
@cli.favorites
a_get("/1/favorites.json").
with(:query => {:count => "1"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @cli.options = @cli.options.merge("number" => 345)
+ @cli.favorites
+ a_get("/1/favorites.json").
+ with(:query => {:count => "200"}).
+ should have_been_made
+ a_get("/1/favorites.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ should have_been_made
+ end
end
context "with a user passed" do
before do
@@ -1789,17 +1837,33 @@
end
context "--number" do
before do
- @cli.options = @cli.options.merge("number" => 1)
stub_get("/1/statuses/mentions.json").
with(:query => {:count => "1"}).
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/mentions.json").
+ with(:query => {:count => "200"}).
+ to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/mentions.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results to 1" do
+ @cli.options = @cli.options.merge("number" => 1)
@cli.mentions
a_get("/1/statuses/mentions.json").
with(:query => {:count => "1"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @cli.options = @cli.options.merge("number" => 345)
+ @cli.mentions
+ a_get("/1/statuses/mentions.json").
+ with(:query => {:count => "200"}).
+ should have_been_made
+ a_get("/1/statuses/mentions.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ should have_been_made
+ end
end
end
@@ -2058,17 +2122,33 @@
end
context "--number" do
before do
- @cli.options = @cli.options.merge("number" => 1)
stub_get("/1/statuses/retweeted_by_me.json").
with(:query => {:count => "1"}).
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/retweeted_by_me.json").
+ with(:query => {:count => "200"}).
+ to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/retweeted_by_me.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results to 1" do
+ @cli.options = @cli.options.merge("number" => 1)
@cli.retweets
a_get("/1/statuses/retweeted_by_me.json").
with(:query => {:count => "1"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @cli.options = @cli.options.merge("number" => 345)
+ @cli.retweets
+ a_get("/1/statuses/retweeted_by_me.json").
+ with(:query => {:count => "200"}).
+ should have_been_made
+ a_get("/1/statuses/retweeted_by_me.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ should have_been_made
+ end
end
context "with a user passed" do
before do
@@ -2417,17 +2497,33 @@
end
context "--number" do
before do
- @cli.options = @cli.options.merge("number" => 1)
stub_get("/1/statuses/home_timeline.json").
with(:query => {:count => "1"}).
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/home_timeline.json").
+ with(:query => {:count => "200"}).
+ to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/home_timeline.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results to 1" do
+ @cli.options = @cli.options.merge("number" => 1)
@cli.timeline
a_get("/1/statuses/home_timeline.json").
with(:query => {:count => "1"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @cli.options = @cli.options.merge("number" => 345)
+ @cli.timeline
+ a_get("/1/statuses/home_timeline.json").
+ with(:query => {:count => "200"}).
+ should have_been_made
+ a_get("/1/statuses/home_timeline.json").
+ with(:query => {:count => "145", :max_id => "194546264212385792"}).
+ should have_been_made
+ end
end
context "with a user passed" do
before do
@@ -2455,6 +2551,36 @@
should have_been_made
end
end
+ context "--number" do
+ before do
+ stub_get("/1/statuses/user_timeline.json").
+ with(:query => {:count => "1", :screen_name => "sferik"}).
+ to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/user_timeline.json").
+ with(:query => {:count => "200", :screen_name => "sferik"}).
+ to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/statuses/user_timeline.json").
+ with(:query => {:count => "145", :screen_name => "sferik", :max_id => "194546264212385792"}).
+ to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ end
+ it "should limit the number of results to 1" do
+ @cli.options = @cli.options.merge("number" => 1)
+ @cli.timeline("sferik")
+ a_get("/1/statuses/user_timeline.json").
+ with(:query => {:count => "1", :screen_name => "sferik"}).
+ should have_been_made
+ end
+ it "should limit the number of results to 345" do
+ @cli.options = @cli.options.merge("number" => 345)
+ @cli.timeline("sferik")
+ a_get("/1/statuses/user_timeline.json").
+ with(:query => {:count => "200", :screen_name => "sferik"}).
+ should have_been_made
+ a_get("/1/statuses/user_timeline.json").
+ with(:query => {:count => "145", :screen_name => "sferik", :max_id => "194546264212385792"}).
+ should have_been_made
+ end
+ end
end
end
View
20 spec/list_spec.rb
@@ -452,17 +452,33 @@
end
context "--number" do
before do
- @list.options = @list.options.merge("number" => 1)
stub_get("/1/lists/statuses.json").
with(:query => {:owner_screen_name => "testcli", :per_page => "1", :slug => "presidents"}).
to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/lists/statuses.json").
+ with(:query => {:owner_screen_name => "testcli", :per_page => "200", :slug => "presidents"}).
+ to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_get("/1/lists/statuses.json").
+ with(:query => {:owner_screen_name => "testcli", :per_page => "145", :max_id => "194546264212385792", :slug => "presidents"}).
+ to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results to 1" do
+ @list.options = @list.options.merge("number" => 1)
@list.timeline("presidents")
a_get("/1/lists/statuses.json").
with(:query => {:owner_screen_name => "testcli", :per_page => "1", :slug => "presidents"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @list.options = @list.options.merge("number" => 345)
+ @list.timeline("presidents")
+ a_get("/1/lists/statuses.json").
+ with(:query => {:owner_screen_name => "testcli", :per_page => "200", :slug => "presidents"}).
+ should have_been_made
+ a_get("/1/lists/statuses.json").
+ with(:query => {:owner_screen_name => "testcli", :per_page => "145", :max_id => "194546264212385792", :slug => "presidents"}).
+ should have_been_made
+ end
end
context "with a user passed" do
it "should request the correct resource" do
View
20 spec/search_spec.rb
@@ -95,17 +95,33 @@
end
context "--number" do
before do
- @search.options = @search.options.merge("number" => 1)
stub_request(:get, "https://search.twitter.com/search.json").
with(:query => {:q => "twitter", :rpp => "1"}).
to_return(:body => fixture("search.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_request(:get, "https://search.twitter.com/search.json").
+ with(:query => {:q => "twitter", :rpp => "200"}).
+ to_return(:body => fixture("search.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ stub_request(:get, "https://search.twitter.com/search.json").
+ with(:query => {:q => "twitter", :rpp => "145", :max_id => "194521261307727871"}).
+ to_return(:body => fixture("search.json"), :headers => {:content_type => "application/json; charset=utf-8"})
end
- it "should limit the number of results" do
+ it "should limit the number of results to 1" do
+ @search.options = @search.options.merge("number" => 1)
@search.all("twitter")
a_request(:get, "https://search.twitter.com/search.json").
with(:query => {:q => "twitter", :rpp => "1"}).
should have_been_made
end
+ it "should limit the number of results to 345" do
+ @search.options = @search.options.merge("number" => 345)
+ @search.all("twitter")
+ a_request(:get, "https://search.twitter.com/search.json").
+ with(:query => {:q => "twitter", :rpp => "200"}).
+ should have_been_made
+ a_request(:get, "https://search.twitter.com/search.json").
+ with(:query => {:q => "twitter", :rpp => "145", :max_id => "194521261307727871"}).
+ should have_been_made
+ end
end
end

0 comments on commit c037e12

Please sign in to comment.
Something went wrong with that request. Please try again.