ex_twitter 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ex_twitter.gemspec +1 -1
- data/lib/ex_twitter/client.rb +0 -59
- data/lib/ex_twitter/existing_api.rb +3 -5
- data/lib/ex_twitter/new_api.rb +107 -16
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29d8daa0330612db348fe30bb6b1cbfa6c0885ff
|
4
|
+
data.tar.gz: c602c974e8090a18c2f097aa8e42f0f1d9409f11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd36a6d3a5db84ea97bf6340a7191bb73a88cc974f96f2da32be73b3e0a8b289bfac3472af1a39ffc0fe80c085ff5f39ca1e6bc975ddf9c7eb4ba724ca17cc34
|
7
|
+
data.tar.gz: a776361322fb184b4527bc6a9a28ec478911a68d5011afd81a6a5a64f03d9db9b949dff9b561108c4be0e868b8bc7c4c73c98a23193c54a7982647a20d58a547
|
data/ex_twitter.gemspec
CHANGED
data/lib/ex_twitter/client.rb
CHANGED
@@ -135,64 +135,5 @@ module ExTwitter
|
|
135
135
|
twitter_addiction_series(times)
|
136
136
|
]
|
137
137
|
end
|
138
|
-
|
139
|
-
|
140
|
-
def calc_scores_from_users(users, options)
|
141
|
-
min = options.has_key?(:min) ? options[:min] : 0
|
142
|
-
max = options.has_key?(:max) ? options[:max] : 1000
|
143
|
-
users.each_with_object(Hash.new(0)) { |u, memo| memo[u.id] += 1 }.
|
144
|
-
select { |_k, v| min <= v && v <= max }.
|
145
|
-
sort_by { |_, v| -v }.to_h
|
146
|
-
end
|
147
|
-
|
148
|
-
def calc_scores_from_tweets(tweets, options = {})
|
149
|
-
calc_scores_from_users(tweets.map { |t| t.user }, options)
|
150
|
-
end
|
151
|
-
|
152
|
-
def select_favoriting_from_favs(favs, options = {})
|
153
|
-
return [] if favs.empty?
|
154
|
-
uids = calc_scores_from_tweets(favs)
|
155
|
-
result = uids.map { |uid, score| f = favs.
|
156
|
-
find { |f| f.user.id.to_i == uid.to_i }; Array.new(score, f) }.flatten.map { |f| f.user }
|
157
|
-
(options.has_key?(:uniq) && !options[:uniq]) ? result : result.uniq { |u| u.id }
|
158
|
-
end
|
159
|
-
|
160
|
-
def favoriting(user, options= {})
|
161
|
-
favs = options.has_key?(:favorites) ? options.delete(:favorites) : favorites(user, options)
|
162
|
-
select_favoriting_from_favs(favs, options)
|
163
|
-
rescue => e
|
164
|
-
logger.warn "#{__method__} #{user.inspect} #{e.class} #{e.message}"
|
165
|
-
raise e
|
166
|
-
end
|
167
|
-
|
168
|
-
def favorited_by(user)
|
169
|
-
end
|
170
|
-
|
171
|
-
def close_friends(_uid, options = {})
|
172
|
-
min = options.has_key?(:min) ? options[:min] : 0
|
173
|
-
max = options.has_key?(:max) ? options[:max] : 1000
|
174
|
-
uid_i = _uid.to_i
|
175
|
-
_replying = options.has_key?(:replying) ? options.delete(:replying) : replying(uid_i, options)
|
176
|
-
_replied = options.has_key?(:replied) ? options.delete(:replied) : replied(uid_i, options)
|
177
|
-
_favoriting = options.has_key?(:favoriting) ? options.delete(:favoriting) : favoriting(uid_i, options)
|
178
|
-
|
179
|
-
min_max = {min: min, max: max}
|
180
|
-
_users = _replying + _replied + _favoriting
|
181
|
-
return [] if _users.empty?
|
182
|
-
|
183
|
-
scores = calc_scores_from_users(_users, min_max)
|
184
|
-
replying_scores = calc_scores_from_users(_replying, min_max)
|
185
|
-
replied_scores = calc_scores_from_users(_replied, min_max)
|
186
|
-
favoriting_scores = calc_scores_from_users(_favoriting, min_max)
|
187
|
-
|
188
|
-
scores.keys.map { |uid| _users.find { |u| u.id.to_i == uid.to_i } }.
|
189
|
-
map do |u|
|
190
|
-
u[:score] = scores[u.id]
|
191
|
-
u[:replying_score] = replying_scores[u.id]
|
192
|
-
u[:replied_score] = replied_scores[u.id]
|
193
|
-
u[:favoriting_score] = favoriting_scores[u.id]
|
194
|
-
u
|
195
|
-
end
|
196
|
-
end
|
197
138
|
end
|
198
139
|
end
|
@@ -68,6 +68,7 @@ module ExTwitter
|
|
68
68
|
|
69
69
|
# use compact, not use sort and uniq
|
70
70
|
# specify reduce: false to use tweet for inactive_*
|
71
|
+
# TODO Perhaps `old_users` automatically merges result...
|
71
72
|
def users(*args)
|
72
73
|
options = args.extract_options!
|
73
74
|
options[:reduce] = false
|
@@ -83,14 +84,11 @@ module ExTwitter
|
|
83
84
|
end
|
84
85
|
|
85
86
|
processed_users.sort_by{|p| p[:i] }.map{|p| p[:users] }.flatten.compact
|
86
|
-
rescue => e # debug
|
87
|
-
logger.warn "#{__method__}: #{args.inspect} #{e.class} #{e.message}"
|
88
|
-
raise e
|
89
87
|
end
|
90
88
|
|
91
89
|
def home_timeline(*args)
|
92
90
|
options = {count: 200, include_rts: true, call_limit: 3}.merge(args.extract_options!)
|
93
|
-
fetch_cache_or_call_api(__method__, user.
|
91
|
+
fetch_cache_or_call_api(__method__, user.id, options) {
|
94
92
|
collect_with_max_id("old_#{__method__}", options)
|
95
93
|
}
|
96
94
|
end
|
@@ -105,7 +103,7 @@ module ExTwitter
|
|
105
103
|
|
106
104
|
def mentions_timeline(*args)
|
107
105
|
options = {count: 200, include_rts: true, call_limit: 1}.merge(args.extract_options!)
|
108
|
-
fetch_cache_or_call_api(__method__, user.
|
106
|
+
fetch_cache_or_call_api(__method__, user.id, options) {
|
109
107
|
collect_with_max_id("old_#{__method__}", options)
|
110
108
|
}
|
111
109
|
end
|
data/lib/ex_twitter/new_api.rb
CHANGED
@@ -110,11 +110,10 @@ module ExTwitter
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
-
def _extract_screen_names(tweets
|
114
|
-
|
113
|
+
def _extract_screen_names(tweets)
|
114
|
+
tweets.map do |t|
|
115
115
|
$1 if t.text =~ /^(?:\.)?@(\w+)( |\W)/ # include statuses starts with .
|
116
116
|
end.compact
|
117
|
-
(options.has_key?(:uniq) && !options[:uniq]) ? result : result.uniq
|
118
117
|
end
|
119
118
|
|
120
119
|
# users which specified user is replying
|
@@ -123,7 +122,7 @@ module ExTwitter
|
|
123
122
|
options = args.extract_options!
|
124
123
|
tweets =
|
125
124
|
if args.empty?
|
126
|
-
user_timeline(
|
125
|
+
user_timeline(options)
|
127
126
|
elsif uid_or_screen_name?(args[0])
|
128
127
|
user_timeline(args[0], options)
|
129
128
|
elsif args[0].kind_of?(Array) && args[0].all? { |t| t.respond_to?(:text) }
|
@@ -131,8 +130,14 @@ module ExTwitter
|
|
131
130
|
else
|
132
131
|
raise
|
133
132
|
end
|
134
|
-
|
135
|
-
|
133
|
+
|
134
|
+
screen_names = _extract_screen_names(tweets)
|
135
|
+
result = users(screen_names, {super_operation: __method__}.merge(options))
|
136
|
+
if options.has_key?(:uniq) && !options[:uniq]
|
137
|
+
screen_names.map { |sn| result.find { |r| r.screen_name == sn } }
|
138
|
+
else
|
139
|
+
result.uniq { |r| r.id }
|
140
|
+
end
|
136
141
|
rescue Twitter::Error::NotFound => e
|
137
142
|
e.message == 'No user matches for specified terms.' ? [] : (raise e)
|
138
143
|
rescue => e
|
@@ -140,15 +145,14 @@ module ExTwitter
|
|
140
145
|
raise e
|
141
146
|
end
|
142
147
|
|
143
|
-
def _extract_uids(tweets
|
144
|
-
|
148
|
+
def _extract_uids(tweets)
|
149
|
+
tweets.map do |t|
|
145
150
|
t.user.id.to_i if t.text =~ /^(?:\.)?@(\w+)( |\W)/ # include statuses starts with .
|
146
151
|
end.compact
|
147
|
-
(options.has_key?(:uniq) && !options[:uniq]) ? result : result.uniq
|
148
152
|
end
|
149
153
|
|
150
|
-
def _extract_users(tweets, uids
|
151
|
-
uids.map { |
|
154
|
+
def _extract_users(tweets, uids)
|
155
|
+
uids.map { |uid| tweets.find { |t| t.user.id.to_i == uid.to_i } }.map { |t| t.user }.compact
|
152
156
|
end
|
153
157
|
|
154
158
|
# users which specified user is replied
|
@@ -156,13 +160,61 @@ module ExTwitter
|
|
156
160
|
def replied(*args)
|
157
161
|
options = args.extract_options!
|
158
162
|
|
159
|
-
|
160
|
-
|
163
|
+
result =
|
164
|
+
if args.empty? || (uid_or_screen_name?(args[0]) && authenticating_user?(args[0]))
|
165
|
+
mentions_timeline.map { |m| m.user }
|
166
|
+
else
|
167
|
+
searched_result = search('@' + user(args[0]).screen_name, options)
|
168
|
+
uids = _extract_uids(searched_result)
|
169
|
+
_extract_users(searched_result, uids)
|
170
|
+
end
|
171
|
+
|
172
|
+
if options.has_key?(:uniq) && !options[:uniq]
|
173
|
+
result
|
174
|
+
else
|
175
|
+
result.uniq { |r| r.id }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def _count_users_with_two_sided_threshold(users, options)
|
180
|
+
min = options.has_key?(:min) ? options[:min] : 0
|
181
|
+
max = options.has_key?(:max) ? options[:max] : 1000
|
182
|
+
users.each_with_object(Hash.new(0)) { |u, memo| memo[u.id] += 1 }.
|
183
|
+
select { |_k, v| min <= v && v <= max }.
|
184
|
+
sort_by { |_, v| -v }.to_h
|
185
|
+
end
|
186
|
+
|
187
|
+
def _extract_favorite_users(favs, options = {})
|
188
|
+
counted_value = _count_users_with_two_sided_threshold(favs.map { |t| t.user }, options)
|
189
|
+
counted_value.map do |uid, cnt|
|
190
|
+
fav = favs.find { |f| f.user.id.to_i == uid.to_i }
|
191
|
+
Array.new(cnt, fav.user)
|
192
|
+
end.flatten
|
193
|
+
end
|
194
|
+
|
195
|
+
def favoriting(*args)
|
196
|
+
options = args.extract_options!
|
197
|
+
|
198
|
+
favs =
|
199
|
+
if args.empty?
|
200
|
+
favorites(options)
|
201
|
+
elsif uid_or_screen_name?(args[0])
|
202
|
+
favorites(args[0], options)
|
203
|
+
elsif args[0].kind_of?(Array) && args[0].all? { |t| t.respond_to?(:text) }
|
204
|
+
args[0]
|
205
|
+
else
|
206
|
+
raise
|
207
|
+
end
|
208
|
+
|
209
|
+
result = _extract_favorite_users(favs, options)
|
210
|
+
if options.has_key?(:uniq) && !options[:uniq]
|
211
|
+
result
|
161
212
|
else
|
162
|
-
|
163
|
-
uids = _extract_uids(searched_result, options)
|
164
|
-
_extract_users(searched_result, uids, options)
|
213
|
+
result.uniq { |r| r.id }
|
165
214
|
end
|
215
|
+
rescue => e
|
216
|
+
logger.warn "#{__method__} #{user.inspect} #{e.class} #{e.message}"
|
217
|
+
raise e
|
166
218
|
end
|
167
219
|
|
168
220
|
def _extract_inactive_users(users, options = {})
|
@@ -177,6 +229,45 @@ module ExTwitter
|
|
177
229
|
end
|
178
230
|
end
|
179
231
|
|
232
|
+
def favorited_by(*args)
|
233
|
+
end
|
234
|
+
|
235
|
+
def close_friends(*args)
|
236
|
+
options = {uniq: false}.merge(args.extract_options!)
|
237
|
+
min_max = {
|
238
|
+
min: options.has_key?(:min) ? options.delete(:min) : 0,
|
239
|
+
max: options.has_key?(:max) ? options.delete(:max) : 1000
|
240
|
+
}
|
241
|
+
|
242
|
+
_replying, _replied, _favoriting =
|
243
|
+
if args.empty?
|
244
|
+
[replying(options), replied(options), favoriting(options)]
|
245
|
+
elsif uid_or_screen_name?(args[0])
|
246
|
+
[replying(args[0], options), replied(args[0], options), favoriting(args[0], options)]
|
247
|
+
elsif (m_names = %i(replying replied favoriting)).all? { |m_name| args[0].respond_to?(m_name) }
|
248
|
+
m_names.map { |mn| args[0].send(mn) }
|
249
|
+
else
|
250
|
+
raise
|
251
|
+
end
|
252
|
+
|
253
|
+
_users = _replying + _replied + _favoriting
|
254
|
+
return [] if _users.empty?
|
255
|
+
|
256
|
+
scores = _count_users_with_two_sided_threshold(_users, min_max)
|
257
|
+
replying_scores = _count_users_with_two_sided_threshold(_replying, min_max)
|
258
|
+
replied_scores = _count_users_with_two_sided_threshold(_replied, min_max)
|
259
|
+
favoriting_scores = _count_users_with_two_sided_threshold(_favoriting, min_max)
|
260
|
+
|
261
|
+
scores.keys.map { |uid| _users.find { |u| u.id.to_i == uid.to_i } }.
|
262
|
+
map do |u|
|
263
|
+
u[:score] = scores[u.id]
|
264
|
+
u[:replying_score] = replying_scores[u.id]
|
265
|
+
u[:replied_score] = replied_scores[u.id]
|
266
|
+
u[:favoriting_score] = favoriting_scores[u.id]
|
267
|
+
u
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
180
271
|
def inactive_friends(user = nil)
|
181
272
|
if user.blank?
|
182
273
|
_extract_inactive_users(friends_parallelly, authorized: true)
|