Packages

Elixir library for working with playfab

Current section

Files

Jump to
playfab_ex lib mix tasks gen_api.ex
Raw

lib/mix/tasks/gen_api.ex

defmodule Mix.Tasks.GenApi do
use Mix.Task
def run(_) do
gen_api()
end
def gen_api do
["client", "server", "matchmaker", "admin", "playstream"]
|> Enum.each(&(do_gen_api(&1)))
end
defp do_gen_api(name) do
body = Tesla.get("https://api.playfab.com/documentation/#{name}").body
{:ok, pid} = Agent.start_link(fn() -> nil end)
File.mkdir_p("lib/#{name}/default")
Floki.find(body, ".api")
|> Enum.into([], &(parse_group(&1, name)))
|> Enum.each(&(generate(&1, pid, name)))
end
defp parse_group({"h4", [_, {"id", group}], detail}, name) do
module_string = group |> String.replace("-", "")
module = Macro.camelize("Elixir.PlayfabEx.#{name |> Macro.camelize}.Default." <> module_string) |> String.to_atom
end
defp parse_group({_, _, detail}, _) do
count = Floki.find(detail, "a") |> Enum.count
for i <- 0..count do
link = Floki.find(detail, "a")
|> Floki.attribute("href")
|> Enum.at(i)
title = Floki.find(detail, "a")
|> Enum.at(i)
|> get_text()
docs = detail
|> Floki.find("p")
|> Enum.at(i)
|> get_text()
%{link: link, title: title, docs: docs}
end
end
defp parse_group(_, _), do: nil
def get_text(nil), do: nil
def get_text(html), do: html |> Floki.text
defp generate(data, pid, folder) when is_atom(data) do
Agent.update(pid, fn(_) -> data |> Atom.to_string |> String.replace("Elixir.", "") end)
end
defp generate(detail, pid, folder) do
current_module = Agent.get(pid, fn(state) -> state end)
to_write = ["defmodule #{current_module} do"]
to_write = Enum.reduce(detail, to_write, fn(%{docs: docs, link: link, title: title}, acc) ->
if(title == nil || String.contains?(title, "http")) do
acc
else
function_name = Macro.underscore(title |> String.replace("IDs", "Ids"))
acc ++ [~s(
@doc """
#{docs}
@link https://api.playfab.com#{link}
"""
@spec #{function_name}(map(\)\) :: {:ok, map} | {:error, String.t}
def #{function_name}(params\) do
fetch("#{Macro.camelize(folder)}/#{title}", params\)
end)]
end
end)
to_write = to_write ++ [~S(
defp fetch(path, params\) do
string_params = Poison.encode!(params\)
try do
response = Tesla.post("https://#{title_id(\)}.playfabapi.com/#{path}", string_params, headers: %{"Content-Type" => "application/json", "X-SecretKey" => secret_key(\)}\)
|> Map.get(:body\)
|> Poison.decode!
{:ok, response}
rescue
_ -> {:error, "Unable to fetch data from playfab"}
end
end
defp title_id(\) do
Application.get_env(:playfab_ex, :title_id\)
end
defp secret_key(\) do
Application.get_env(:playfab_ex, :secret_key\)
end
)]
to_write = to_write ++ ["end"]
filename = current_module
|> String.replace("PlayfabEx.", "")
|> Macro.underscore()
File.write!("lib/" <> filename <> ".ex", to_write |> Enum.join("\n"))
delegate_module = String.replace(current_module, "Default.", "")
to_write = ["defmodule #{delegate_module} do"]
to_write = to_write ++ [" use Interface"]
to_write = Enum.reduce(detail, to_write, fn(%{docs: docs, link: link, title: title}, acc) ->
if(title == nil || String.contains?(title, "http")) do
acc
else
function_name = Macro.underscore(title |> String.replace("IDs", "Ids"))
acc ++ [~s(
@doc """
#{docs}
[online docs](https://api.playfab.com#{link}\)
"""
@spec #{function_name}(map(\)\) :: {:ok, map} | {:error, String.t}
definterface #{function_name}(params\), to: (Application.get_env(:playfab_ex, #{delegate_module}\) || #{current_module}\)
)]
end
end)
to_write = to_write ++ ["end"]
filename = delegate_module
|> String.replace("PlayfabEx.", "")
|> Macro.underscore()
File.write!("lib/" <> filename <> ".ex", to_write |> Enum.join("\n"))
end
end