-
Notifications
You must be signed in to change notification settings - Fork 6
/
config.ru
153 lines (129 loc) · 4.95 KB
/
config.ru
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
146
147
148
149
150
151
152
153
#encoding: UTF-8
require "rubygems"
require "tweetstream"
require "em-http-request"
require "httparty"
require "simple_oauth"
require "json"
require "uri"
require "redis"
require "time"
# require the file with the API keys
require "./oauth-keys"
# config oauth
ACCOUNT_ID = OAUTH[:token].split("-").first.to_i
TweetStream.configure do |config|
config.consumer_key = OAUTH[:consumer_key]
config.consumer_secret = OAUTH[:consumer_secret]
config.oauth_token = OAUTH[:token]
config.oauth_token_secret = OAUTH[:token_secret]
config.auth_method = :oauth
end
# redis setup
$redis = Redis.new(REDIS)
$redis.set("count", 0, options = {:nx => true})
#def fetch_cotations
# response = HTTParty.get(BIT_AVERAGE_URL)
# $COTATIONS[:data] = JSON.parse response.body
# $COTATIONS[:timestamp] = Time.now
#end
# constants
BIT_AVERAGE_URL = "https://api.bitcoinaverage.com/ticker/global/all" #bitcoinaverage.com API endpoint
# variables
twurl = URI.parse("https://api.twitter.com/1.1/statuses/update.json")
bit_regex = /\d+(\.|,)?(\d+)?/ # any money amount | accepts both . or , as separator
currency_regex = /#[a-zA-Z]{3}/ # "#" followed by 3 letters
# user stream connection
@client = TweetStream::Client.new
puts "[STARTING] rack..."
run lambda { |env| [200, {'Content-Type'=>'text/plain'}, StringIO.new("#{$redis.get("count")} conversions so far")] }
pid = fork do
puts "[STARTING] bot..."
@client.userstream() do |status|
puts "[NEW TWEET] #{status.text}"
retweet = status.retweet? #checks if it's a convertion retweet
reply_to_me = status.in_reply_to_user_id == ACCOUNT_ID # checks if tweet mentions the bot
contains_currency = status.text =~ currency_regex # checks if tweet has a hashtag with a currency code
contains_amount = status.text =~ bit_regex # checks if tweets contains a number in it
puts retweet
puts reply_to_me
puts contains_currency
puts contains_amount
# check if stream is not a retweet and is valid
if !retweet && reply_to_me && contains_amount && contains_currency
puts "[PROCESSING] #{status.text}"
bit_amount = status.text[bit_regex].gsub(',', '.').to_f # grabs the amount on the tweet
currency = status.text[currency_regex][1..-1] # takes the "#" out
p bit_amount
p currency
# bloquing cotation update
operation = proc {
def cotations_updated?
if $redis.exists("timestamp") == true
(Time.now - Time.parse($redis.get("timestamp"))) < 10
else
return false
end
end
if cotations_updated?
puts "COTATIONS ARE UPDATED. No need no fetch them"
else
puts "Will fetch new cotations"
response = HTTParty.get(BIT_AVERAGE_URL)
$redis.set("data", response.body)
$redis.set("timestamp", Time.now)
# puts "Cotations fetched: #{$redis.get("data")}"
puts "Cotations fetched!"
end
def final_amount(amount, currency)
puts "Will compute final_amount"
cotations = JSON.parse($redis.get("data"))
if cotations[currency]
cotations[currency]["last"] * amount
else
-1
end
end
result = final_amount(bit_amount, currency)
result = result.round(2)
puts "Should return #{result}"
result
}
callback = proc { |this_amount|
this_amount = ("%.2f" % this_amount).gsub(/(\d)(?=\d{3}+\.)/, '\1,') # display right number of decimals for currency
cotations = JSON.parse($redis.get("data"))
if cotations[currency]
reply = "#{bit_amount} bitcoins in #{currency} is #{this_amount}"
else
reply = "Currency #{currency} not found :("
end
#create the reply tweet
puts reply
tweet = {
"status" => "@#{status.user.screen_name} " + reply,
"in_reply_to_status_id" => status.id.to_s
}
puts tweet
authorization = SimpleOAuth::Header.new(:post, twurl.to_s, tweet, OAUTH)
http = EventMachine::HttpRequest.new(twurl.to_s).post({
:head => {"Authorization" => authorization},
:body => tweet
})
http.errback {
puts "[ERROR] errback"
}
http.callback {
$redis.set("count", $redis.get("count").to_i + 1)
puts "[count] = #{$redis.get("count")}"
if http.response_header.status.to_i == 200
puts "[HTTP_OK] #{http.response_header.status}"
else
puts "[HTTP_ERROR] #{http.response_header.status}"
end
}
}
EventMachine.defer(operation, callback)
end
end
end
Process.detach(pid)