spacetraders.rb/lib/client.rb

120 lines
2.9 KiB
Ruby

# frozen_string_literal: true
require 'net/http'
require 'uri'
require 'json'
require_relative 'open_struct'
module SpaceTraders
class Client
DEFAULT_BASE_URL = ENV['SPACETRADERS_DEFAULT_BASE_URL'] || 'https://api.spacetraders.io/v2'
def self.register(name:, faction: 'COSMIC', base_url: DEFAULT_BASE_URL)
Log.debug("register new account #{name} faction #{faction}")
res = Net::HTTP.post(
URI("#{base_url}/register"),
{ symbol: name, faction: faction }.to_json,
'Content-Type' => 'application/json'
)
token = JSON.parse(res.body).dig('data', 'token')
new(token: token, base_url: base_url)
end
def self.load_from_env
new(token: ENV['SPACETRADERS_TOKEN'], base_url: DEFAULT_BASE_URL)
end
attr_accessor :token, :base_url
# @param parse : if false, get/post will return the raw response, not the parsed body
def initialize(token:, base_url: DEFAULT_BASE_URL, parse: true)
raise 'Invalid Nil token' if token.nil?
@parse = parse
@token = token
@base_url = base_url
end
def parse?
@parse
end
private def parse!(res)
@res = res
@body = JSON.parse(res.body)
OpenStruct.deep_load @body["data"]
end
def meta
@body["meta"] if @body
end
def data(parse: true)
if @body
data = @body["data"]
data = OpenStruct.deep_load(data) if parse
data
end
end
def post(endpoint:, body:)
Log.debug("post #{endpoint} with body #{body}")
res = Net::HTTP.post(
URI("#{base_url}/#{endpoint}"),
body ? body.to_json : nil,
'Authorization' => "Bearer #{@token}",
'Content-Type' => 'application/json'
)
if block_given?
yield JSON.parse(res.body), res
elsif parse?
parse!(res)
else
res
end
end
def get(endpoint:)
Log.debug("get #{endpoint}")
res = Net::HTTP.get_response(
URI("#{@base_url}/#{endpoint}"),
'Authorization' => "Bearer #{@token}",
'Content-Type' => 'application/json'
)
if block_given?
yield JSON.parse(res.body), res
elsif parse?
parse!(res)
else
res
end
end
end
require 'endpoint'
class Client
def self.add_endpoint(name)
Log.debug("add_endpoint #{name}")
define_method(name.to_s.downcase) do
variable_name = "@memoize_#{name}"
variable = nil
# variable = instance_variable_get(variable_name)
if variable.nil?
endpoint = SpaceTraders::Endpoint::const_get(name.to_s.camelcase).new(client: self)
instance_variable_set(variable_name, endpoint)
endpoint
else
variable
end
end
end
def self.add_endpoints(*names)
names.each { add_endpoint(_1) }
end
add_endpoints :agents, :contracts, :ships, :systems
end
end