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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/bin/gettc +60 -69
  3. data/dist/config.yml +1 -1
  4. data/dist/include/cpp/engine.rb +78 -86
  5. data/dist/include/cpp/topcoder +236 -236
  6. data/dist/include/go/engine.rb +53 -61
  7. data/dist/include/haskell/engine.rb +112 -122
  8. data/dist/include/java/engine.rb +187 -184
  9. data/dist/include/javascript/engine.rb +26 -30
  10. data/dist/include/javascript/topcoder.js +3 -3
  11. data/dist/include/javascript/topcoder/errors.js +5 -5
  12. data/dist/include/javascript/topcoder/reader.js +188 -165
  13. data/dist/include/javascript/topcoder/writer.js +37 -33
  14. data/dist/include/python/engine.rb +43 -52
  15. data/dist/include/python/topcoder/__init__.pyc +0 -0
  16. data/dist/include/python/topcoder/__pycache__/__init__.cpython-34.pyc +0 -0
  17. data/dist/include/python/topcoder/__pycache__/errors.cpython-34.pyc +0 -0
  18. data/dist/include/python/topcoder/__pycache__/reader.cpython-34.pyc +0 -0
  19. data/dist/include/python/topcoder/__pycache__/writer.cpython-34.pyc +0 -0
  20. data/dist/include/python/topcoder/errors.pyc +0 -0
  21. data/dist/include/python/topcoder/reader.pyc +0 -0
  22. data/dist/include/python/topcoder/writer.pyc +0 -0
  23. data/dist/include/ruby/engine.rb +47 -52
  24. data/dist/include/ruby/topcoder/reader.rb +205 -193
  25. data/dist/include/ruby/topcoder/writer.rb +39 -37
  26. data/dist/template/bin/runner.rb +146 -151
  27. data/dist/template/bin/runner.sh +96 -96
  28. data/dist/template/prob/{name}.html +1 -1
  29. data/dist/template/solve/cpp/{name}.cpp +3 -4
  30. data/dist/template/solve/cpp/{name}Solver.cpp +14 -14
  31. data/dist/template/solve/go/{name}/{name}.go +3 -3
  32. data/dist/template/solve/go/{name}Solver.go +2 -2
  33. data/dist/template/solve/haskell/{name}.hs +6 -6
  34. data/dist/template/solve/haskell/{name}Solver.hs +10 -10
  35. data/dist/template/solve/java/{name}.java +4 -4
  36. data/dist/template/solve/java/{name}Solver.java +4 -4
  37. data/dist/template/solve/javascript/{name}.js +4 -6
  38. data/dist/template/solve/javascript/{name}Solver.js +11 -9
  39. data/dist/template/solve/python/{name}.py +1 -1
  40. data/dist/template/solve/python/{name}Solver.py +2 -2
  41. data/dist/template/solve/ruby/{name}.rb +4 -4
  42. data/dist/template/solve/ruby/{name}Solver.rb +14 -17
  43. data/dist/template/util/check/check.cpp +19 -19
  44. data/{core/lib → lib}/gettc.rb +0 -0
  45. data/lib/gettc/account.rb +14 -0
  46. data/lib/gettc/download.rb +211 -0
  47. data/lib/gettc/generate.rb +156 -0
  48. data/lib/gettc/parse.rb +237 -0
  49. data/lib/gettc/print.rb +54 -0
  50. data/lib/gettc/problem.rb +39 -0
  51. data/lib/gettc/signature.rb +63 -0
  52. data/lib/gettc/types.rb +93 -0
  53. data/lib/version.rb +3 -0
  54. data/test/gettc/download_test.rb +61 -0
  55. data/test/gettc/generate_test.rb +70 -0
  56. data/test/gettc/parse_test.rb +78 -0
  57. data/test/gettc/signature_test.rb +71 -0
  58. data/test/gettc/types_test.rb +31 -0
  59. metadata +28 -23
  60. data/core/lib/gettc/download.rb +0 -130
  61. data/core/lib/gettc/generate.rb +0 -145
  62. data/core/lib/gettc/parse.rb +0 -233
  63. data/core/lib/gettc/print.rb +0 -56
  64. data/core/lib/gettc/problem.rb +0 -33
  65. data/core/lib/gettc/signature.rb +0 -55
  66. data/core/lib/gettc/types.rb +0 -83
  67. data/core/lib/version.rb +0 -3
  68. data/core/test/gettc/download_test.rb +0 -29
  69. data/core/test/gettc/generate_test.rb +0 -31
  70. data/core/test/gettc/parse_test.rb +0 -104
  71. data/core/test/gettc/signature_test.rb +0 -54
  72. data/core/test/gettc/types_test.rb +0 -28
@@ -5,4 +5,4 @@
5
5
  <body>
6
6
  <%= @prob.to_html %>
7
7
  </body>
8
- </html>
8
+ </html>
@@ -4,8 +4,7 @@ using namespace std;
4
4
 
5
5
  class <%= prob.name %> {
6
6
  public:
7
- <%= engine = CppEngine.new func, vars
8
- engine.declare.gsub /^/, " " %> {
9
- return <%= func.type.dumb_cpp %>;
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
- engine = CppEngine.new func, vars
6
+ engine = CppEngine.new(func, vars)
7
7
  %>
8
8
  int main(int argc, char const *argv[]) {
9
- try {
10
- std::ifstream ifs(argv[1]);
9
+ try {
10
+ std::ifstream ifs(argv[1]);
11
11
  <%=
12
- engine.input.gsub(/^/, ' ' * 8)
12
+ engine.input.gsub(/^/, ' ' * 4)
13
13
  %>
14
- ifs.close();
14
+ ifs.close();
15
15
 
16
- std::ofstream ofs(argv[2]);
17
- <%= prob.name %> solver;
16
+ std::ofstream ofs(argv[2]);
17
+ <%= prob.name %> solver;
18
18
  <%=
19
- engine.output.gsub(/^/, ' ' * 8)
19
+ engine.output.gsub(/^/, ' ' * 4)
20
20
  %>
21
- ofs.close();
22
- } catch (std::exception &e) {
23
- std::cerr << e.what() << std::endl;
24
- }
25
- return 0;
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 func, vars
3
+ engine = GoEngine.new(func, vars)
4
4
  %>
5
- func <%= engine.func_name %>(<%= engine.declare.join ", " %>) <%= func.type.to_go %> {
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 func, vars
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 "\n#{' ' * 8}" %>
21
+ <%= engine.declare.join("\n#{' ' * 8}") %>
22
22
  )
23
23
 
24
24
  if fileHandle, errIO = os.Open(os.Args[1]); errIO != nil {
@@ -1,7 +1,7 @@
1
- module <%= prob.name %> where
2
- <%
3
- engine = HaskellEngine.new func, vars
1
+ module <%= prob.name %> where
2
+ <%
3
+ engine = HaskellEngine.new(func, vars)
4
+ %>
5
+ <%=
6
+ engine.declare
4
7
  %>
5
- <%=
6
- engine.declare
7
- %>
@@ -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 func, vars
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
@@ -1,9 +1,9 @@
1
1
  <%
2
- engine = JavaEngine.new func, vars
2
+ engine = JavaEngine.new(func, vars )
3
3
  %>public class <%= prob.name %> {
4
- <%=
5
- engine.declare.gsub(/^/, ' ' * 4)
4
+ <%=
5
+ engine.declare.gsub(/^/, ' ' * 4)
6
6
  %> {
7
7
  return <%= func.type.dumb_java %>;
8
8
  }
9
- }
9
+ }
@@ -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 func, vars
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 func, vars
3
- %>module.exports = {
4
- <%= func.name %> : function(<%= engine.arglist %>) {
5
- return <%= func.type.dumb_javascript %>;
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 func, vars %>
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
- 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"));
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() { try {
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
1
  <%
2
- engine = PythonEngine.new func, vars
2
+ engine = PythonEngine.new(func, vars)
3
3
  %>def <%= func.name %>(<%= engine.arglist %>):
4
4
  return <%= func.type.dumb_python %>
@@ -1,4 +1,4 @@
1
- <%= engine = PythonEngine.new func, vars
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
- engine = RubyEngine.new func, vars
2
+ engine = RubyEngine.new(func, vars)
3
3
  %>class <%= prob.name %>
4
- def <%= func.name %>(<%= engine.arglist %>)
5
- return <%= func.type.dumb_ruby %>
6
- end
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 func, vars %>
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
- gettc_home = File.join(ENV["HOME"], ".gettc")
10
- if ENV.has_key?("GETTC_HOME")
11
- gettc_home = ENV["GETTC_HOME"]
12
- end
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
- reader = Reader.new(IO.read(ARGV[0]))
21
- <%= engine.input.gsub(/^/, " " * 4) %>
15
+ def main
16
+ reader = Reader.new(IO.read(ARGV[0]))
17
+ <%= engine.input.gsub(/^/, " " * 2) %>
22
18
 
23
- result = <%= prob.name %>.new().<%= func.name %>(<%= engine.arglist %>)
24
- IO.write(ARGV[1], Writer.new().next(result, <%= func.type.to_ruby %>).to_s())
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
- init()
27
- main()
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
- engine = CppEngine.new func, vars
5
+ <%
6
+ engine = CppEngine.new(func, vars)
7
7
  %>
8
- int main(int argc, char *argv[]) {
9
- try {
10
- <%= func.type.to_cpp %> output, result;
11
- ifstream ifs;
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
- ifs.open(argv[2]);
18
- read(ifs, result);
19
- ifs.close();
13
+ ifs.open(argv[1]);
14
+ read(ifs, output);
15
+ ifs.close();
20
16
 
21
- return same(output, result) ? 0 : 1;
22
- } catch (exception &e) {
23
- cerr << e.what() << endl;
24
- }
25
- return 2;
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
  }
File without changes
@@ -0,0 +1,14 @@
1
+ module Gettc
2
+ class Account
3
+ attr_accessor :username, :password
4
+
5
+ def initialize(username, password)
6
+ @username = username
7
+ @password = password
8
+ end
9
+
10
+ def to_s
11
+ "#{@username}|#{@password}"
12
+ end
13
+ end
14
+ end
@@ -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