gettc 1.10 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
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