forked from pingcap/discourse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtwitter_api.rb
145 lines (112 loc) · 3.93 KB
/
twitter_api.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# frozen_string_literal: true
# lightweight Twitter api calls
class TwitterApi
class << self
include ActionView::Helpers::NumberHelper
def prettify_tweet(tweet)
text = tweet["full_text"].dup
if (entities = tweet["entities"]) && (urls = entities["urls"])
urls.each do |url|
text.gsub!(url["url"], "<a target='_blank' href='#{url["expanded_url"]}'>#{url["display_url"]}</a>")
end
end
text = link_hashtags_in link_handles_in text
result = Rinku.auto_link(text, :all, 'target="_blank"').to_s
if tweet['extended_entities'] && media = tweet['extended_entities']['media']
media.each do |m|
if m['type'] == 'photo'
if large = m['sizes']['large']
result << "<div class='tweet-images'><img class='tweet-image' src='#{m['media_url_https']}' width='#{large['w']}' height='#{large['h']}'></div>"
end
elsif m['type'] == 'video'
if large = m['sizes']['large']
result << "<div class='tweet-images'><iframe class='tweet-video' src='https://twitter.com/i/videos/#{tweet['id_str']}' width='#{large['w']}' height='#{large['h']}' frameborder='0' allowfullscreen></iframe></div>"
end
end
end
end
result
end
def prettify_number(count)
number_to_human(count, format: '%n%u', precision: 2, units: { thousand: 'K', million: 'M', billion: 'B' })
end
def user_timeline(screen_name)
JSON.parse(twitter_get(user_timeline_uri_for screen_name))
end
def tweet_for(id)
JSON.parse(twitter_get(tweet_uri_for id))
end
alias_method :status, :tweet_for
def raw_tweet_for(id)
twitter_get(tweet_uri_for id)
end
def twitter_credentials_missing?
consumer_key.blank? || consumer_secret.blank?
end
protected
def link_handles_in(text)
text.scan(/(?:^|\s)@(\w+)/).flatten.uniq.each do |handle|
text.gsub!(/(?:^|\s)@#{handle}/, [
" <a href='https://twitter.com/#{handle}' target='_blank'>",
"@#{handle}",
"</a>"
].join)
end
text.strip
end
def link_hashtags_in(text)
text.scan(/(?:^|\s)#(\w+)/).flatten.uniq.each do |hashtag|
text.gsub!(/(?:^|\s)##{hashtag}/, [
" <a href='https://twitter.com/search?q=%23#{hashtag}' ",
"target='_blank'>",
"##{hashtag}",
"</a>"
].join)
end
text.strip
end
def user_timeline_uri_for(screen_name)
URI.parse "#{BASE_URL}/1.1/statuses/user_timeline.json?screen_name=#{screen_name}&count=50&include_rts=false&exclude_replies=true"
end
def tweet_uri_for(id)
URI.parse "#{BASE_URL}/1.1/statuses/show.json?id=#{id}&tweet_mode=extended"
end
unless defined? BASE_URL
BASE_URL = 'https://api.twitter.com'.freeze
end
def twitter_get(uri)
request = Net::HTTP::Get.new(uri)
request.add_field 'Authorization', "Bearer #{bearer_token}"
http(uri).request(request).body
end
def authorization
request = Net::HTTP::Post.new(auth_uri)
request.add_field 'Authorization',
"Basic #{bearer_token_credentials}"
request.add_field 'Content-Type',
'application/x-www-form-urlencoded;charset=UTF-8'
request.set_form_data 'grant_type' => 'client_credentials'
http(auth_uri).request(request).body
end
def bearer_token
@access_token ||= JSON.parse(authorization).fetch('access_token')
end
def bearer_token_credentials
Base64.strict_encode64(
"#{URI::encode(consumer_key)}:#{URI::encode(consumer_secret)}"
)
end
def auth_uri
URI.parse "#{BASE_URL}/oauth2/token"
end
def http(uri)
Net::HTTP.new(uri.host, uri.port).tap { |http| http.use_ssl = true }
end
def consumer_key
SiteSetting.twitter_consumer_key
end
def consumer_secret
SiteSetting.twitter_consumer_secret
end
end
end