class IVLE::API

Attributes

api_key[RW]
password[RW]
username[RW]

Public Class Methods

new(*args) click to toggle source
# File lib/IVLE.rb, line 62
def initialize(*args)
  self.api_key  = args[0]

  if args.size == 2
    @access_token = args[1]
  elsif args.size == 3
    self.username = args[1]
    self.password = args[2]
  else
    raise ArgumentError "Expected 2 or 3 arguments, got #{args.size}"
  end
end

Public Instance Methods

api(method, params={}, verb=:get, add_auth=true) click to toggle source

I don't trust the API documentation so this is now public. Call this yourself if my implementation fails.

# File lib/IVLE.rb, line 77
def api(method, params={}, verb=:get, add_auth=true)
  params = add_auth(params) if add_auth
  resp = client.send(verb, "api/Lapi.svc/#{method}", params)
  format_response(resp.body)
end
api_post(method, params={}) click to toggle source
# File lib/IVLE.rb, line 83
def api_post(method, params={})
  api(method, params, :post)
end

Private Instance Methods

access_token() click to toggle source
# File lib/IVLE.rb, line 89
def access_token
  # Seriously IVLE, implement proper oAuth
  # Who did you even enslave to make this

  @access_token ||= begin
    agent = Mechanize.new { |a| a.verify_mode = OpenSSL::SSL::VERIFY_NONE unless IVLE.settings[:verify_ssl] }
    page = agent.get("https://ivle.nus.edu.sg/api/login?apikey=#{api_key}&url=")

    form = page.form_with(name: 'frm') do |f|
      f.field_with(name: 'userid').value = self.username
      f.field_with(name: 'password').value = self.password
    end

    form.submit.body
  end
end
add_auth(params) click to toggle source
# File lib/IVLE.rb, line 119
def add_auth(params)
  default_params = { apikey: api_key, authtoken: access_token }
  default_params.merge(params)
end
client() click to toggle source
# File lib/IVLE.rb, line 106
def client
  options = {
    url: 'https://ivle.nus.edu.sg/',
    ssl: { verify: IVLE.settings[:verify_ssl] }
  }

  @client ||= Faraday.new(options) do |faraday|
    faraday.request  :json                                  # convert POST params to JSON
    faraday.response :logger if IVLE.settings[:faraday_log] # log requests to STDOUT
    faraday.adapter  Faraday.default_adapter                # make requests with Net::HTTP
  end
end
format_response(body) click to toggle source
# File lib/IVLE.rb, line 124
def format_response(body)
  # Documentation does not represent production (really!?), so we play it safe here
  JSON.parse(body, symbolize_names: true)
rescue
  Nokogiri::XML(body).root.element_children.each_with_object({}) do |e, h|
    h[e.name.to_sym] = e.content
  end
end