This commit is contained in:
65
lib/cobblemon_ui/tier_list_scraper.ex
Normal file
65
lib/cobblemon_ui/tier_list_scraper.ex
Normal file
@@ -0,0 +1,65 @@
|
||||
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
|
||||
Reference in New Issue
Block a user