gettc 1.10 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/gettc +60 -69
- data/dist/config.yml +1 -1
- data/dist/include/cpp/engine.rb +78 -86
- data/dist/include/cpp/topcoder +236 -236
- data/dist/include/go/engine.rb +53 -61
- data/dist/include/haskell/engine.rb +112 -122
- data/dist/include/java/engine.rb +187 -184
- data/dist/include/javascript/engine.rb +26 -30
- data/dist/include/javascript/topcoder.js +3 -3
- data/dist/include/javascript/topcoder/errors.js +5 -5
- data/dist/include/javascript/topcoder/reader.js +188 -165
- data/dist/include/javascript/topcoder/writer.js +37 -33
- data/dist/include/python/engine.rb +43 -52
- data/dist/include/python/topcoder/__init__.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/__init__.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/errors.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/reader.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/writer.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/errors.pyc +0 -0
- data/dist/include/python/topcoder/reader.pyc +0 -0
- data/dist/include/python/topcoder/writer.pyc +0 -0
- data/dist/include/ruby/engine.rb +47 -52
- data/dist/include/ruby/topcoder/reader.rb +205 -193
- data/dist/include/ruby/topcoder/writer.rb +39 -37
- data/dist/template/bin/runner.rb +146 -151
- data/dist/template/bin/runner.sh +96 -96
- data/dist/template/prob/{name}.html +1 -1
- data/dist/template/solve/cpp/{name}.cpp +3 -4
- data/dist/template/solve/cpp/{name}Solver.cpp +14 -14
- data/dist/template/solve/go/{name}/{name}.go +3 -3
- data/dist/template/solve/go/{name}Solver.go +2 -2
- data/dist/template/solve/haskell/{name}.hs +6 -6
- data/dist/template/solve/haskell/{name}Solver.hs +10 -10
- data/dist/template/solve/java/{name}.java +4 -4
- data/dist/template/solve/java/{name}Solver.java +4 -4
- data/dist/template/solve/javascript/{name}.js +4 -6
- data/dist/template/solve/javascript/{name}Solver.js +11 -9
- data/dist/template/solve/python/{name}.py +1 -1
- data/dist/template/solve/python/{name}Solver.py +2 -2
- data/dist/template/solve/ruby/{name}.rb +4 -4
- data/dist/template/solve/ruby/{name}Solver.rb +14 -17
- data/dist/template/util/check/check.cpp +19 -19
- data/{core/lib → lib}/gettc.rb +0 -0
- data/lib/gettc/account.rb +14 -0
- data/lib/gettc/download.rb +211 -0
- data/lib/gettc/generate.rb +156 -0
- data/lib/gettc/parse.rb +237 -0
- data/lib/gettc/print.rb +54 -0
- data/lib/gettc/problem.rb +39 -0
- data/lib/gettc/signature.rb +63 -0
- data/lib/gettc/types.rb +93 -0
- data/lib/version.rb +3 -0
- data/test/gettc/download_test.rb +61 -0
- data/test/gettc/generate_test.rb +70 -0
- data/test/gettc/parse_test.rb +78 -0
- data/test/gettc/signature_test.rb +71 -0
- data/test/gettc/types_test.rb +31 -0
- metadata +28 -23
- data/core/lib/gettc/download.rb +0 -130
- data/core/lib/gettc/generate.rb +0 -145
- data/core/lib/gettc/parse.rb +0 -233
- data/core/lib/gettc/print.rb +0 -56
- data/core/lib/gettc/problem.rb +0 -33
- data/core/lib/gettc/signature.rb +0 -55
- data/core/lib/gettc/types.rb +0 -83
- data/core/lib/version.rb +0 -3
- data/core/test/gettc/download_test.rb +0 -29
- data/core/test/gettc/generate_test.rb +0 -31
- data/core/test/gettc/parse_test.rb +0 -104
- data/core/test/gettc/signature_test.rb +0 -54
- data/core/test/gettc/types_test.rb +0 -28
@@ -4,8 +4,7 @@ using namespace std;
|
|
4
4
|
|
5
5
|
class <%= prob.name %> {
|
6
6
|
public:
|
7
|
-
<%=
|
8
|
-
|
9
|
-
|
10
|
-
}
|
7
|
+
<%= CppEngine.new(func, vars).declare.gsub(/^/, ' ') %> {
|
8
|
+
return <%= func.type.dumb_cpp %>;
|
9
|
+
}
|
11
10
|
};
|
@@ -3,24 +3,24 @@
|
|
3
3
|
#include "<%= prob.name %>.cpp"
|
4
4
|
namespace tc = TopCoder;
|
5
5
|
<%
|
6
|
-
|
6
|
+
engine = CppEngine.new(func, vars)
|
7
7
|
%>
|
8
8
|
int main(int argc, char const *argv[]) {
|
9
|
-
|
10
|
-
|
9
|
+
try {
|
10
|
+
std::ifstream ifs(argv[1]);
|
11
11
|
<%=
|
12
|
-
|
12
|
+
engine.input.gsub(/^/, ' ' * 4)
|
13
13
|
%>
|
14
|
-
|
14
|
+
ifs.close();
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
std::ofstream ofs(argv[2]);
|
17
|
+
<%= prob.name %> solver;
|
18
18
|
<%=
|
19
|
-
|
19
|
+
engine.output.gsub(/^/, ' ' * 4)
|
20
20
|
%>
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
21
|
+
ofs.close();
|
22
|
+
} catch (std::exception &e) {
|
23
|
+
std::cerr << e.what() << std::endl;
|
24
|
+
}
|
25
|
+
return 0;
|
26
|
+
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
package <%= prob.name %>
|
2
2
|
<%
|
3
|
-
engine = GoEngine.new
|
3
|
+
engine = GoEngine.new(func, vars)
|
4
4
|
%>
|
5
|
-
func <%= engine.func_name %>(<%= engine.declare.join
|
5
|
+
func <%= engine.func_name %>(<%= engine.declare.join(", ") %>) <%= func.type.to_go %> {
|
6
6
|
return <%= func.type.dumb_go %>
|
7
|
-
}
|
7
|
+
}
|
@@ -7,7 +7,7 @@ import (
|
|
7
7
|
"topcoder"
|
8
8
|
)
|
9
9
|
<%
|
10
|
-
engine = GoEngine.new
|
10
|
+
engine = GoEngine.new(func, vars)
|
11
11
|
%>
|
12
12
|
func main() {
|
13
13
|
if len(os.Args) < 3 {
|
@@ -18,7 +18,7 @@ func main() {
|
|
18
18
|
var (
|
19
19
|
fileHandle *os.File
|
20
20
|
errIO error
|
21
|
-
<%= engine.declare.join
|
21
|
+
<%= engine.declare.join("\n#{' ' * 8}") %>
|
22
22
|
)
|
23
23
|
|
24
24
|
if fileHandle, errIO = os.Open(os.Args[1]); errIO != nil {
|
@@ -2,26 +2,26 @@ import System.Environment (getArgs)
|
|
2
2
|
import System.IO
|
3
3
|
import qualified TopCoder as TC
|
4
4
|
import qualified <%= prob.name %> (<%= func.name %>)
|
5
|
-
<%
|
6
|
-
engine = HaskellEngine.new
|
5
|
+
<%
|
6
|
+
engine = HaskellEngine.new(func, vars )
|
7
|
+
%>
|
8
|
+
<%=
|
9
|
+
engine.input
|
7
10
|
%>
|
8
|
-
<%=
|
9
|
-
engine.input
|
10
|
-
%>
|
11
11
|
|
12
|
-
main = do
|
12
|
+
main = do
|
13
13
|
args <- getArgs
|
14
14
|
hIn <- openFile (head args) ReadMode
|
15
15
|
contents <- hGetContents hIn
|
16
16
|
case (TC.parse getVars "parse variables" contents) of
|
17
17
|
Left err -> print err
|
18
|
-
Right (<%=
|
18
|
+
Right (<%=
|
19
19
|
temp = engine.vars.map do |var| var.name end
|
20
20
|
temp.join(', ')
|
21
21
|
%>) -> do
|
22
22
|
hOut <- openFile (head (tail args)) WriteMode
|
23
|
-
hPutStr hOut $ show $ <%= prob.name %>.<%=
|
24
|
-
engine.output
|
23
|
+
hPutStr hOut $ show $ <%= prob.name %>.<%=
|
24
|
+
engine.output
|
25
25
|
%>
|
26
26
|
hClose hOut
|
27
|
-
hClose hIn
|
27
|
+
hClose hIn
|
@@ -8,14 +8,14 @@ import org.topcoder.TopcoderReader;
|
|
8
8
|
import org.topcoder.TopcoderWriter;
|
9
9
|
import org.topcoder.TypeRef;
|
10
10
|
<%
|
11
|
-
engine = JavaEngine.new
|
11
|
+
engine = JavaEngine.new(func, vars )
|
12
12
|
%>
|
13
13
|
public class <%= prob.name %>Solver {
|
14
14
|
public static void main(String[] args) {
|
15
15
|
try {
|
16
16
|
TopcoderReader reader = new TopcoderReader(new FileReader(args[0]));
|
17
|
-
<%=
|
18
|
-
engine.input.gsub(/^/, ' ' * 8)
|
17
|
+
<%=
|
18
|
+
engine.input.gsub(/^/, ' ' * 8)
|
19
19
|
%>
|
20
20
|
reader.close();
|
21
21
|
|
@@ -28,5 +28,5 @@ public class <%= prob.name %>Solver {
|
|
28
28
|
} catch (Exception err) {
|
29
29
|
err.printStackTrace(System.err);
|
30
30
|
}
|
31
|
-
}
|
31
|
+
}
|
32
32
|
}
|
@@ -1,7 +1,5 @@
|
|
1
1
|
<%
|
2
|
-
engine = JavascriptEngine.new
|
3
|
-
%>
|
4
|
-
|
5
|
-
|
6
|
-
}
|
7
|
-
}
|
2
|
+
engine = JavascriptEngine.new(func, vars)
|
3
|
+
%>exports.<%= func.name %> = function(<%= engine.arglist %>) {
|
4
|
+
return <%= func.type.dumb_javascript %>;
|
5
|
+
};
|
@@ -1,30 +1,32 @@
|
|
1
1
|
#! /usr/bin/env node
|
2
|
-
<% engine = JavascriptEngine.new
|
2
|
+
<% engine = JavascriptEngine.new(func, vars) %>
|
3
3
|
var fs = require("fs");
|
4
4
|
var path = require("path");
|
5
5
|
var tc = null;
|
6
6
|
|
7
7
|
function init() {
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
var gettcHome = process.env.GETTC_HOME || path.join(process.env.HOME, ".gettc");
|
9
|
+
var includeDir = path.join(gettcHome, "include", "javascript");
|
10
|
+
tc = require(path.join(includeDir, "topcoder"));
|
11
11
|
}
|
12
12
|
|
13
|
-
function main() {
|
13
|
+
function main() {
|
14
|
+
try {
|
14
15
|
var input = fs.readFileSync(process.argv[2], { encoding: "ascii" });
|
15
16
|
var reader = new tc.Reader(input);
|
16
|
-
<%= engine.input.gsub(/^/, " " * 4) %>
|
17
|
+
<%= engine.input.gsub(/^/, " " * 4) %>
|
17
18
|
|
18
19
|
var <%= prob.name %> = require("./<%= prob.name %>");
|
19
20
|
var result = <%= prob.name %>.<%= func.name %>(<%= engine.arglist %>);
|
20
|
-
|
21
|
+
|
21
22
|
var writer = new tc.Writer();
|
22
23
|
writer.next(result, "<%= func.type.to_s %>");
|
23
24
|
fs.writeFileSync(process.argv[3], writer.toString(), { encoding: "ascii" });
|
24
|
-
} catch (err) {
|
25
|
+
} catch (err) {
|
25
26
|
console.log(err.toString());
|
26
27
|
console.trace();
|
27
|
-
}
|
28
|
+
}
|
29
|
+
}
|
28
30
|
|
29
31
|
init();
|
30
32
|
main();
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= engine = PythonEngine.new
|
1
|
+
<%= engine = PythonEngine.new(func, vars)
|
2
2
|
engine.shebang %>
|
3
3
|
import os, sys
|
4
4
|
import <%= prob.name %>
|
@@ -14,7 +14,7 @@ def main():
|
|
14
14
|
with open(sys.argv[1], "r") as fi:
|
15
15
|
input = fi.read()
|
16
16
|
reader = tc.Reader(input)
|
17
|
-
|
17
|
+
|
18
18
|
<%= engine.input.gsub(/^/, ' ' * 8) %>
|
19
19
|
|
20
20
|
result = <%= prob.name %>.<%= func.name %>(<%= engine.arglist %>)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<%
|
2
|
-
|
2
|
+
engine = RubyEngine.new(func, vars)
|
3
3
|
%>class <%= prob.name %>
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
def <%= func.name %>(<%= engine.arglist %>)
|
5
|
+
return <%= func.type.dumb_ruby %>
|
6
|
+
end
|
7
7
|
end
|
@@ -1,27 +1,24 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
|
-
<% engine = RubyEngine.new
|
2
|
+
<% engine = RubyEngine.new(func, vars) %>
|
3
3
|
require_relative "<%= prob.name %>"
|
4
4
|
|
5
5
|
require "gettc/types"
|
6
6
|
include Gettc
|
7
7
|
|
8
|
-
def init
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
gettc_home = File.expand_path(gettc_home)
|
14
|
-
$LOAD_PATH << File.join(gettc_home, "include", "ruby")
|
15
|
-
require "topcoder"
|
16
|
-
include TopCoder
|
8
|
+
def init
|
9
|
+
gettc_home = File.expand_path(ENV["GETTC_HOME"] || File.join(ENV["HOME"], ".gettc"))
|
10
|
+
$LOAD_PATH << File.join(gettc_home, "include", "ruby")
|
11
|
+
require "topcoder"
|
12
|
+
include TopCoder
|
17
13
|
end
|
18
14
|
|
19
|
-
def main
|
20
|
-
|
21
|
-
<%= engine.input.gsub(/^/, " " *
|
15
|
+
def main
|
16
|
+
reader = Reader.new(IO.read(ARGV[0]))
|
17
|
+
<%= engine.input.gsub(/^/, " " * 2) %>
|
22
18
|
|
23
|
-
|
24
|
-
|
19
|
+
result = <%= prob.name %>.new().<%= func.name %>(<%= engine.arglist %>)
|
20
|
+
IO.write(ARGV[1], Writer.new.next(result, <%= func.type.to_ruby %>).to_s)
|
25
21
|
end
|
26
|
-
|
27
|
-
|
22
|
+
|
23
|
+
init
|
24
|
+
main
|
@@ -1,26 +1,26 @@
|
|
1
1
|
#include <topcoder>
|
2
|
-
using namespace TopCoder;
|
2
|
+
using namespace TopCoder;
|
3
3
|
#include <fstream>
|
4
4
|
using namespace std;
|
5
|
-
<%
|
6
|
-
|
5
|
+
<%
|
6
|
+
engine = CppEngine.new(func, vars)
|
7
7
|
%>
|
8
|
-
int main(int argc, char *argv[]) {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
ifs.open(argv[1]);
|
14
|
-
read(ifs, output);
|
15
|
-
ifs.close();
|
8
|
+
int main(int argc, char *argv[]) {
|
9
|
+
try {
|
10
|
+
<%= func.type.to_cpp %> output, result;
|
11
|
+
ifstream ifs;
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
ifs.open(argv[1]);
|
14
|
+
read(ifs, output);
|
15
|
+
ifs.close();
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
return
|
17
|
+
ifs.open(argv[2]);
|
18
|
+
read(ifs, result);
|
19
|
+
ifs.close();
|
20
|
+
|
21
|
+
return same(output, result) ? 0 : 1;
|
22
|
+
} catch (exception &e) {
|
23
|
+
cerr << e.what() << endl;
|
24
|
+
}
|
25
|
+
return 2;
|
26
26
|
}
|
data/{core/lib → lib}/gettc.rb
RENAMED
File without changes
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require "net/https"
|
2
|
+
require "cgi"
|
3
|
+
require "uri"
|
4
|
+
require "ostruct"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
require "gettc/account"
|
8
|
+
|
9
|
+
module Gettc
|
10
|
+
class DownloadError < StandardError
|
11
|
+
end
|
12
|
+
|
13
|
+
class HttpError < DownloadError
|
14
|
+
attr_accessor :request, :response
|
15
|
+
|
16
|
+
def initialize(request, response, message = "An error occurred while making Http request")
|
17
|
+
@request = request
|
18
|
+
@response = response
|
19
|
+
|
20
|
+
filename = "gettc_http_response-#{Time.now.to_i}.html"
|
21
|
+
File.write(filename, @response.body)
|
22
|
+
|
23
|
+
super [ message, "Request: #{get_url(@request)}", http_to_s(@request), @request.body,
|
24
|
+
"Response: #{@response.class.to_s}", http_to_s(@response),
|
25
|
+
"Response body written to #{filename}" ].join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def http_to_s(http)
|
31
|
+
http.to_hash.map { |name, value| " #{name}: #{value}" }.join("\n")
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_url(request)
|
35
|
+
request["host"].to_s + request.path
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class BadResponseError < HttpError
|
40
|
+
def initialize(request, response, message = "Server response is in bad format")
|
41
|
+
super request, response, message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class AuthTokenError < DownloadError
|
46
|
+
attr_accessor :account, :server_response
|
47
|
+
|
48
|
+
def initialize(account, server_response, message = "Failed to acquire an OAuth token")
|
49
|
+
@account = account
|
50
|
+
@server_response = server_response
|
51
|
+
super "#{message}\nAccount: #{@account}\nServer Response:\n#{JSON.pretty_generate(server_response)}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class CookieError < DownloadError
|
56
|
+
attr_accessor :cookie
|
57
|
+
|
58
|
+
def initialize(cookie, message = "Cookie is in bad format")
|
59
|
+
@cookie = cookie
|
60
|
+
super "#{message}\nCookie: #{@cookie}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class IDNotAvailable < HttpError
|
65
|
+
attr_accessor :id
|
66
|
+
|
67
|
+
def initialize(id, request, response, message = "Problem ID not available")
|
68
|
+
@id = id
|
69
|
+
super request, response, "#{message}: #{id}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class ProxyError < DownloadError
|
74
|
+
attr_accessor :proxy
|
75
|
+
|
76
|
+
def initialize(proxy, message = "Proxy error")
|
77
|
+
@proxy = proxy
|
78
|
+
super "#{message}: http_proxy = #{proxy}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Downloader
|
83
|
+
ROOT = "https://community.topcoder.com"
|
84
|
+
LIMIT = 10
|
85
|
+
|
86
|
+
def initialize(account)
|
87
|
+
@account = account
|
88
|
+
@proxy = get_proxy
|
89
|
+
@cookie = get_cookie
|
90
|
+
end
|
91
|
+
|
92
|
+
def download(url)
|
93
|
+
uri = url
|
94
|
+
unless uri.is_a?(URI)
|
95
|
+
uri = url.start_with?("http") ? URI.parse(url) : URI.join(ROOT, url)
|
96
|
+
end
|
97
|
+
|
98
|
+
connect(uri) do |http|
|
99
|
+
LIMIT.times do
|
100
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
101
|
+
request["cookie"] = @cookie
|
102
|
+
|
103
|
+
response = http.request(request)
|
104
|
+
if response.is_a?(Net::HTTPSuccess)
|
105
|
+
raise BadResponseError.new(request, response) if block_given? && !yield(response.body)
|
106
|
+
return response.body
|
107
|
+
end
|
108
|
+
raise HttpError.new(request, response) unless response.is_a?(Net::HTTPMovedPermanently)
|
109
|
+
|
110
|
+
uri = URI.parse(response["location"])
|
111
|
+
end
|
112
|
+
|
113
|
+
raise DownloadError.new("Tried #{LIMIT} times without success")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def download_statement(problem_id)
|
118
|
+
download("/stat?c=problem_statement&pm=#{problem_id}") do |body|
|
119
|
+
body.match("<h3>Problem Statement</h3>")
|
120
|
+
end
|
121
|
+
rescue BadResponseError => error
|
122
|
+
raise IDNotAvailable.new(problem_id, error.request, error.response)
|
123
|
+
end
|
124
|
+
|
125
|
+
def download_detail(problem_id, round_id)
|
126
|
+
download("/tc?module=ProblemDetail&rd=#{round_id}&pm=#{problem_id}") do |body|
|
127
|
+
body.match("Problem Detail")
|
128
|
+
body.match("Problem Name")
|
129
|
+
body.match("Used As")
|
130
|
+
body.match("Categories")
|
131
|
+
body.match("Top Submission")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def download_solution(problem_id, round_id, solution_id)
|
136
|
+
download("/stat?c=problem_solution&cr=#{solution_id}&rd=#{round_id}&pm=#{problem_id}") do |body|
|
137
|
+
body.match("<TITLE>TopCoder Statistics - Problem Solution</TITLE>")
|
138
|
+
body.match("System Test Results")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def get_proxy
|
145
|
+
uri = URI.parse(ENV["http_proxy"])
|
146
|
+
proxy = OpenStruct.new
|
147
|
+
proxy.host, proxy.port = uri.host, uri.port
|
148
|
+
proxy.user, proxy.pass = uri.userinfo ? uri.userinfo.split(/:/) : nil, nil
|
149
|
+
proxy
|
150
|
+
rescue URI::InvalidURIError
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
|
154
|
+
def connect(uri)
|
155
|
+
uri = URI.parse(uri) unless uri.is_a?(URI)
|
156
|
+
options = { use_ssl: uri.scheme == 'https' }
|
157
|
+
|
158
|
+
if @proxy.nil?
|
159
|
+
Net::HTTP.start(uri.host, uri.port, options) { |http| yield http }
|
160
|
+
else
|
161
|
+
Net::HTTP.start(uri.host, uri.port,
|
162
|
+
@proxy.host, @proxy.port,
|
163
|
+
@proxy.user, @proxy.pass,
|
164
|
+
options) do |http|
|
165
|
+
begin
|
166
|
+
yield http
|
167
|
+
rescue Errno::ECONNRESET
|
168
|
+
raise ProxyError.new(@proxy)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def post_json(uri, params)
|
175
|
+
uri = URI.parse(uri) unless uri.is_a?(URI)
|
176
|
+
connect(uri) do |http|
|
177
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
178
|
+
request["Content-Type"] = "application/json"
|
179
|
+
request.body = params.to_json
|
180
|
+
http.request(request)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def get_cookie
|
185
|
+
jwt_token_response = JSON(post_json("http://api.topcoder.com/v2/auth", {
|
186
|
+
username: @account.username,
|
187
|
+
password: @account.password
|
188
|
+
}).body)
|
189
|
+
jwt_token = jwt_token_response["token"]
|
190
|
+
raise AuthTokenError.new(@account, jwt_token_response, "Failed to acquire a JWT token") unless jwt_token
|
191
|
+
|
192
|
+
refresh_token_response = JSON(post_json("http://api.topcoder.com/v2/reauth", {
|
193
|
+
token: jwt_token
|
194
|
+
}).body)
|
195
|
+
refresh_token = refresh_token_response["token"]
|
196
|
+
raise AuthTokenError.new(@account, refresh_token_response, "Failed to acquire a Refresh token") unless refresh_token
|
197
|
+
|
198
|
+
response = post_json("https://api.topcoder.com/v3/authorizations", {
|
199
|
+
param: {
|
200
|
+
externalToken: refresh_token
|
201
|
+
}
|
202
|
+
})
|
203
|
+
raw_cookie = response["set-cookie"]
|
204
|
+
|
205
|
+
unless CGI::Cookie.parse(raw_cookie).has_key?("tcsso")
|
206
|
+
raise DownloadError.new(raw_cookie, "Server refused to send a tcsso cookie")
|
207
|
+
end
|
208
|
+
raw_cookie
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|