comparison app/models/tweet.rb @ 145:c791b6bfeeda

More refactors
author nanaya <me@nanaya.pro>
date Wed, 13 Dec 2017 06:31:07 +0900
parents 1925b08153dc
children 7ca8aeba1a63
comparison
equal deleted inserted replaced
144:1925b08153dc 145:c791b6bfeeda
14 def cache_expires_time 14 def cache_expires_time
15 (15 + rand(15)).minutes 15 (15 + rand(15)).minutes
16 end 16 end
17 17
18 def timeline 18 def timeline
19 initial_config_id = client_config_id 19 if @timeline.nil?
20 raw = Rails.cache.fetch("timeline:v2:#{@twitter_id}", :expires_in => cache_expires_time) do
21 client_try(:user_timeline, @twitter_id, TIMELINE_OPTIONS).tap do |data|
22 if data[:result] == :ok
23 data[:data] = data[:data].select do |tweet|
24 tweet.retweeted_status.nil? || tweet.user.id != tweet.retweeted_status.user.id
25 end.map { |tweet| tweet.to_h }
26 end
27 end
28 end
20 29
21 @timeline ||= 30 raise Twitter::Error::NotFound if raw[:result] == :not_found
22 Rails.cache.fetch("timeline:v1:#{@twitter_id}", :expires_in => cache_expires_time) do
23 begin
24 timeline = client.user_timeline(@twitter_id, TIMELINE_OPTIONS)
25 rescue Twitter::Error::TooManyRequests
26 @client_config_id += 1
27 31
28 if initial_config_id == client_config_id 32 @timeline = raw[:data].map { |tweet_hash| Twitter::Tweet.new(tweet_hash) }
29 raise 33 end
30 else
31 retry
32 end
33 rescue Twitter::Error::NotFound
34 data = { :result => :not_found }
35 end
36 34
37 data || { 35 @timeline
38 :result => :ok,
39 :timeline => timeline.select do |tweet|
40 tweet.retweeted_status.nil? || tweet.user.id != tweet.retweeted_status.user.id
41 end.map do |tweet|
42 # Fails when there's Twitter::NullObject initiated somewhere in previous select
43 # Reference: https://github.com/sferik/twitter/issues/892
44 tweet.to_h
45 end,
46 }
47 end.tap do |data|
48 raise Twitter::Error::NotFound if data[:result] == :not_found
49
50 data[:timeline_parsed] = data[:timeline].map do |tweet_hash|
51 Twitter::Tweet.new(tweet_hash)
52 end
53 end[:timeline_parsed]
54 end 36 end
55 37
56 def user 38 def user
57 @user ||= 39 if @user.nil?
58 if timeline.any? 40 return timeline.first.user if timeline.any?
59 timeline.first.user 41
60 else 42 raw = Rails.cache.fetch("user:v1:#{@twitter_id}", :expires_in => cache_expires_time) do
61 Rails.cache.fetch("user:v1:#{@twitter_id}", :expires_in => cache_expires_time) do 43 client_try :user, @twitter_id
62 client.user(@twitter_id)
63 end
64 end 44 end
45
46 raise Twitter::Error::NotFound if raw[:result] == :not_found
47
48 @user = raw[:data]
49 end
50
51 @user
65 end 52 end
66 53
67 def client 54 def client
68 @clients[client_config_id] ||= 55 @clients[client_config_id] ||=
69 Twitter::REST::Client.new do |config| 56 Twitter::REST::Client.new do |config|
71 config.public_send(:"#{cfg_key}=", cfg_value) 58 config.public_send(:"#{cfg_key}=", cfg_value)
72 end 59 end
73 end 60 end
74 end 61 end
75 62
63 def client_try(method, *args)
64 initial_config_id = client_config_id
65
66 begin
67 data = client.public_send method, *args
68 rescue Twitter::Error::TooManyRequests
69 @client_config_id += 1
70
71 if initial_config_id == client_config_id
72 raise
73 else
74 retry
75 end
76 rescue Twitter::Error::NotFound
77 return { :result => :not_found }
78 end
79
80 { :result => :ok, :data => data }
81 end
82
76 def client_config_id 83 def client_config_id
77 @client_config_id ||= 0 84 @client_config_id ||= 0
78 85
79 @client_config_id %= $cfg[:twitter].size 86 @client_config_id %= $cfg[:twitter].size
80 end 87 end