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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
module Sampling
module RiotApi
##
# Return whether or not this sampling method works with the specified game.
# Spoiler: It only works with League of Legends (or subclasses of it).
public
def works_with?(game)
if api_key.nil? or region.nil?
return false
end
if game.name == "League of Legends"
return true
end
unless game.parent.nil?
return works_with?(game.parent)
end
end
##
# This sampling method uses remote IDs
public
def uses_remote?
return true
end
##
# When given a summoner name for a user, figure out the summoner ID.
public
def set_remote_name(user, game, summoner_name)
Delayed::Job.enqueue(UsernameJob.new(user, game, summoner_name), :queue => api_name)
end
private
class UsernameJob < Job
def initialize(user, game, summoner_name)
@user_id = user.id
@game_id = game.id
# Escape any funny stuff
summoner_names = [summoner_name].map{|name|Sampling::RiotApi::standardize(name.gsub(',',''))}
# Generate the request
super("v1.3/summoner/by-name/%{summonerNames}", { :summonerNames => summoner_names.join(",") })
end
def handle(data)
user = User.find(@user_id)
game = Game.find(@game_id)
normalized_summoner_name = data.keys.first
remote_data = {
:id => data[normalized_summoner_name]["id"],
:name => data[normalized_summoner_name]["name"],
}
user.set_remote_username(game, remote_data)
end
end
##
# When given data from RemoteUsername#value, give back a readable name to display.
# Here, this is the summoner name.
public
def get_remote_name(data)
data["name"]
end
##
# Fetch all the statistics for a match.
public
def sampling_start(match)
@match.teams.each do |team|
team.users.each do |user|
Delayed::Job.enqueue(MatchJob.new(user, match), :queue => api_name)
end
end
end
private
class FetchStatisticsJob < Job
def initialize(user, match)
@user_id = user.id
@match_id = match.id
# Get the summoner id
summoner = user.get_remote_username(match.tournament_stage.tournament.game)
if summoner.nil?
raise "Someone didn't enter their summoner name"
end
# Generate the request
super("v1.3/game/by-summoner/%{summonerId}/recent", { :summonerId => summoner["id"] })
end
def handle(data)
user = User.find(@user_id)
match = Match.find(@match_id)
Statistic.create(user: user, match: match, value: TODO)
end
end
public
def sampling_done?(match)
# TODO
end
public
def render_user_interaction(match, user)
return ""
end
public
def handle_user_interaction(match, user)
end
########################################################################
private
def api_name
"prod.api.pvp.net/api/lol"
end
private
def api_key
ENV["RIOT_API_KEY"]
end
private
def region
ENV["RIOT_API_REGION"]
end
private
def url(request, args={})
"https://prod.api.pvp.net/api/lol/#{region}/#{request % args.merge(args){|k,v|url_escape(v)}}?#{api_key}"
end
private
def url_escape(string)
URI::escape(string.to_s, /[^a-zA-Z0-9._~!$&'()*+,;=:@-]/)
end
private
def standardize(summoner_name)
summoner_name.to_s.downcase.gsub(' ', '')
end
private
class Job < ThrottledApiRequest.new(api_name, 10.seconds, 10)
def initialize(request, args={})
@url = Sampling::RiotApi::url(request, args)
end
def perform
response = open(@url)
status = response.status
data = JSON::parse(response.read)
# Error codes that RIOT uses:
# "400"=>"Bad request"
# "401"=>"Unauthorized"
# "429"=>"Rate limit exceeded"
# "500"=>"Internal server error"
# "503"=>"Service unavailable"
# "404"=>"Not found"
# Should probably handle these better
if status[0] != "200"
raise "GET #{@url} => #{status.join(" ")}"
end
self.handle(data)
end
def handle(data)
end
end
end
end
|