Files
cobblemon-ui/lib/cobblemon_ui/tier_list_scraper.ex
Alex Mickelson f69f287ece
Some checks failed
Build and Deploy / Build & Push Image (push) Failing after 5s
tier list
2026-03-16 20:06:26 -06:00

66 lines
1.5 KiB
Elixir

defmodule CobblemonUi.TierListScraper do
@url "https://rankedboost.com/pokemon/tier-list/"
@filename "pokemon_tier_list.json"
def output_file do
dir = System.get_env("CACHE_DIR", ".")
Path.join(dir, @filename)
end
def run do
with {:ok, html} <- fetch_page(),
pokemon <- parse(html),
:ok <- write_json(pokemon) do
{:ok, pokemon}
end
end
def fetch_page do
case Req.get(@url) do
{:ok, %Req.Response{status: 200, body: body}} -> {:ok, body}
{:ok, %Req.Response{status: status}} -> {:error, {:http_error, status}}
{:error, err} -> {:error, err}
end
end
def parse(html) do
html
|> Floki.parse_document!()
|> Floki.find(".pokemon-tier")
|> Enum.map(&extract_pokemon/1)
end
defp extract_pokemon(node) do
name =
node
|> Floki.find(".name")
|> Floki.text()
|> String.trim()
tier =
node
|> Floki.find(".tier")
|> Floki.text()
|> String.trim()
%{name: name, tier: tier}
end
def write_json(data) do
json = Jason.encode!(data, pretty: true)
File.write(output_file(), json)
end
# Returns a map of %{lowercase_name => tier} for fast lookup, or an empty map if unavailable.
def load_tier_list do
with {:ok, contents} <- File.read(output_file()),
{:ok, entries} <- Jason.decode(contents) do
Map.new(entries, fn %{"name" => name, "tier" => tier} ->
{String.downcase(name), tier}
end)
else
_ -> %{}
end
end
end