Class: AtCoderFriends::Scraping::Agent

Inherits:
Object
  • Object
show all
Includes:
Authentication, CustomTest, Session, Submission, Tasks
Defined in:
lib/at_coder_friends/scraping/agent.rb

Overview

common functions for scraping

Constant Summary collapse

BASE_URL =
'https://atcoder.jp/'
CONTACT =
'https://github.com/nejiko96/at_coder_friends'

Constants included from Authentication

AtCoderFriends::Scraping::Authentication::XPATH_USERNAME

Constants included from Session

Session::SESSION_STORE_FMT

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Submission

#post_submit, #submit

Methods included from CustomTest

#check_custom_test, #code_test, #post_custom_test

Methods included from Tasks

#fetch_all, #fetch_assignments, #fetch_problem

Methods included from Authentication

#fetch_raw, #fetch_with_auth, #post_login, #read_auth, #show_username, #username_link

Methods included from Session

#load_session, #save_session, #session_store

Constructor Details

#initialize(ctx) ⇒ Agent

Returns a new instance of Agent.



21
22
23
24
25
26
27
28
# File 'lib/at_coder_friends/scraping/agent.rb', line 21

def initialize(ctx)
  @ctx = ctx
  @agent = Mechanize.new
  agent.user_agent = "AtCoderFriends/#{VERSION} (#{CONTACT})"
  agent.pre_connect_hooks << proc { sleep 0.1 }
  agent.log = Logger.new($stderr) if ctx.options[:debug]
  load_session
end

Instance Attribute Details

#agentObject (readonly)

Returns the value of attribute agent.



19
20
21
# File 'lib/at_coder_friends/scraping/agent.rb', line 19

def agent
  @agent
end

#ctxObject (readonly)

Returns the value of attribute ctx.



19
20
21
# File 'lib/at_coder_friends/scraping/agent.rb', line 19

def ctx
  @ctx
end

Instance Method Details

#common_url(path) ⇒ Object



34
35
36
# File 'lib/at_coder_friends/scraping/agent.rb', line 34

def common_url(path)
  File.join(BASE_URL, path)
end

#contestObject



30
31
32
# File 'lib/at_coder_friends/scraping/agent.rb', line 30

def contest
  @contest ||= ctx.path_info.contest_name
end

#contest_url(path = '') ⇒ Object



38
39
40
# File 'lib/at_coder_friends/scraping/agent.rb', line 38

def contest_url(path = '')
  File.join(BASE_URL, 'contests', contest, path)
end

#find_lang(page, langs) ⇒ Object



57
58
59
60
61
# File 'lib/at_coder_friends/scraping/agent.rb', line 57

def find_lang(page, langs)
  langs.find do |lng|
    page.search("div#select-lang select option[value=#{lng}]")[0]
  end || langs[0]
end

#lang_id(ext) ⇒ Object



42
43
44
# File 'lib/at_coder_friends/scraping/agent.rb', line 42

def lang_id(ext)
  [lang_id_conf(ext)].flatten
end

#lang_id_conf(ext) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/at_coder_friends/scraping/agent.rb', line 46

def lang_id_conf(ext)
  ctx.config.dig('ext_settings', ext, 'submit_lang') || (
    msg = <<~MSG
      submit_lang for .#{ext} is not specified.
      Available languages:
      #{lang_list_txt || '(failed to fetch)'}
    MSG
    raise AppError, msg
  )
end

#lang_listObject



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/at_coder_friends/scraping/agent.rb', line 69

def lang_list
  @lang_list ||= begin
    page = fetch_with_auth(contest_url('custom_test'))
    form = page.forms[1]
    sel = form.field_with(name: 'data.LanguageId')
    sel && sel
      .options
      .reject { |opt| opt.value.empty? }
      .map do |opt|
        { v: opt.value, t: opt.text }
      end
  end
end

#lang_list_txtObject



63
64
65
66
67
# File 'lib/at_coder_friends/scraping/agent.rb', line 63

def lang_list_txt
  lang_list
    &.map { |opt| "#{opt[:v]} - #{opt[:t]}" }
    &.join("\n")
end