twitter_friendly 1.2.0 → 1.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 687792a2d0065ebefe3b95ad38f1df4558a644f0c07819619961dd85f4b7fa7c
4
- data.tar.gz: ec86328550855e0f864daea0f3ab8bbfadf25cc71e217cda7d794c1d3eb52a2b
3
+ metadata.gz: 810019b532f5f365b544ca6e0a0066717794b8975b59ae0a840b74f44377bff6
4
+ data.tar.gz: 75f3b7052fa926da7457b53f71d0f2f6e08496efd02042750681678b53d351dd
5
5
  SHA512:
6
- metadata.gz: b3029c832c6da171bedcd7a9a82e2c211e2be912913deed15d6a32ff4d2884f18d4b990ec8f902f4e97dcd684815a59c13a7f0f5e95e6134dc2043e343d43430
7
- data.tar.gz: 36365cf299fab85c22859303652963185700c967023a558b7f16f1b289b6b563ccc32ed6f014d48d8383bf0beb3438c102fe9d43e0b34e42c964cec57f650db5
6
+ metadata.gz: '08a9a4ef337d993f1cb3bb6689df73d67b5adc74576214206774c5dc2b720e0ef66c30a376c2d122c4a70d7dc85661f6114508ad0e030819f52a0c65370a3033'
7
+ data.tar.gz: f26d6b48033db9dc96752a55c12a5e7ffe1c3610773f0014af8d1a69b4c84384de5eec858c204634212c1e205b2579ec6cf689a8dd0cdf634031a65510520ca4
data/.gitignore CHANGED
@@ -7,8 +7,8 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
- *.log
11
10
  /.pryrc
12
11
  /.env
13
- /.twitter_friendly
12
+ /log/
13
+ /cache/
14
14
  /.idea
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- twitter_friendly (1.2.0)
4
+ twitter_friendly (1.2.1)
5
5
  activesupport (>= 4.2, < 6.0)
6
6
  oj (~> 3.7.6)
7
7
  parallel (~> 1.12.1)
data/README.md CHANGED
@@ -5,16 +5,16 @@
5
5
 
6
6
  The twitter_friendly is a gem to crawl many friends/followers with minimal code. When you want to get a list of friends/followers for a user, all you need to write is the below.
7
7
 
8
- ```
8
+ ```ruby
9
9
  require 'twitter_friendly'
10
10
 
11
11
  client =
12
12
  TwitterFriendly::Client.new(
13
- consumer_key: 'CONSUMER_KEY',
14
- consumer_secret: 'CONSUMER_SECRET',
15
- access_token: 'ACCESS_TOKEN',
13
+ consumer_key: 'CONSUMER_KEY',
14
+ consumer_secret: 'CONSUMER_SECRET',
15
+ access_token: 'ACCESS_TOKEN',
16
16
  access_token_secret: 'ACCESS_TOKEN_SECRET',
17
- expires_in: 86400 # 1day
17
+ expires_in: 86400 # 1day
18
18
  )
19
19
 
20
20
  ids = []
@@ -22,7 +22,8 @@ ids = []
22
22
  begin
23
23
  ids = client.follower_ids('yousuck2020')
24
24
  rescue Twitter::Error::TooManyRequests => e
25
- sleep client.rate_limit.follower_ids[:reset_in]
25
+ seconds = e.rate_limit.reset_in.to_i # or client.rate_limit.follower_ids[:reset_in]
26
+ sleep seconds
26
27
  retry
27
28
  end
28
29
 
@@ -44,13 +45,13 @@ gem 'twitter_friendly'
44
45
 
45
46
  And then execute:
46
47
 
47
- ```sh
48
+ ```bash
48
49
  $ bundle
49
50
  ```
50
51
 
51
52
  Or install it yourself as:
52
53
 
53
- ```sh
54
+ ```bash
54
55
  $ gem install twitter_friendly
55
56
  ```
56
57
 
@@ -58,7 +59,7 @@ $ gem install twitter_friendly
58
59
 
59
60
  You can pass configuration options as a block to `TwitterFriendly::Client.new` just like the below.
60
61
 
61
- ```
62
+ ```ruby
62
63
  client = TwitterFriendly::Client.new do |config|
63
64
  config.consumer_key = "YOUR_CONSUMER_KEY"
64
65
  config.consumer_secret = "YOUR_CONSUMER_SECRET"
@@ -9,37 +9,35 @@ module TwitterFriendly
9
9
  def initialize(*args)
10
10
  options = {expires_in: 1.hour, race_condition_ttl: 5.minutes}.merge(args.extract_options!)
11
11
 
12
- path = options[:cache_dir] || File.join('.twitter_friendly', 'cache')
12
+ path = options[:cache_dir] || File.join('cache')
13
13
  FileUtils.mkdir_p(path) unless File.exists?(path)
14
14
  @client = ::ActiveSupport::Cache::FileStore.new(path, options)
15
15
  end
16
16
 
17
- # @param key [String]
18
- #
19
- # @option serialize_options [Array] :args
20
- def fetch(key, serialize_options, &block)
17
+ def fetch(key, args:, &block)
21
18
  block_result = nil
22
- yield_and_encode =
23
- Proc.new do
24
- block_result = yield
25
- encode(block_result, serialize_options)
26
- end
19
+ yield_and_encode = Proc.new do
20
+ block_result = yield
21
+ encode(block_result, args: args)
22
+ end
23
+
24
+ # 目的のデータがキャッシュになかった場合、キャッシュにはシリアライズしたJSONを保存しつつ、
25
+ # このメソッドの呼び出し元にはJSONにシリアライズする前の結果を返している。
26
+ # こうしないと、不要なデコードをすることになってしまう。
27
27
 
28
28
  fetch_result = @client.fetch(key, &yield_and_encode)
29
29
 
30
- block_result || decode(fetch_result, serialize_options)
30
+ block_result || decode(fetch_result, args: args)
31
31
  end
32
32
 
33
33
  private
34
34
 
35
- # @option options [Array] :args
36
- def encode(obj, options)
37
- Serializer.encode(obj, options)
35
+ def encode(obj, args:)
36
+ Serializer.encode(obj, args: args)
38
37
  end
39
38
 
40
- # @option options [Array] :args
41
- def decode(str, options)
42
- Serializer.decode(str, options)
39
+ def decode(str, args:)
40
+ Serializer.decode(str, args: args)
43
41
  end
44
42
  end
45
43
  end
@@ -39,18 +39,18 @@ module TwitterFriendly
39
39
 
40
40
  module_function
41
41
 
42
- def start_processing(operation, options)
43
- payload = {operation: operation}.merge(options)
42
+ def start_processing(method_name, options)
43
+ payload = {operation: method_name}.merge(options)
44
44
  ::ActiveSupport::Notifications.instrument('start_processing.twitter_friendly', payload) {}
45
45
  end
46
46
 
47
- def complete_processing(operation, options)
48
- payload = {operation: operation}.merge(options)
47
+ def complete_processing(method_name, options)
48
+ payload = {operation: method_name}.merge(options)
49
49
  ::ActiveSupport::Notifications.instrument('complete_processing.twitter_friendly', payload) { yield(payload) }
50
50
  end
51
51
 
52
- def perform_request(caller, options, &block)
53
- payload = {operation: 'request', args: [caller, options]}
52
+ def perform_request(method_name, options, &block)
53
+ payload = {operation: 'request', args: [method_name, options]}
54
54
  ::ActiveSupport::Notifications.instrument('request.twitter_friendly', payload) { yield(payload) }
55
55
  end
56
56
  end
@@ -26,12 +26,14 @@ module TwitterFriendly
26
26
 
27
27
  def initialize(*args)
28
28
  options = args.extract_options!
29
- @twitter = Twitter::REST::Client.new(options.slice(:access_token, :access_token_secret, :consumer_key, :consumer_secret))
30
29
 
30
+ @twitter = Twitter::REST::Client.new(options.slice(:access_token, :access_token_secret, :consumer_key, :consumer_secret))
31
31
  options.except!(:access_token, :access_token_secret, :consumer_key, :consumer_secret)
32
- @cache = TwitterFriendly::Cache.new(options)
33
32
 
34
- @logger = TwitterFriendly::Logger.new(options)
33
+ @cache = TwitterFriendly::Cache.new(options.slice(:cache_dir, :expires_in, :race_condition_ttl))
34
+ options.except!(:cache_dir, :expires_in, :race_condition_ttl)
35
+
36
+ @logger = TwitterFriendly::Logger.new(options.slice(:log_dir, :log_level))
35
37
 
36
38
  unless subscriber_attached?
37
39
  if @logger.level == ::Logger::DEBUG
@@ -1,6 +1,7 @@
1
1
  module TwitterFriendly
2
2
  module Logging
3
3
  def truncated_payload(payload)
4
+ return '' if payload.empty?
4
5
  return payload.inspect if !payload.has_key?(:args) || !payload[:args].is_a?(Array) || payload[:args].empty? || !payload[:args][0].is_a?(Array)
5
6
 
6
7
  args = payload[:args].dup
@@ -30,24 +31,28 @@ module TwitterFriendly
30
31
  include Logging
31
32
 
32
33
  def start_processing(event)
33
- debug do
34
+ info do
34
35
  payload = event.payload
35
- name = "TF::Started #{payload[:operation]}"
36
+ operation = payload.delete(:operation)
36
37
 
37
38
  if payload[:super_operation]
38
- "#{name} in #{payload[:super_operation][0]} at #{Time.now}"
39
+ "TF::Started #{operation} in #{payload[:super_operation][0]} at #{Time.now}"
39
40
  else
40
- "#{name} at #{Time.now}"
41
+ "TF::Started #{operation} at #{Time.now}"
41
42
  end
42
43
  end
43
44
  end
44
45
 
45
46
  def complete_processing(event)
46
- debug do
47
+ info do
47
48
  payload = event.payload
48
- name = "TF::Completed #{payload[:operation]} in #{event.duration.round(1)}ms"
49
+ operation = payload.delete(:operation)
49
50
 
50
- "#{name}#{" #{truncated_payload(payload)}" unless payload.empty?}"
51
+ if payload.empty?
52
+ "TF::Completed #{operation} in #{event.duration.round(1)}ms"
53
+ else
54
+ "TF::Completed #{operation} in #{event.duration.round(1)}ms #{truncated_payload(payload)}"
55
+ end
51
56
  end
52
57
  end
53
58
 
@@ -66,11 +71,19 @@ module TwitterFriendly
66
71
  debug do
67
72
  payload = event.payload
68
73
  payload.delete(:name)
69
- operation = payload.delete(:operation)
70
- name = " TW::#{operation.capitalize} #{payload[:args][0] if payload[:args]&.is_a?(Array)} (#{event.duration.round(1)}ms)"
71
- c = (%i(encode decode).include?(operation.to_sym)) ? YELLOW : CYAN
74
+ operation = payload.delete(:operation).capitalize
75
+ args = payload[:args]
76
+ method_name = args.shift
77
+
78
+ name = " TW::#{operation} #{method_name} (#{event.duration.round(1)}ms)"
79
+ c = (%i(Encode Decode).include?(operation.to_sym)) ? YELLOW : CYAN
72
80
  name = color(name, c, true)
73
- " #{name}#{" #{payload[:args][1] if payload[:args]&.is_a?(Array)}" unless payload.empty?}"
81
+
82
+ if args.size == 1 && args[0].is_a?(Hash) && args[0].empty?
83
+ " #{name}"
84
+ else
85
+ " #{name} #{args[1]}"
86
+ end
74
87
  end
75
88
  end
76
89
 
@@ -8,7 +8,7 @@ module TwitterFriendly
8
8
  def_delegators :@logger, :debug, :info, :warn, :error, :fatal, :level
9
9
 
10
10
  def initialize(options = {})
11
- path = options[:log_dir] || File.join('.twitter_friendly')
11
+ path = options[:log_dir] || File.join('log')
12
12
  FileUtils.mkdir_p(path) unless File.exists?(path)
13
13
 
14
14
  @logger = ::Logger.new(File.join(path, 'twitter_friendly.log'))
@@ -3,8 +3,8 @@ require 'parallel'
3
3
  module TwitterFriendly
4
4
  module REST
5
5
  module Users
6
- def verify_credentials(options = {})
7
- @twitter.verify_credentials({skip_status: true}.merge(options))&.to_hash
6
+ def verify_credentials(include_entities: false, skip_status: true, include_email: true)
7
+ @twitter.verify_credentials(include_entities: include_entities, skip_status: skip_status, include_email: include_email)&.to_hash
8
8
  end
9
9
 
10
10
  def user?(*args)
@@ -19,9 +19,9 @@ module TwitterFriendly
19
19
 
20
20
  def users(values, options = {})
21
21
  if values.size <= MAX_USERS_PER_REQUEST
22
- @twitter.users(values, options)
22
+ @twitter.users(values, options).map(&:to_h)
23
23
  else
24
- parallel(in_threads: 10) do |batch|
24
+ parallel(in_threads: 6) do |batch|
25
25
  values.each_slice(MAX_USERS_PER_REQUEST) { |targets| batch.users(targets, options) }
26
26
  end.flatten
27
27
  end
@@ -4,14 +4,14 @@ require 'oj'
4
4
  module TwitterFriendly
5
5
  class Serializer
6
6
  class << self
7
- def encode(obj, options = {})
8
- Instrumenter.perform_encode(options) do
7
+ def encode(obj, args:)
8
+ Instrumenter.perform_encode(args: args) do
9
9
  (!!obj == obj) ? obj : coder.encode(obj)
10
10
  end
11
11
  end
12
12
 
13
- def decode(str, options = {})
14
- Instrumenter.perform_decode(options) do
13
+ def decode(str, args:)
14
+ Instrumenter.perform_decode(args: args) do
15
15
  str.kind_of?(String) ? coder.decode(str) : str
16
16
  end
17
17
  end
@@ -31,13 +31,13 @@ module TwitterFriendly
31
31
 
32
32
  module_function
33
33
 
34
- def perform_encode(options, &block)
35
- payload = {operation: 'encode', args: options[:args]}
34
+ def perform_encode(args:, &block)
35
+ payload = {operation: 'encode', args: args}
36
36
  ::ActiveSupport::Notifications.instrument('encode.twitter_friendly', payload) { yield(payload) }
37
37
  end
38
38
 
39
- def perform_decode(options, &block)
40
- payload = {operation: 'decode', args: options[:args]}
39
+ def perform_decode(args:, &block)
40
+ payload = {operation: 'decode', args: args}
41
41
  ::ActiveSupport::Notifications.instrument('decode.twitter_friendly', payload) { yield(payload) }
42
42
  end
43
43
  end
@@ -1,3 +1,3 @@
1
1
  module TwitterFriendly
2
- VERSION = "1.2.0"
2
+ VERSION = "1.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter_friendly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ts-3156
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-14 00:00:00.000000000 Z
11
+ date: 2019-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport