Skip to content
This repository
Browse code

Merge pull request #32 from jphpsf/favorites-max

Add support for getting more than 200 favorites
  • Loading branch information...
commit c037e12954ce2250a1dc929c88dc4eeca4e05018 2 parents 5262168 + d705c79
Erik Michaels-Ober authored
15 lib/t/cli.rb
@@ -40,6 +40,7 @@ class CLI < Thor
40 40 DEFAULT_NUM_RESULTS = 20
41 41 MAX_SCREEN_NAME_SIZE = 20
42 42 MAX_USERS_PER_REQUEST = 100
  43 + MAX_NUM_RESULTS = 200
43 44
44 45 check_unknown_options!
45 46
@@ -129,7 +130,7 @@ def block(user, *users)
129 130 method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
130 131 def direct_messages
131 132 count = options['number'] || DEFAULT_NUM_RESULTS
132   - direct_messages = client.direct_messages(:count => count)
  133 + direct_messages = collect_with_count(:direct_messages, count)
133 134 direct_messages.reverse! if options['reverse']
134 135 if options['csv']
135 136 say ["ID", "Posted at", "Screen name", "Text"].to_csv unless direct_messages.empty?
@@ -163,7 +164,7 @@ def direct_messages
163 164 method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
164 165 def direct_messages_sent
165 166 count = options['number'] || DEFAULT_NUM_RESULTS
166   - direct_messages = client.direct_messages_sent(:count => count)
  167 + direct_messages = collect_with_count(:direct_messages_sent, count)
167 168 direct_messages.reverse! if options['reverse']
168 169 if options['csv']
169 170 say ["ID", "Posted at", "Screen name", "Text"].to_csv unless direct_messages.empty?
@@ -327,7 +328,7 @@ def favorites(user=nil)
327 328 end
328 329 end
329 330 count = options['number'] || DEFAULT_NUM_RESULTS
330   - statuses = client.favorites(user, :count => count)
  331 + statuses = collect_with_count(:favorites, count, {:args => [user]})
331 332 print_statuses(statuses)
332 333 end
333 334 map %w(faves favourites) => :favorites
@@ -515,7 +516,7 @@ def lists(user=nil)
515 516 method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
516 517 def mentions
517 518 count = options['number'] || DEFAULT_NUM_RESULTS
518   - statuses = client.mentions(:count => count)
  519 + statuses = collect_with_count(:mentions, count)
519 520 print_statuses(statuses)
520 521 end
521 522 map %w(replies) => :mentions
@@ -610,7 +611,7 @@ def retweets(user=nil)
610 611 end
611 612 end
612 613 count = options['number'] || DEFAULT_NUM_RESULTS
613   - statuses = client.retweeted_by(user, :count => count)
  614 + statuses = collect_with_count(:retweeted_by, count, {:args => [user]})
614 615 print_statuses(statuses)
615 616 end
616 617 map %w(rts) => :retweets
@@ -695,9 +696,9 @@ def timeline(user=nil)
695 696 else
696 697 user.strip_ats
697 698 end
698   - statuses = client.user_timeline(user, :count => count)
  699 + statuses = collect_with_count(:user_timeline, count, {:args => [user]})
699 700 else
700   - statuses = client.home_timeline(:count => count)
  701 + statuses = collect_with_count(:home_timeline, count)
701 702 end
702 703 print_statuses(statuses)
703 704 end
26 lib/t/collectable.rb
... ... @@ -1,6 +1,8 @@
1 1 module T
2 2 module Collectable
3 3
  4 + MAX_NUM_RESULTS = 200
  5 +
4 6 def collect_with_cursor(collection=[], cursor=-1, &block)
5 7 object = yield cursor
6 8 collection += object.collection
@@ -9,9 +11,33 @@ def collect_with_cursor(collection=[], cursor=-1, &block)
9 11
10 12 def collect_with_max_id(collection=[], max_id=nil, &block)
11 13 array = yield max_id
  14 + return collection unless !array.nil?
12 15 collection += array
13 16 array.empty? ? collection : collect_with_max_id(collection, array.last.id - 1, &block)
14 17 end
15 18
  19 + def collect_with_count(method, count, opts = {})
  20 + # Most of the APIs use :count to request a specific count. For the few that don't, this allows
  21 + # to specify a different count parameter (e.g. search uses :rpp and recommendations uses :limit)
  22 + count_key = opts[:count_key].nil? ? :count : opts[:count_key]
  23 + params = {}
  24 + params[count_key] = MAX_NUM_RESULTS
  25 + statuses = collect_with_max_id do |max_id|
  26 + params[:max_id] = max_id unless max_id.nil?
  27 + params[count_key] = count unless count >= MAX_NUM_RESULTS
  28 + if count > 0
  29 + count -= MAX_NUM_RESULTS
  30 + retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
  31 + if opts[:args].nil? || !opts[:args].is_a?(Array) || opts[:args].empty?
  32 + client.send(method, params)
  33 + elsif opts[:args].length === 1
  34 + client.send(method, opts[:args][0], params)
  35 + elsif opts[:args].length === 2
  36 + client.send(method, opts[:args][0], opts[:args][1], params)
  37 + end
  38 + end
  39 + end
  40 + end.flatten.compact
  41 + end
16 42 end
17 43 end
4 lib/t/list.rb
@@ -173,8 +173,8 @@ def timeline(list)
173 173 owner.strip_ats
174 174 end
175 175 end
176   - per_page = options['number'] || DEFAULT_NUM_RESULTS
177   - statuses = client.list_timeline(owner, list, :per_page => per_page)
  176 + count = options['number'] || DEFAULT_NUM_RESULTS
  177 + statuses = collect_with_count(:list_timeline, count, {:args => [owner, list], :count_key => :per_page})
178 178 print_statuses(statuses)
179 179 end
180 180 map %w(tl) => :timeline
4 lib/t/search.rb
@@ -33,8 +33,8 @@ def initialize(*)
33 33 method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
34 34 method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
35 35 def all(query)
36   - rpp = options['number'] || DEFAULT_NUM_RESULTS
37   - statuses = client.search(query, :rpp => rpp)
  36 + count = options['number'] || DEFAULT_NUM_RESULTS
  37 + statuses = collect_with_count(:search, count, {:args => [query], :count_key => :rpp})
38 38 if options['csv']
39 39 say ["ID", "Posted at", "Screen name", "Text"].to_csv unless statuses.empty?
40 40 statuses.each do |status|
150 spec/cli_spec.rb
@@ -171,17 +171,33 @@
171 171 end
172 172 context "--number" do
173 173 before do
174   - @cli.options = @cli.options.merge("number" => 1)
175 174 stub_get("/1/direct_messages.json").
176 175 with(:query => {:count => "1"}).
177 176 to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  177 + stub_get("/1/direct_messages.json").
  178 + with(:query => {:count => "200"}).
  179 + to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  180 + stub_get("/1/direct_messages.json").
  181 + with(:query => {:count => "145", :max_id => "1624782205"}).
  182 + to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
178 183 end
179   - it "should limit the number of results" do
  184 + it "should limit the number of results to 1" do
  185 + @cli.options = @cli.options.merge("number" => 1)
180 186 @cli.direct_messages
181 187 a_get("/1/direct_messages.json").
182 188 with(:query => {:count => "1"}).
183 189 should have_been_made
184 190 end
  191 + it "should limit the number of results to 345" do
  192 + @cli.options = @cli.options.merge("number" => 345)
  193 + @cli.direct_messages
  194 + a_get("/1/direct_messages.json").
  195 + with(:query => {:count => "200"}).
  196 + should have_been_made
  197 + a_get("/1/direct_messages.json").
  198 + with(:query => {:count => "145", :max_id => "1624782205"}).
  199 + should have_been_made
  200 + end
185 201 end
186 202 context "--reverse" do
187 203 before do
@@ -276,17 +292,33 @@
276 292 end
277 293 context "--number" do
278 294 before do
279   - @cli.options = @cli.options.merge("number" => 1)
280 295 stub_get("/1/direct_messages/sent.json").
281 296 with(:query => {:count => "1"}).
282 297 to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  298 + stub_get("/1/direct_messages/sent.json").
  299 + with(:query => {:count => "200"}).
  300 + to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  301 + stub_get("/1/direct_messages/sent.json").
  302 + with(:query => {:count => "145", :max_id => "1624782205"}).
  303 + to_return(:body => fixture("direct_messages.json"), :headers => {:content_type => "application/json; charset=utf-8"})
283 304 end
284   - it "should limit the number of results" do
  305 + it "should limit the number of results 1" do
  306 + @cli.options = @cli.options.merge("number" => 1)
285 307 @cli.direct_messages_sent
286 308 a_get("/1/direct_messages/sent.json").
287 309 with(:query => {:count => "1"}).
288 310 should have_been_made
289 311 end
  312 + it "should limit the number of results to 345" do
  313 + @cli.options = @cli.options.merge("number" => 345)
  314 + @cli.direct_messages_sent
  315 + a_get("/1/direct_messages/sent.json").
  316 + with(:query => {:count => "200"}).
  317 + should have_been_made
  318 + a_get("/1/direct_messages/sent.json").
  319 + with(:query => {:count => "145", :max_id => "1624782205"}).
  320 + should have_been_made
  321 + end
290 322 end
291 323 context "--reverse" do
292 324 before do
@@ -809,17 +841,33 @@
809 841 end
810 842 context "--number" do
811 843 before do
812   - @cli.options = @cli.options.merge("number" => 1)
813 844 stub_get("/1/favorites.json").
814 845 with(:query => {:count => "1"}).
815 846 to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  847 + stub_get("/1/favorites.json").
  848 + with(:query => {:count => "200"}).
  849 + to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  850 + stub_get("/1/favorites.json").
  851 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  852 + to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
816 853 end
817   - it "should limit the number of results" do
  854 + it "should limit the number of results to 1" do
  855 + @cli.options = @cli.options.merge("number" => 1)
818 856 @cli.favorites
819 857 a_get("/1/favorites.json").
820 858 with(:query => {:count => "1"}).
821 859 should have_been_made
822 860 end
  861 + it "should limit the number of results to 345" do
  862 + @cli.options = @cli.options.merge("number" => 345)
  863 + @cli.favorites
  864 + a_get("/1/favorites.json").
  865 + with(:query => {:count => "200"}).
  866 + should have_been_made
  867 + a_get("/1/favorites.json").
  868 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  869 + should have_been_made
  870 + end
823 871 end
824 872 context "with a user passed" do
825 873 before do
@@ -1789,17 +1837,33 @@
1789 1837 end
1790 1838 context "--number" do
1791 1839 before do
1792   - @cli.options = @cli.options.merge("number" => 1)
1793 1840 stub_get("/1/statuses/mentions.json").
1794 1841 with(:query => {:count => "1"}).
1795 1842 to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  1843 + stub_get("/1/statuses/mentions.json").
  1844 + with(:query => {:count => "200"}).
  1845 + to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  1846 + stub_get("/1/statuses/mentions.json").
  1847 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  1848 + to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
1796 1849 end
1797   - it "should limit the number of results" do
  1850 + it "should limit the number of results to 1" do
  1851 + @cli.options = @cli.options.merge("number" => 1)
1798 1852 @cli.mentions
1799 1853 a_get("/1/statuses/mentions.json").
1800 1854 with(:query => {:count => "1"}).
1801 1855 should have_been_made
1802 1856 end
  1857 + it "should limit the number of results to 345" do
  1858 + @cli.options = @cli.options.merge("number" => 345)
  1859 + @cli.mentions
  1860 + a_get("/1/statuses/mentions.json").
  1861 + with(:query => {:count => "200"}).
  1862 + should have_been_made
  1863 + a_get("/1/statuses/mentions.json").
  1864 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  1865 + should have_been_made
  1866 + end
1803 1867 end
1804 1868 end
1805 1869
@@ -2058,17 +2122,33 @@
2058 2122 end
2059 2123 context "--number" do
2060 2124 before do
2061   - @cli.options = @cli.options.merge("number" => 1)
2062 2125 stub_get("/1/statuses/retweeted_by_me.json").
2063 2126 with(:query => {:count => "1"}).
2064 2127 to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  2128 + stub_get("/1/statuses/retweeted_by_me.json").
  2129 + with(:query => {:count => "200"}).
  2130 + to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  2131 + stub_get("/1/statuses/retweeted_by_me.json").
  2132 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  2133 + to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
2065 2134 end
2066   - it "should limit the number of results" do
  2135 + it "should limit the number of results to 1" do
  2136 + @cli.options = @cli.options.merge("number" => 1)
2067 2137 @cli.retweets
2068 2138 a_get("/1/statuses/retweeted_by_me.json").
2069 2139 with(:query => {:count => "1"}).
2070 2140 should have_been_made
2071 2141 end
  2142 + it "should limit the number of results to 345" do
  2143 + @cli.options = @cli.options.merge("number" => 345)
  2144 + @cli.retweets
  2145 + a_get("/1/statuses/retweeted_by_me.json").
  2146 + with(:query => {:count => "200"}).
  2147 + should have_been_made
  2148 + a_get("/1/statuses/retweeted_by_me.json").
  2149 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  2150 + should have_been_made
  2151 + end
2072 2152 end
2073 2153 context "with a user passed" do
2074 2154 before do
@@ -2417,17 +2497,33 @@
2417 2497 end
2418 2498 context "--number" do
2419 2499 before do
2420   - @cli.options = @cli.options.merge("number" => 1)
2421 2500 stub_get("/1/statuses/home_timeline.json").
2422 2501 with(:query => {:count => "1"}).
2423 2502 to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  2503 + stub_get("/1/statuses/home_timeline.json").
  2504 + with(:query => {:count => "200"}).
  2505 + to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  2506 + stub_get("/1/statuses/home_timeline.json").
  2507 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  2508 + to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
2424 2509 end
2425   - it "should limit the number of results" do
  2510 + it "should limit the number of results to 1" do
  2511 + @cli.options = @cli.options.merge("number" => 1)
2426 2512 @cli.timeline
2427 2513 a_get("/1/statuses/home_timeline.json").
2428 2514 with(:query => {:count => "1"}).
2429 2515 should have_been_made
2430 2516 end
  2517 + it "should limit the number of results to 345" do
  2518 + @cli.options = @cli.options.merge("number" => 345)
  2519 + @cli.timeline
  2520 + a_get("/1/statuses/home_timeline.json").
  2521 + with(:query => {:count => "200"}).
  2522 + should have_been_made
  2523 + a_get("/1/statuses/home_timeline.json").
  2524 + with(:query => {:count => "145", :max_id => "194546264212385792"}).
  2525 + should have_been_made
  2526 + end
2431 2527 end
2432 2528 context "with a user passed" do
2433 2529 before do
@@ -2455,6 +2551,36 @@
2455 2551 should have_been_made
2456 2552 end
2457 2553 end
  2554 + context "--number" do
  2555 + before do
  2556 + stub_get("/1/statuses/user_timeline.json").
  2557 + with(:query => {:count => "1", :screen_name => "sferik"}).
  2558 + to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  2559 + stub_get("/1/statuses/user_timeline.json").
  2560 + with(:query => {:count => "200", :screen_name => "sferik"}).
  2561 + to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  2562 + stub_get("/1/statuses/user_timeline.json").
  2563 + with(:query => {:count => "145", :screen_name => "sferik", :max_id => "194546264212385792"}).
  2564 + to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  2565 + end
  2566 + it "should limit the number of results to 1" do
  2567 + @cli.options = @cli.options.merge("number" => 1)
  2568 + @cli.timeline("sferik")
  2569 + a_get("/1/statuses/user_timeline.json").
  2570 + with(:query => {:count => "1", :screen_name => "sferik"}).
  2571 + should have_been_made
  2572 + end
  2573 + it "should limit the number of results to 345" do
  2574 + @cli.options = @cli.options.merge("number" => 345)
  2575 + @cli.timeline("sferik")
  2576 + a_get("/1/statuses/user_timeline.json").
  2577 + with(:query => {:count => "200", :screen_name => "sferik"}).
  2578 + should have_been_made
  2579 + a_get("/1/statuses/user_timeline.json").
  2580 + with(:query => {:count => "145", :screen_name => "sferik", :max_id => "194546264212385792"}).
  2581 + should have_been_made
  2582 + end
  2583 + end
2458 2584 end
2459 2585 end
2460 2586
20 spec/list_spec.rb
@@ -452,17 +452,33 @@
452 452 end
453 453 context "--number" do
454 454 before do
455   - @list.options = @list.options.merge("number" => 1)
456 455 stub_get("/1/lists/statuses.json").
457 456 with(:query => {:owner_screen_name => "testcli", :per_page => "1", :slug => "presidents"}).
458 457 to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  458 + stub_get("/1/lists/statuses.json").
  459 + with(:query => {:owner_screen_name => "testcli", :per_page => "200", :slug => "presidents"}).
  460 + to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  461 + stub_get("/1/lists/statuses.json").
  462 + with(:query => {:owner_screen_name => "testcli", :per_page => "145", :max_id => "194546264212385792", :slug => "presidents"}).
  463 + to_return(:body => fixture("empty_array.json"), :headers => {:content_type => "application/json; charset=utf-8"})
459 464 end
460   - it "should limit the number of results" do
  465 + it "should limit the number of results to 1" do
  466 + @list.options = @list.options.merge("number" => 1)
461 467 @list.timeline("presidents")
462 468 a_get("/1/lists/statuses.json").
463 469 with(:query => {:owner_screen_name => "testcli", :per_page => "1", :slug => "presidents"}).
464 470 should have_been_made
465 471 end
  472 + it "should limit the number of results to 345" do
  473 + @list.options = @list.options.merge("number" => 345)
  474 + @list.timeline("presidents")
  475 + a_get("/1/lists/statuses.json").
  476 + with(:query => {:owner_screen_name => "testcli", :per_page => "200", :slug => "presidents"}).
  477 + should have_been_made
  478 + a_get("/1/lists/statuses.json").
  479 + with(:query => {:owner_screen_name => "testcli", :per_page => "145", :max_id => "194546264212385792", :slug => "presidents"}).
  480 + should have_been_made
  481 + end
466 482 end
467 483 context "with a user passed" do
468 484 it "should request the correct resource" do
20 spec/search_spec.rb
@@ -95,17 +95,33 @@
95 95 end
96 96 context "--number" do
97 97 before do
98   - @search.options = @search.options.merge("number" => 1)
99 98 stub_request(:get, "https://search.twitter.com/search.json").
100 99 with(:query => {:q => "twitter", :rpp => "1"}).
101 100 to_return(:body => fixture("search.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  101 + stub_request(:get, "https://search.twitter.com/search.json").
  102 + with(:query => {:q => "twitter", :rpp => "200"}).
  103 + to_return(:body => fixture("search.json"), :headers => {:content_type => "application/json; charset=utf-8"})
  104 + stub_request(:get, "https://search.twitter.com/search.json").
  105 + with(:query => {:q => "twitter", :rpp => "145", :max_id => "194521261307727871"}).
  106 + to_return(:body => fixture("search.json"), :headers => {:content_type => "application/json; charset=utf-8"})
102 107 end
103   - it "should limit the number of results" do
  108 + it "should limit the number of results to 1" do
  109 + @search.options = @search.options.merge("number" => 1)
104 110 @search.all("twitter")
105 111 a_request(:get, "https://search.twitter.com/search.json").
106 112 with(:query => {:q => "twitter", :rpp => "1"}).
107 113 should have_been_made
108 114 end
  115 + it "should limit the number of results to 345" do
  116 + @search.options = @search.options.merge("number" => 345)
  117 + @search.all("twitter")
  118 + a_request(:get, "https://search.twitter.com/search.json").
  119 + with(:query => {:q => "twitter", :rpp => "200"}).
  120 + should have_been_made
  121 + a_request(:get, "https://search.twitter.com/search.json").
  122 + with(:query => {:q => "twitter", :rpp => "145", :max_id => "194521261307727871"}).
  123 + should have_been_made
  124 + end
109 125 end
110 126 end
111 127

0 comments on commit c037e12

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