Packages

A client for EVE Online's CREST API

Current section

Files

Jump to
crest lib crest.ex
Raw

lib/crest.ex

defmodule CREST do
@moduledoc """
Contains functionality for fetching resources from CREST.
"""
require HTTPotion
alias CREST.HTTP
@root_url "https://#{Application.fetch_env!(:crest, :host)}/"
#
# General-purpose queries
#
@doc """
Get CREST root.
"""
@spec get_root :: Map.t
def get_root do
get_all_pages("", "application/vnd.ccp.eve.Api-v5+json; charset=utf-8")
end
#
# Universe
#
@doc """
Gets all regions.
"""
@spec get_regions() :: Map.t
def get_regions do
accept = "application/vnd.ccp.eve.RegionCollection-v1+json; charset=utf-8"
url = "regions/"
get_all_pages(url, accept)
end
@doc """
Gets specific region.
"""
@spec get_region(number | String.t) :: Map.t
def get_region(region_id) do
accept = "application/vnd.ccp.eve.Region-v1+json; charset=utf-8"
url = "regions/#{region_id}/"
get_all_pages(url, accept)
end
@doc """
Gets all constellations.
"""
@spec get_constellations() :: Map.t
def get_constellations do
accept = "application/vnd.ccp.eve.ConstellationCollection-v1+json; charset=utf-8"
url = "constellations/"
get_all_pages(url, accept)
end
@doc """
Gets specific constellation
"""
@spec get_constellation(number | String.t) :: Map.t
def get_constellation(constellation_id) do
accept = "application/vnd.ccp.eve.Constellation-v1+json; charset=utf-8"
url = "constellations/#{constellation_id}/"
get_all_pages(url, accept)
end
@doc """
Gets all solar systems.
"""
@spec get_solar_systems() :: Map.t
def get_solar_systems do
accept = "application/vnd.ccp.eve.SystemCollection-v1+json; charset=utf-8"
url = "solarsystems/"
get_all_pages(url, accept)
end
@doc """
Gets specific solar system.
"""
@spec get_solar_system(number | String.t) :: Map.t
def get_solar_system(system_id) do
accept = "application/vnd.ccp.eve.System-v1+json; charset=utf-8"
url = "solarsystems/#{system_id}/"
get_all_pages(url, accept)
end
@doc """
Gets location info for stations, systems, constellations and regions.
"""
@spec get_location(number | String.t) :: Map.t
def get_location(location_id) do
accept = "application/vnd.ccp.eve.Location-v1+json; charset=utf-8"
url = "universe/locations/#{location_id}/"
get_all_pages(url, accept)
end
#
# Types
#
@doc """
Get all types, including those not on market.
"""
@spec get_types() :: Map.t
def get_types do
accept = "application/vnd.ccp.eve.ItemTypeCollection-v1+json; charset=utf-8"
url = "inventory/types/"
get_all_pages(url, accept)
end
@doc """
Get specific type.
"""
@spec get_type(number | String.t) :: Map.t
def get_type(type_id) do
accept = "application/vnd.ccp.eve.ItemType-v3+json; charset=utf-8"
url = "inventory/types/#{type_id}/"
get_all_pages(url, accept)
end
#
# Market
#
@doc """
Get types on market.
"""
@spec get_market_types() :: Map.t
def get_market_types do
accept = "application/vnd.ccp.eve.MarketTypeCollection-v1+json; charset=utf-8"
url = "market/types/"
get_all_pages(url, accept)
end
@doc """
Gets all orders in a region.
"""
@spec get_orders_in_region(number | String.t) :: Map.t
def get_orders_in_region(region_id) do
accept = "application/vnd.ccp.eve.MarketOrderCollectionSlim-v1+json; charset=utf-8"
url = "market/#{region_id}/orders/all/"
get_all_pages(url, accept)
end
#
# Helper functions
#
@spec get_all_pages(String.t, String.t) :: Map.t
defp get_all_pages(url, accept) do
url = @root_url <> url
{url, accept}
|> HTTP.get
|> get_remaining_pages(url, accept)
end
@spec get_remaining_pages(Map.t, String.t, String.t) :: Map.t
defp get_remaining_pages(first_page, url, accept) do
# Get remaining pages if necessary
case first_page["pageCount"] do
nil -> first_page
page_count -> do_get_remaining_pages(first_page, url, accept, page_count)
end
end
@spec do_get_remaining_pages(Map.t, String.t, String.t, Number.t) :: List.t
defp do_get_remaining_pages(first_page, url, accept, page_count) do
# Fetches all remaing pages in parallel and extracts items
page_count
|> Range.new(2)
|> Enum.map(fn page_num -> (
Task.async(fn ->
request_url = url <> "?page=#{page_num}"
HTTP.get({request_url, accept})
end))
end)
|> Enum.map(fn task -> Task.await(task, 30_000) end)
|> (fn pages -> [first_page | pages] end).()
|> Enum.flat_map(&(Map.get(&1, "items")))
end
end