Skip to content

Instantly share code, notes, and snippets.

@leite
Last active July 23, 2020 05:36
Show Gist options
  • Save leite/3d4ab147b7f4e272a94a725b3769ade1 to your computer and use it in GitHub Desktop.
Save leite/3d4ab147b7f4e272a94a725b3769ade1 to your computer and use it in GitHub Desktop.
list all municipalities of brazil by state
defmodule CEP.Municipalities do
@moduledoc """
Documentation for `CEP.Municipalities`.
"""
alias CEP.{Utils, Municipalities}
defstruct has_municipalities?: false,
states: %{},
municipalities: [],
timeout: 900,
cache: nil
@municipalities_url "https://sidra.ibge.gov.br/Territorio/Unidades?nivel=6"
@doc """
Get municipalities
"""
def get(
%CEP{all?: all?, municipalities?: municipalities?} = options
) when all? and not municipalities? do
options
end
@doc """
Get municipalities
"""
def get(%CEP{
all?: all?,
municipalities?: municipalities?,
cache_exists?: cache_exists?,
cache: cache,
timeout: timeout
} = options) when all? or municipalities? do
sections = if cache_exists?, do: Utils.list_sections(cache), else: []
load_municipalities_from_cache(%Municipalities{
timeout: timeout,
cache: cache,
has_municipalities?: municipalities? and Enum.member?(sections, "municipalities")
})
|> get_municipalities
|> IO.inspect
options
end
def get_municipalities(
%Municipalities{has_municipalities?: has_municipalities?, cache: cache, timeout: timeout} = struct
) when not has_municipalities? do
case HTTPoison.get(@municipalities_url, [], timeout: 15_000, recv_timeout: timeout * 1_000) do
{:ok, %{status_code: 200, body: body}} ->
Utils.write_cache(body, cache, :municipalities)
|> Poison.decode
|> parse_municipalities(struct)
{:ok, %{status_code: status}} ->
exit {:error, "something went wrong, http code ##{status}"}
{:error, %{reason: reason}} ->
exit {:error, "something else went really wrong, reason: #{reason}"}
end
end
def load_municipalities_from_cache(
%Municipalities{has_municipalities?: has_municipalities?} = struct
) when not has_municipalities? do
struct
end
def load_municipalities_from_cache(
%Municipalities{has_municipalities?: has_municipalities?, cache: cache} = struct
) when has_municipalities? do
Utils.read_cache(cache, :municipalities) |> parse_municipalities(struct)
end
def parse_municipalities(
[municipality | m_tail], [state | s_tail], %{municipalities: municipalities} = struct, s_cache \\ []
) do
parse_municipalities(
m_tail,
s_tail,
%Municipalities{struct | municipalities: ["#{municipality}_#{state}" | municipalities] },
[ %{state: state, municipality: municipality} | s_cache ]
)
end
def parse_municipalities [], [], %{municipalities: municipalities, states: states} = struct, s_cache do
%Municipalities{struct | municipalities: municipalities, states: Enum.group_by(s_cache, & &1[:state])}
end
def parse_municipalities({:ok, %{"Nivel"=>%{"Id"=>6}, "Nomes"=>names, "SiglasUF"=>ufs}}, struct) do
parse_municipalities names, ufs, struct
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment