annotate app/models/tweet.rb @ 197:ac1fe544a203

Update gems
author nanaya <me@nanaya.pro>
date Wed, 01 Apr 2020 20:49:14 +0900
parents 3176bd0d3c2c
children 17461f7682a2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
15
207917e41964 Add tweets~
edogawaconan <me@myconan.net>
parents:
diff changeset
1 class Tweet
137
00dc9346dfaa Skip self retweets
nanaya <me@nanaya.pro>
parents: 136
diff changeset
2 TIMELINE_OPTIONS = {
00dc9346dfaa Skip self retweets
nanaya <me@nanaya.pro>
parents: 136
diff changeset
3 :count => 100,
00dc9346dfaa Skip self retweets
nanaya <me@nanaya.pro>
parents: 136
diff changeset
4 :exclude_replies => false,
00dc9346dfaa Skip self retweets
nanaya <me@nanaya.pro>
parents: 136
diff changeset
5 :include_rts => true,
00dc9346dfaa Skip self retweets
nanaya <me@nanaya.pro>
parents: 136
diff changeset
6 :tweet_mode => :extended,
00dc9346dfaa Skip self retweets
nanaya <me@nanaya.pro>
parents: 136
diff changeset
7 }
00dc9346dfaa Skip self retweets
nanaya <me@nanaya.pro>
parents: 136
diff changeset
8
158
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
9 def self.cache_expires_time
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
10 (15 + rand(15)).minutes
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
11 end
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
12
176
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
13 def self.client_options(id)
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
14 {
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
15 :timeouts => {
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
16 :connect => 5,
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
17 :read => 5,
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
18 :write => 5,
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
19 },
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
20 }.merge $cfg[:twitter][id]
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
21 end
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
22
135
3fc882b0884d Refactored client initialization
nanaya <me@nanaya.pro>
parents: 134
diff changeset
23 def initialize(twitter_id)
3fc882b0884d Refactored client initialization
nanaya <me@nanaya.pro>
parents: 134
diff changeset
24 @clients = {}
165
5af9b537db86 Unbreak \everything/
nanaya <me@nanaya.pro>
parents: 163
diff changeset
25 @twitter_id = twitter_id
135
3fc882b0884d Refactored client initialization
nanaya <me@nanaya.pro>
parents: 134
diff changeset
26 end
3fc882b0884d Refactored client initialization
nanaya <me@nanaya.pro>
parents: 134
diff changeset
27
158
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
28 def id
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
29 user.id
152
fd7344643903 Better? cache key
nanaya <me@nanaya.pro>
parents: 146
diff changeset
30 end
fd7344643903 Better? cache key
nanaya <me@nanaya.pro>
parents: 146
diff changeset
31
86
5bfc986200db The caching becomes a bit confusing because of parameters
nanaya <me@myconan.net>
parents: 78
diff changeset
32 def timeline
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
33 if @timeline.nil?
158
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
34 cache_key = "timeline:v2:#{id}/#{Base64.urlsafe_encode64 id.to_s}"
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
35 raw = Rails.cache.fetch(cache_key, :expires_in => self.class.cache_expires_time) do
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
36 client_try(:user_timeline, id, TIMELINE_OPTIONS).tap do |data|
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
37 if data[:result] == :ok
158
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
38 if data[:data].any? && data[:data].first.user.id != id
146
7ca8aeba1a63 Try tracing where the failures happen
nanaya <me@nanaya.pro>
parents: 145
diff changeset
39 wrong_user = data[:data].first.user
160
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
40 throw "Wrong timeline data. Requested: #{id}, got: #{wrong_user.id} (#{wrong_user.screen_name.printable})"
146
7ca8aeba1a63 Try tracing where the failures happen
nanaya <me@nanaya.pro>
parents: 145
diff changeset
41 end
7ca8aeba1a63 Try tracing where the failures happen
nanaya <me@nanaya.pro>
parents: 145
diff changeset
42
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
43 data[:data] = data[:data].select do |tweet|
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
44 tweet.retweeted_status.nil? || tweet.user.id != tweet.retweeted_status.user.id
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
45 end.map { |tweet| tweet.to_h }
134
3646b3e319c7 Only try/catch the tweet downloading part
nanaya <me@nanaya.pro>
parents: 108
diff changeset
46 end
76
0c023d35cd80 Allows usage of multiple twitter keys
nanaya <me@myconan.net>
parents: 73
diff changeset
47 end
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
48 end
141
88d7a7714d4e Restrict to just the fetch process
nanaya <me@nanaya.pro>
parents: 138
diff changeset
49
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
50 raise Twitter::Error::NotFound if raw[:result] == :not_found
144
1925b08153dc Record 404s
nanaya <me@nanaya.pro>
parents: 143
diff changeset
51
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
52 @timeline = raw[:data].map { |tweet_hash| Twitter::Tweet.new(tweet_hash) }
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
53 end
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
54
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
55 @timeline
15
207917e41964 Add tweets~
edogawaconan <me@myconan.net>
parents:
diff changeset
56 end
207917e41964 Add tweets~
edogawaconan <me@myconan.net>
parents:
diff changeset
57
48
8983c426e256 Prevent exploding on empty timeline.
nanaya <me@myconan.net>
parents: 47
diff changeset
58 def user
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
59 if @user.nil?
165
5af9b537db86 Unbreak \everything/
nanaya <me@nanaya.pro>
parents: 163
diff changeset
60 cache_key = "user:v1:#{@twitter_id.is_a?(Integer) ? 'id' : 'lookup'}:#{@twitter_id}"
5af9b537db86 Unbreak \everything/
nanaya <me@nanaya.pro>
parents: 163
diff changeset
61 raw = Rails.cache.fetch(cache_key, :expires_in => self.class.cache_expires_time) do
160
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
62 client_try(:user, @twitter_id).tap do |data|
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
63 if data[:result] == :ok
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
64 user = data[:data]
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
65
177
3176bd0d3c2c Correct casing check
nanaya <me@nanaya.pro>
parents: 176
diff changeset
66 if user.id != @twitter_id && user.screen_name.downcase != @twitter_id.try(:downcase)
160
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
67 throw "Wrong user data. Requested: #{@twitter_id}, got: #{user.id} (#{user.screen_name.printable})"
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
68 end
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
69 end
4e4195e60c2b Add check at user level as well
nanaya <me@nanaya.pro>
parents: 158
diff changeset
70 end
48
8983c426e256 Prevent exploding on empty timeline.
nanaya <me@myconan.net>
parents: 47
diff changeset
71 end
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
72
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
73 raise Twitter::Error::NotFound if raw[:result] == :not_found
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
74
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
75 @user = raw[:data]
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
76 end
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
77
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
78 @user
48
8983c426e256 Prevent exploding on empty timeline.
nanaya <me@myconan.net>
parents: 47
diff changeset
79 end
8983c426e256 Prevent exploding on empty timeline.
nanaya <me@myconan.net>
parents: 47
diff changeset
80
135
3fc882b0884d Refactored client initialization
nanaya <me@nanaya.pro>
parents: 134
diff changeset
81 def client
176
08cc4a4d8a5f Timeout and simpler client config
nanaya <me@nanaya.pro>
parents: 165
diff changeset
82 @clients[client_config_id] ||= Twitter::REST::Client.new(self.class.client_options client_config_id)
76
0c023d35cd80 Allows usage of multiple twitter keys
nanaya <me@myconan.net>
parents: 73
diff changeset
83 end
0c023d35cd80 Allows usage of multiple twitter keys
nanaya <me@myconan.net>
parents: 73
diff changeset
84
145
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
85 def client_try(method, *args)
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
86 initial_config_id = client_config_id
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
87
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
88 begin
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
89 data = client.public_send method, *args
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
90 rescue Twitter::Error::TooManyRequests
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
91 @client_config_id += 1
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
92
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
93 if initial_config_id == client_config_id
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
94 raise
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
95 else
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
96 retry
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
97 end
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
98 rescue Twitter::Error::NotFound
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
99 return { :result => :not_found }
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
100 end
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
101
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
102 { :result => :ok, :data => data }
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
103 end
c791b6bfeeda More refactors
nanaya <me@nanaya.pro>
parents: 144
diff changeset
104
135
3fc882b0884d Refactored client initialization
nanaya <me@nanaya.pro>
parents: 134
diff changeset
105 def client_config_id
158
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
106 @client_config_count ||= $cfg[:twitter].size
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
107 @client_config_id ||= rand(@client_config_count)
76
0c023d35cd80 Allows usage of multiple twitter keys
nanaya <me@myconan.net>
parents: 73
diff changeset
108
158
74422bae017d Always use canonical id and turn cache time generator a class method
nanaya <me@nanaya.pro>
parents: 157
diff changeset
109 @client_config_id %= @client_config_count
15
207917e41964 Add tweets~
edogawaconan <me@myconan.net>
parents:
diff changeset
110 end
207917e41964 Add tweets~
edogawaconan <me@myconan.net>
parents:
diff changeset
111 end