twitter_friendly 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef71f130f04b632a363dd5dbe4f7e2b91127d3e74da06b2250d63bf939c90a86
4
- data.tar.gz: 4b0796b5bb063275954bade7042cb0ebe165710d8bc519b7844d78934c6817a0
3
+ metadata.gz: cec5d0d0bab4de7c8cc59727c5c57ce632b76c6e40c3684a66cce539cbb509ef
4
+ data.tar.gz: d37e61958513f084b5eed73f68f9d073202dd58e774138072cb6a1b28b3e70bc
5
5
  SHA512:
6
- metadata.gz: 473bd0e95817c1d6ff726374466fce9eace07ee8b4f3333674f0a2dcfa648b62c47e5641e88a21d4430618c09af342f4f07836fe5190aefeaa5bb3b588c8611a
7
- data.tar.gz: e5af4919178d9602423a7c30944850d09080bd4e9fdc81f55de42466fe6705f23e0ce7a4d51a0abc52d7628db3bcc673791f06735e88cafd5675dac9d7995185
6
+ metadata.gz: 376dbce938d1e5baf735fee3ff09a869ce2b2b562c159046c1a92c37d9e5408d2f5ae4ce005f98eb62d5dbb6f10b31229b15bd402a905c949ad9adbe38aa0aae
7
+ data.tar.gz: 93f140337e9a317165f974e65a992e34a42d1f278add7add063379c882c51aeef54ccb179cef419e02ad21956f3d9aad2f370fad211d5bb680ab587fa8298eeb
data/.gitignore CHANGED
@@ -7,4 +7,8 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ *.log
11
+ /.pryrc
12
+ /.env
13
+ /.twitter_friendly
10
14
  /.idea
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ -fd
@@ -0,0 +1,41 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ # For ruby compatibility, we test the highest and lowest minor versions only.
5
+ # For example, if our gemspec says `required_ruby_version = ">= 2.3.0"`, and
6
+ # ruby 2.5.0 has just been released, then we test 2.3 and 2.5, but not 2.4.
7
+ rvm:
8
+ - 2.3.8
9
+ - 2.4.5
10
+ - 2.5.3
11
+
12
+ env:
13
+ global:
14
+ - TRAVIS=true
15
+
16
+ # We want to use `sudo: false` because the container infrastructure is supposed
17
+ # to be faster, but Travis is having issues with containers lately ..
18
+ #
19
+ # > No output has been received in the last 10m0s
20
+ #
21
+ # .. and they recommend we use the VM infrastructure (`sudo: required`) in
22
+ # the meantime.
23
+ sudo: required
24
+
25
+ before_install:
26
+ - gem update bundler
27
+
28
+ gemfile:
29
+ - gemfiles/ar_4.2.gemfile
30
+ - gemfiles/ar_5.1.gemfile
31
+ - gemfiles/ar_5.2.gemfile
32
+ matrix:
33
+ exclude:
34
+ # optimization: don't test intermediate rubies (see above)
35
+ - rvm: 2.4.5
36
+ gemfile: gemfiles/ar_4.2.gemfile
37
+ - rvm: 2.4.5
38
+ gemfile: gemfiles/ar_5.1.gemfile
39
+ - rvm: 2.4.5
40
+ gemfile: gemfiles/ar_5.2.gemfile
41
+ fast_finish: true
@@ -1,18 +1,29 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- twitter_friendly (0.1.0)
4
+ twitter_friendly (0.2.0)
5
+ activesupport (>= 4.2, < 6.0)
6
+ oj (~> 3.7.6)
5
7
  parallel (~> 1.12.1)
6
8
  twitter (~> 6.2.0)
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
10
12
  specs:
13
+ activesupport (5.2.2)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 0.7, < 2)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
11
18
  addressable (2.5.2)
12
19
  public_suffix (>= 2.0.2, < 4.0)
13
20
  buftok (0.2.0)
21
+ coderay (1.1.2)
22
+ concurrent-ruby (1.1.4)
23
+ diff-lcs (1.3)
14
24
  domain_name (0.5.20180417)
15
25
  unf (>= 0.0.5, < 1.0.0)
26
+ dotenv (2.6.0)
16
27
  equalizer (0.0.11)
17
28
  http (3.3.0)
18
29
  addressable (~> 2.3)
@@ -23,13 +34,35 @@ GEM
23
34
  domain_name (~> 0.5)
24
35
  http-form_data (2.1.1)
25
36
  http_parser.rb (0.6.0)
37
+ i18n (1.5.1)
38
+ concurrent-ruby (~> 1.0)
26
39
  memoizable (0.4.2)
27
40
  thread_safe (~> 0.3, >= 0.3.1)
41
+ method_source (0.9.2)
42
+ minitest (5.11.3)
28
43
  multipart-post (2.0.0)
29
44
  naught (1.1.0)
45
+ oj (3.7.6)
30
46
  parallel (1.12.1)
47
+ pry (0.12.2)
48
+ coderay (~> 1.1.0)
49
+ method_source (~> 0.9.0)
31
50
  public_suffix (3.0.3)
32
- rake (10.5.0)
51
+ rake (12.3.2)
52
+ rb-readline (0.5.5)
53
+ rspec (3.8.0)
54
+ rspec-core (~> 3.8.0)
55
+ rspec-expectations (~> 3.8.0)
56
+ rspec-mocks (~> 3.8.0)
57
+ rspec-core (3.8.0)
58
+ rspec-support (~> 3.8.0)
59
+ rspec-expectations (3.8.2)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.8.0)
62
+ rspec-mocks (3.8.0)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.8.0)
65
+ rspec-support (3.8.0)
33
66
  simple_oauth (0.3.1)
34
67
  thread_safe (0.3.6)
35
68
  twitter (6.2.0)
@@ -43,6 +76,8 @@ GEM
43
76
  multipart-post (~> 2.0)
44
77
  naught (~> 1.0)
45
78
  simple_oauth (~> 0.3.0)
79
+ tzinfo (1.2.5)
80
+ thread_safe (~> 0.1)
46
81
  unf (0.1.4)
47
82
  unf_ext
48
83
  unf_ext (0.0.7.5)
@@ -51,9 +86,13 @@ PLATFORMS
51
86
  ruby
52
87
 
53
88
  DEPENDENCIES
54
- bundler (~> 1.17)
55
- rake (~> 10.0)
89
+ bundler
90
+ dotenv
91
+ pry
92
+ rake
93
+ rb-readline
94
+ rspec (~> 3.8)
56
95
  twitter_friendly!
57
96
 
58
97
  BUNDLED WITH
59
- 1.17.2
98
+ 2.0.1
data/README.md CHANGED
@@ -1,8 +1,13 @@
1
- # TwitterFriendly
1
+ # twitter_friendly
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/twitter_friendly`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Gem Version](https://badge.fury.io/rb/twitter_friendly.png)](https://badge.fury.io/rb/twitter_friendly)
4
+ [![Build Status](https://travis-ci.org/ts-3156/twitter_friendly.svg?branch=master)](https://travis-ci.org/ts-3156/twitter_friendly)
4
5
 
5
- TODO: Delete this and the text above, and describe your gem
6
+ A twitter-friendly Ruby interface to the Twitter API. This twitter_friendly gem provides multiple features.
7
+
8
+ - Auto pagination
9
+ - Auto caching
10
+ - Parallelly fetching
6
11
 
7
12
  ## Installation
8
13
 
@@ -14,25 +19,172 @@ gem 'twitter_friendly'
14
19
 
15
20
  And then execute:
16
21
 
17
- $ bundle
22
+ ```sh
23
+ $ bundle
24
+ ```
18
25
 
19
26
  Or install it yourself as:
20
27
 
21
- $ gem install twitter_friendly
28
+ ```sh
29
+ $ gem install twitter_friendly
30
+ ```
31
+
32
+ ## Configuration
33
+
34
+ You can pass configuration options as a block to `TwitterFriendly::Client.new` just like the below.
35
+
36
+ ```
37
+ client = TwitterFriendly::Client.new do |config|
38
+ config.consumer_key = "YOUR_CONSUMER_KEY"
39
+ config.consumer_secret = "YOUR_CONSUMER_SECRET"
40
+ config.access_token = "YOUR_ACCESS_TOKEN"
41
+ config.access_token_secret = "YOUR_ACCESS_SECRET"
42
+ end
43
+ ```
44
+
45
+ ## Useful features
46
+
47
+ After configuring a `client`, you can do the following things.
48
+
49
+ Fetch all friends's user IDs (by screen name or user ID, or by implicit authenticated user)
50
+
51
+ ```ruby
52
+ ids = client.follower_ids('gem')
53
+ ids.size
54
+ # => 1741
55
+ ```
56
+
57
+ As using a cache, it's super fast from the second time.
58
+
59
+ ```ruby
60
+ Benchmark.bm 20 do |r|
61
+ r.report "Fetch follower_ids" do
62
+ client.follower_ids('gem')
63
+ end
64
+ r.report "(Cached)" do
65
+ client.follower_ids('gem')
66
+ end
67
+ end
68
+
69
+ # user system total real
70
+ # Fetch follower_ids 0.010330 0.003607 0.013937 ( 0.981068)
71
+ # (Cached) 0.000865 0.000153 0.001018 ( 0.001019) <- Roughly 900 times faster!
72
+ ```
73
+
74
+ You don't need to write a boilerplate code as having auto pagination feature.
75
+
76
+ ```ruby
77
+ users = client.follower_ids('a_user_has_many_friends')
78
+ users.size
79
+ # => 50000
80
+ ```
81
+
82
+ If you don't use twitter_friendly gem, you must write the code like the below to fetch all follower's ids.
83
+
84
+ ```ruby
85
+ def collect_with_max_id(collection=[], max_id=nil, &block)
86
+ response = yield(max_id)
87
+ collection += response
88
+ response.empty? ? collection.flatten : collect_with_max_id(collection, response.last.id - 1, &block)
89
+ end
90
+
91
+ ids =
92
+ collect_with_max_id do |max_id|
93
+ options = {count: 200, include_rts: true}
94
+ options[:max_id] = max_id unless max_id.nil?
95
+ client.follower_ids('user_name', options)
96
+ end
97
+ ```
98
+
99
+ Additionally, twitter_friendly gem has a parallel execution feature.
100
+
101
+ ```ruby
102
+ ids = [id1, id2, id3, ... , id1000]
103
+
104
+ Benchmark.bm 25 do |r|
105
+ r.report "Fetch users in parallel" do
106
+ client.users(ids)
107
+ end
108
+
109
+ client.cache.clear
22
110
 
23
- ## Usage
111
+ r.report "Fetch users in serial" do
112
+ client.users(ids, parallel: false)
113
+ end
114
+ end
24
115
 
25
- TODO: Write usage instructions here
116
+ # user system total real
117
+ # Fetch users in parallel 0.271966 0.057981 0.329947 ( 2.675270) <- Super fast!
118
+ # Fetch users in serial 0.201375 0.044399 0.245774 ( 8.068372)
119
+ ```
120
+
121
+ ## Usage examples
122
+
123
+ Fetch all friends's user IDs (by screen name or user ID, or by implicit authenticated user)
124
+
125
+ ```ruby
126
+ client.friend_ids('gem')
127
+ client.friend_ids(213747670)
128
+ client.friend_ids
129
+ ```
130
+
131
+ Fetch all followers's user IDs (by screen name or user ID, or by implicit authenticated user)
132
+
133
+ ```ruby
134
+ client.follower_ids('gem')
135
+ client.follower_ids(213747670)
136
+ client.follower_ids
137
+ ```
138
+
139
+ Fetch all friends with profile details (by screen name or user ID, or by implicit authenticated user)
140
+
141
+ ```ruby
142
+ client.friends('gem')
143
+ client.friends(213747670)
144
+ client.friends
145
+ ```
26
146
 
27
- ## Development
147
+ Fetch all followers with profile details (by screen name or user ID, or by implicit authenticated user)
28
148
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
149
+ ```ruby
150
+ client.followers('gem')
151
+ client.followers(213747670)
152
+ client.followers
153
+ ```
30
154
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
155
+
156
+ Fetch the timeline of Tweets (by screen name or user ID, or by implicit authenticated user)
157
+
158
+ ```ruby
159
+ client.user_timeline('gem')
160
+ client.user_timeline(213747670)
161
+ client.user_timeline
162
+
163
+ result.size
164
+ # => 588
165
+
166
+ result.first.text
167
+ # => "Your tweet text..."
168
+
169
+ result.first.user.screen_name
170
+ # => "your_screen_name"
171
+ ```
172
+
173
+ Fetch the timeline of Tweets from the authenticated user's home page
174
+
175
+ ```ruby
176
+ client.home_timeline
177
+ ```
178
+
179
+ Fetch the timeline of Tweets mentioning the authenticated user
180
+
181
+ ```ruby
182
+ client.mentions_timeline
183
+ ```
32
184
 
33
185
  ## Contributing
34
186
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/twitter_friendly.
187
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ts-3156/twitter_friendly.
36
188
 
37
189
  ## License
38
190
 
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'dotenv/load'
4
+ require 'twitter_friendly'
5
+
6
+ TwitterFriendly.cache.clear
7
+
8
+ client =
9
+ TwitterFriendly::Client.new(
10
+ consumer_key: ENV['CK'],
11
+ consumer_secret: ENV['CS'],
12
+ access_token: ENV['AT'],
13
+ access_token_secret: ENV['ATS']
14
+ )
15
+
16
+ def diff(ary1, ary2)
17
+ [ary1 - ary2, ary2 - ary1]
18
+ end
19
+
20
+ def diff?(ary1, ary2)
21
+ diff(ary1, ary2).flatten.any?
22
+ end
23
+
24
+ def users_diff(ary1, ary2)
25
+ diff(ary1.map {|a| a[:id]}, ary2.map {|a| a[:id]})
26
+ end
27
+
28
+ def users_diff?(ary1, ary2)
29
+ users_diff(ary1, ary2).flatten.any?
30
+ end
31
+
32
+ friend_ids = follower_ids = []
33
+
34
+ %i(friend_ids follower_ids).each do |method|
35
+ ids = client.send(method)
36
+ cached_ids = client.send(method)
37
+ raw_ids = client.internal_client.send(method).attrs[:ids]
38
+
39
+ puts method
40
+ puts " fetch #{ids.size}, cache #{cached_ids.size}, raw #{raw_ids.size}"
41
+ puts " ids is different from cached_ids diff=#{diff(ids, cached_ids).inspect}" if diff?(ids, cached_ids)
42
+ puts " cached_ids is different from raw_ids diff=#{diff(cached_ids, raw_ids).inspect}" if diff?(cached_ids, raw_ids)
43
+ puts " ids is different from raw_ids diff=#{diff(ids, raw_ids).inspect}" if diff?(ids, raw_ids)
44
+ puts " #{client.rate_limit.send(method)}"
45
+
46
+ eval("#{method}=ids")
47
+ end
48
+
49
+ client.cache.clear
50
+
51
+ ids1, ids2 = client.friend_ids_and_follower_ids
52
+ cached_ids1, cached_ids2 = client.friend_ids_and_follower_ids
53
+
54
+ puts 'friend_ids_and_follower_ids'
55
+ puts " fetch #{ids1.size}, cache #{cached_ids1.size}"
56
+ puts " fetch #{ids2.size}, cache #{cached_ids2.size}"
57
+ puts " ids1 is different from cached_ids1 diff=#{diff(ids1, cached_ids1)}" if diff?(ids1, cached_ids1)
58
+ puts " ids2 is different from cached_ids2 diff=#{diff(ids2, cached_ids2)}" if diff?(ids2, cached_ids2)
59
+
60
+ client.cache.clear
61
+
62
+ friends = followers = []
63
+
64
+ %i(friends followers).each do |method|
65
+ users = client.send(method)
66
+ cached_users = client.send(method)
67
+ # raw_users = client.internal_client.send(method).attrs[:users]
68
+
69
+ puts method
70
+ puts " users #{users.size}, cached_users #{cached_users.size}"
71
+ puts " users is different from cached_users diff=#{users_diff(users, cached_users)}" if users_diff?(users, cached_users)
72
+ # puts " cached_users is different from raw_users" if cached_users != raw_users
73
+ # puts " users is different from raw_users" if users != raw_users
74
+ puts " #{client.rate_limit.send(method)}"
75
+
76
+ eval("#{method}=users")
77
+ end
78
+
79
+ client.cache.clear
80
+
81
+ users1, users2 = client.friends_and_followers
82
+ cached_users1, cached_users2 = client.friends_and_followers
83
+
84
+ puts 'friends_and_followers'
85
+ puts " fetch #{users1.size}, cache #{cached_users1.size}"
86
+ puts " fetch #{users2.size}, cache #{cached_users2.size}"
87
+ puts " users1 is different from cached_users1 diff=#{users_diff(users1, cached_users1)}" if users_diff?(users1, cached_users1)
88
+ puts " users2 is different from cached_users2 diff=#{users_diff(users2, cached_users2)}" if users_diff?(users2, cached_users2)
89
+
90
+ client.cache.clear
91
+
92
+ puts friend_ids.zip(friends).all? {|id, user| id == user[:id] }
93
+ puts follower_ids.zip(followers).all? {|id, user| id == user[:id] }
94
+
95
+ puts 'ok'