gettc 1.10 → 2.0
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 +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
|