codeforces 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/lib/codeforces/api/user.rb +2 -2
- data/lib/codeforces/client.rb +59 -14
- data/lib/codeforces/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWU0ZDA0N2FlYTY5YmM1ZTViODRlMDdkYzE4YTNkMWQ2ZjdlODE4ZA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTM5MDA4NGIwZDE5ODA3ZjllMDM2MTg4MTY5YTdhYTZkOTUwYTY3Ng==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZGE4M2NlNTlmN2JiMDkzOThkMWVmNGI4OTRkYWU1NzIwZjFlMGI4MjczYWJi
|
10
|
+
NGZhMTE4MmU2ZGJiY2YxODgzODM2NjJiNTk0ZjU0NGJjZWZlNmI2ZWI2NTE5
|
11
|
+
ZTZiNjZhNzA4NTk1NmUwZDU2MWY3OTAzZDM3Y2I2NmVkMmQ5NWM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTY3MTJlZmJkMTM5NjNhYmMwNWFkZjliYjJlNjkyZjhmYWFjOWZiMWY3NzEx
|
14
|
+
YWI4YmYxOTAzZjdjMGQ0MDFkN2JmYWM2ZTViYjMzYzEyNjMwMDEyMWEyN2E1
|
15
|
+
Y2U5MTMyNWQzODNlYmY5OTkzZDg0YmVhMzgzZmVmY2UyMzk4MWE=
|
data/lib/codeforces/api/user.rb
CHANGED
@@ -10,8 +10,8 @@ class Codeforces::Api
|
|
10
10
|
|
11
11
|
def info(handles, options = {})
|
12
12
|
handles = [handles] unless handles.is_a?(Array)
|
13
|
-
options[:
|
14
|
-
options[:
|
13
|
+
options[:data] ||= {}
|
14
|
+
options[:data][:handles] = multi_values(handles)
|
15
15
|
post("user.info", options)
|
16
16
|
end
|
17
17
|
|
data/lib/codeforces/client.rb
CHANGED
@@ -2,6 +2,8 @@ require "sawyer"
|
|
2
2
|
require "logger"
|
3
3
|
require "uri"
|
4
4
|
require "addressable/uri"
|
5
|
+
require "time"
|
6
|
+
require "digest/sha2"
|
5
7
|
require "codeforces/api"
|
6
8
|
require "codeforces/client"
|
7
9
|
require "codeforces/helper"
|
@@ -13,11 +15,17 @@ class Codeforces::Client
|
|
13
15
|
|
14
16
|
DEFAULT_ENDPOINT = "http://codeforces.com/api/"
|
15
17
|
DEFAULT_PAGE_COUNT = 50
|
18
|
+
DEFAULT_API_KEY = ENV["CODEFORCES_API_KEY"]
|
19
|
+
DEFAULT_API_SECRET = ENV["CODEFORCES_API_SECRET"]
|
16
20
|
|
17
21
|
attr_reader :endpoint
|
22
|
+
attr_reader :api_key
|
23
|
+
attr_reader :api_secret
|
18
24
|
|
19
|
-
def initialize(
|
20
|
-
@endpoint = endpoint
|
25
|
+
def initialize(options = {})
|
26
|
+
@endpoint = options.fetch(:endpoint, DEFAULT_ENDPOINT)
|
27
|
+
@api_key = options.fetch(:api_key, DEFAULT_API_KEY)
|
28
|
+
@api_secret = options.fetch(:api_secret, DEFAULT_API_SECRET)
|
21
29
|
end
|
22
30
|
|
23
31
|
def logger
|
@@ -33,25 +41,30 @@ class Codeforces::Client
|
|
33
41
|
end
|
34
42
|
|
35
43
|
def get(path, options = {})
|
36
|
-
|
37
|
-
options[:query] ||= {}
|
38
|
-
request_uri.query_values = options[:query]
|
39
|
-
request(:get, "#{path}#{request_uri.query.empty? ? "" : "?#{request_uri.query}"}", options[:data], options).result
|
44
|
+
request(:get, path, options).result
|
40
45
|
end
|
41
46
|
|
42
47
|
def post(path, options = {})
|
43
|
-
|
44
|
-
options[:query] ||= {}
|
45
|
-
request_uri.query_values = options[:query]
|
46
|
-
request(:post, path, request_uri.query).result
|
48
|
+
request(:post, path, options).result
|
47
49
|
end
|
48
50
|
|
49
|
-
def request(method, path,
|
50
|
-
|
51
|
-
|
51
|
+
def request(method, path, options = {})
|
52
|
+
request_uri = ::Addressable::URI.new
|
53
|
+
query = {}
|
54
|
+
query.merge!(options[:query]) unless options[:query].nil?
|
55
|
+
request_uri.query_values = query
|
56
|
+
|
57
|
+
enable_auth!(path, request_uri, query) unless api_key.nil?
|
58
|
+
|
59
|
+
path += "?#{request_uri.query}" unless request_uri.query.empty?
|
60
|
+
|
61
|
+
@last_response = agent.call(method, path, options[:data])
|
62
|
+
|
63
|
+
logger.debug "#{method.upcase} #{::URI.join endpoint, path}"
|
64
|
+
logger.debug "Status: #{last_response.data.status}"
|
52
65
|
|
53
66
|
unless last_response.data.status === "OK"
|
54
|
-
raise "Error: #{last_response.data.status}"
|
67
|
+
raise "Error: #{last_response.data.status} #{last_response.data.comment}"
|
55
68
|
end
|
56
69
|
|
57
70
|
last_response.data
|
@@ -109,5 +122,37 @@ class Codeforces::Client
|
|
109
122
|
logger
|
110
123
|
end
|
111
124
|
|
125
|
+
def enable_auth!(path, request_uri, query)
|
126
|
+
query.merge!({:time => server_time})
|
127
|
+
query.merge!({:apiKey => api_key})
|
128
|
+
request_uri.query_values = query
|
129
|
+
|
130
|
+
# calc signature
|
131
|
+
seed = api_sig_seed(654321, path, request_uri)
|
132
|
+
hash = ::Digest::SHA512.hexdigest(seed)
|
133
|
+
query.merge!({:apiSig => "654321#{hash}"})
|
134
|
+
request_uri.query_values = query
|
135
|
+
|
136
|
+
logger.debug "Enable Auth"
|
137
|
+
logger.debug "API signature seed: #{seed}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def is_old_time?(t)
|
141
|
+
t.nil? || ::Time.now.to_i - t > 30
|
142
|
+
end
|
143
|
+
|
144
|
+
def server_time
|
145
|
+
return @server_time unless is_old_time?(@server_time)
|
146
|
+
|
147
|
+
logger.debug "Resolve Server Time"
|
148
|
+
@server_time = ::Net::HTTP.start("codeforces.com", 80) do |http|
|
149
|
+
::Time.parse(http.head("/")["date"]).to_i
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def api_sig_seed(rand, path, uri)
|
154
|
+
"#{rand}/#{path}?#{uri.query}##{api_secret}"
|
155
|
+
end
|
156
|
+
|
112
157
|
end
|
113
158
|
|
data/lib/codeforces/version.rb
CHANGED