class Contest::Driver::KattisDriver

Public Instance Methods

get_desc() click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 50
def get_desc
  "Kattis (URL: https://open.kattis.com/)"
end
get_opts_ext() click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 29
def get_opts_ext
  define_options do
    opt(
      :contest_id,
      "Contest ID (Ex: open, kth, liu, etc...)",
      :type => :string,
      :required => false,
    )
    opt(
      :problem_id,
      "Problem ID (Ex: aaah, listgame2, etc...)",
      :type => :string,
      :required => true,
    )
  end
end
get_problem_id(options) click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 54
def get_problem_id(options)
  "#{options[:problem_id]}"
end
get_site_name() click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 46
def get_site_name
  "Kattis"
end
get_status_wait(submission_id, subdomain) click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 159
def get_status_wait(submission_id, subdomain)
  submission_id = submission_id.to_s
  # Wait for result
  12.times do
    sleep 10
    submission_page = @client.get "https://#{subdomain}.kattis.com/submissions/#{submission_id}"
    status = get_submission_status(submission_id, submission_page.body)
    return status unless is_wait_status status
    trigger 'retry'
  end
  trigger 'timeout'
  return 'timeout'
end
get_submission_id(body) click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 173
def get_submission_id(body)
  doc = Nokogiri::HTML(body)
  return doc.xpath('//*[@id="wrapper"]/div/div[2]/section/table/tbody/tr[1]/td[1]/a')[0].inner_text().strip
end
get_submission_status(submission_id, body) click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 178
def get_submission_status(submission_id, body)
  doc = Nokogiri::HTML(body)
  return doc.xpath('//*[@id="judge_table"]/tbody/tr[1]/td[4]/span').inner_text().strip
end
initialize_ext() click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 23
def initialize_ext
  @client = Mechanize.new {|agent|
    agent.user_agent_alias = 'Windows IE 7'
  }
end
is_wait_status(status) click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 150
def is_wait_status(status)
  case status
  when "Running", "Compiling", ""
    true
  else
    false
  end
end
resolve_language(label) click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 58
def resolve_language(label)
  case label
  when 'cpp'
    return '1'
  when 'c'
    return '2'
  when 'java'
    return '3'
  when 'python2'
    return '6'
  when 'python3'
    return '8'
  when 'cs'
    return '9'
  when 'golang'
    return '10'
  when 'objc'
     return '11'
  when 'haskell'
          return '12'
  when 'prolog'
          return '13'
  when 'javascript'
          return '14'
  when 'php'
          return '15'
  else
    abort 'unknown language'
  end
end
submit_ext() click to toggle source
# File lib/contest/driver/kattis_driver.rb, line 89
def submit_ext
  trigger 'start'
  problem_id = @options[:problem_id]

  if (@options[:contest_id])
    subdomain = @options[:contest_id]
  else
    subdomain = 'open'
  end

  # Login
  trigger 'before_login'
  login_page = @client.get "https://#{subdomain}.kattis.com/login?email_login=true"
  login_page.form_with(:action => '/login/email') do |form|
    form.user = @config["user"]
    form.password = @config["password"]
  end.submit
  trigger 'after_login'

  # Submit
  trigger 'before_submit', @options
  submit_page = @client.get "https://#{subdomain}.kattis.com/submit"
  res_page = submit_page.form_with(:name => 'upload') do |form|
    form.problem = problem_id
    form['lang'] = @options[:language]
    form.sub_code = File.read(@options[:source])
    # Use file name as main class for Java
    if (@options[:language] == resolve_language('java'))
      form['mainclass'] = @options[:source].rpartition('.')[0]
    end
    form.submit(form.button_with(:name => 'submit'))
  end.submit
  trigger 'after_submit'

  # Result
  trigger 'before_wait'
  user = @config['user']
  doc = Nokogiri::HTML(res_page.body)
  # Check for error messages
  error = doc.xpath('//p[@class="error"]')[0];
  if ((/Problem ID not found in database./ =~ error) ||
      (/Problem-id inte funnet i databasen./ =~ error))
    abort "Problem ID not found in database."
  end
  sleep 2
  submissions_page = @client.get "https://#{subdomain}.kattis.com/users/#{user}"
  submission_id = get_submission_id(submissions_page.body)
  status = get_status_wait(submission_id, subdomain)
  trigger(
    'after_wait',
    {
      :submission_id => submission_id,
      :status => status,
      :result => get_commit_message(status),
    }
  )

  trigger 'finish'
  get_commit_message(status)
end