Packages

Pure Elixir wrapper for the Figure Eight API

Current section

3 Versions

Jump to

Compare versions

20 files changed
+835 additions
-556 deletions
  @@ -4,11 +4,15 @@
4 4 {<<"elixir">>,<<"~> 1.6">>}.
5 5 {<<"files">>,
6 6 [<<"lib">>,<<"lib/figure_eight">>,<<"lib/figure_eight.ex">>,
7 - <<"lib/figure_eight/endpoint.ex">>,<<"lib/figure_eight/entity">>,
8 - <<"lib/figure_eight/entity.ex">>,<<"lib/figure_eight/entity/account.ex">>,
9 - <<"lib/figure_eight/entity/error.ex">>,<<"lib/figure_eight/entity/job.ex">>,
10 - <<"lib/figure_eight/entity/judgment.ex">>,<<"lib/figure_eight/request.ex">>,
11 - <<"mix.exs">>,<<"README.md">>,<<"LICENSE">>]}.
7 + <<"lib/figure_eight/account.ex">>,<<"lib/figure_eight/entity">>,
8 + <<"lib/figure_eight/error.ex">>,<<"lib/figure_eight/job.ex">>,
9 + <<"lib/figure_eight/judgment.ex">>,<<"lib/figure_eight/services">>,
10 + <<"lib/figure_eight/services/endpoint.ex">>,<<"lib/figure_eight/unit.ex">>,
11 + <<"lib/figure_eight/utils">>,<<"lib/figure_eight/utils/entity.ex">>,
12 + <<"lib/figure_eight/utils/reference.ex">>,
13 + <<"lib/figure_eight/utils/request.ex">>,
14 + <<"lib/figure_eight/web_hook_plug.ex">>,<<"mix.exs">>,<<"README.md">>,
15 + <<"LICENSE">>]}.
12 16 {<<"licenses">>,[<<"GPL-3.0">>]}.
13 17 {<<"links">>,
14 18 [{<<"GitHub">>,<<"https://github.com/elridion/figure_eight_elixir">>}]}.
  @@ -23,5 +27,10 @@
23 27 {<<"name">>,<<"httpoison">>},
24 28 {<<"optional">>,false},
25 29 {<<"repository">>,<<"hexpm">>},
26 - {<<"requirement">>,<<"~> 1.0">>}]]}.
27 - {<<"version">>,<<"1.0.0">>}.
30 + {<<"requirement">>,<<"~> 1.0">>}],
31 + [{<<"app">>,<<"plug">>},
32 + {<<"name">>,<<"plug">>},
33 + {<<"optional">>,false},
34 + {<<"repository">>,<<"hexpm">>},
35 + {<<"requirement">>,<<"~> 1.6">>}]]}.
36 + {<<"version">>,<<"2.0.0-rc0">>}.
  @@ -1,52 +1,17 @@
1 1 defmodule FigureEight do
2 2 alias FigureEight.Endpoint
3 - alias FigureEight.Entity.{Account, Job, Judgement}
3 + alias FigureEight.Utils.Request
4 4
5 5 def start(_type, _args) do
6 6 [Endpoint]
7 7 |> Supervisor.start_link(strategy: :one_for_one)
8 8 end
9 9
10 - def account() do
11 - query(Account)
10 + def call(%Request{} = request) do
11 + GenServer.call(FigureEight, request)
12 12 end
13 13
14 - def job(id) do
15 - query(Job, job_id: id)
14 + def cast(%Request{} = request) do
15 + GenServer.cast(FigureEight, request)
16 16 end
17 -
18 - def jobs_meta(team_id \\ nil) do
19 - if team_id do
20 - query(Job, team_id: team_id)
21 - else
22 - query(Job)
23 - end
24 - end
25 -
26 - def judgements(job_id, unit_id) do
27 - query(Judgement, job_id: job_id, unit_id: unit_id)
28 - end
29 -
30 - def judgements_meta(job_id) do
31 - query(Judgement, job_id: job_id)
32 - end
33 -
34 - defp query(mod, conditions \\ %{})
35 -
36 - defp query(mod, conditions) when is_map(conditions) do
37 - apply(mod, :request, [conditions])
38 - |> Endpoint.call()
39 - |> case do
40 - {200, resp} ->
41 - apply(mod, :cast, [resp])
42 -
43 - {:error, _resp} = err ->
44 - err
45 -
46 - {_code, err} ->
47 - apply(FigureEight.Entity.Error, :cast, [err])
48 - end
49 - end
50 -
51 - defp query(mod, conditions), do: query(mod, Map.new(conditions))
52 17 end
  @@ -0,0 +1,63 @@
1 + defmodule FigureEight.Account do
2 + @behaviour FigureEight.Utils.Entity
3 + import FigureEight.Utils.Entity, only: [from_iso8601: 1]
4 + alias FigureEight.Utils.Request
5 +
6 + defstruct [
7 + :akon_id,
8 + :auth_code,
9 + :auth_key,
10 + :balance,
11 + :created_at,
12 + :email,
13 + :first_name,
14 + :id,
15 + :job_template_id,
16 + :last_name,
17 + :status
18 + ]
19 +
20 + def cast(response) do
21 + with {:ok, akon_id} <- Map.fetch(response, "akon_id"),
22 + {:ok, auth_code} <- Map.fetch(response, "auth_code"),
23 + {:ok, auth_key} <- Map.fetch(response, "auth_key"),
24 + {:ok, balance} <- Map.fetch(response, "balance"),
25 + {:ok, created_at} <- Map.fetch(response, "created_at"),
26 + {:ok, email} <- Map.fetch(response, "email"),
27 + {:ok, first_name} <- Map.fetch(response, "first_name"),
28 + {:ok, id} <- Map.fetch(response, "id"),
29 + {:ok, job_template_id} <- Map.fetch(response, "job_template_id"),
30 + {:ok, last_name} <- Map.fetch(response, "last_name"),
31 + {:ok, status} <- Map.fetch(response, "status") do
32 + %__MODULE__{
33 + akon_id: akon_id,
34 + auth_code: auth_code,
35 + auth_key: auth_key,
36 + balance: balance,
37 + created_at: from_iso8601(created_at),
38 + email: email,
39 + first_name: first_name,
40 + id: id,
41 + job_template_id: job_template_id,
42 + last_name: last_name,
43 + status: status
44 + }
45 + else
46 + _err ->
47 + response
48 + end
49 + end
50 +
51 + def get do
52 + %Request{
53 + module: __MODULE__,
54 + url: "account.json",
55 + method: :get
56 + }
57 + end
58 +
59 + def get(api_key) do
60 + get()
61 + |> Request.add_param(:api_key, api_key)
62 + end
63 + end
  @@ -1,100 +0,0 @@
1 - defmodule FigureEight.Endpoint do
2 - use GenServer
3 -
4 - require Logger
5 -
6 - alias FigureEight.Request
7 -
8 - defmodule State do
9 - @enforce_keys [:api_key]
10 - defstruct api_key: nil
11 - end
12 -
13 - def start_link(_args) do
14 - args = Application.get_all_env(:figure_eight)
15 - GenServer.start_link(__MODULE__, args, name: __MODULE__)
16 - end
17 -
18 - def init(_args) do
19 - Logger.info("Endpoint started")
20 - api_key = Application.get_env(:figure_eight, :api_key, "")
21 -
22 - cond do
23 - api_key == "" ->
24 - Logger.warn("Api Key not configured or empty")
25 - {:ok, %State{api_key: api_key}}
26 -
27 - is_bitstring(api_key) ->
28 - {:ok, %State{api_key: api_key}}
29 -
30 - true ->
31 - {:error, "No api key"}
32 - end
33 - end
34 -
35 - def call(%Request{} = req) do
36 - GenServer.call(__MODULE__, req, 10000)
37 - end
38 -
39 - def handle_call(%Request{paginated: true} = request, _from, state) do
40 - response =
41 - request
42 - |> Request.add_param(:key, state.api_key)
43 - |> pagination_loop
44 -
45 - {:reply, response, state}
46 - end
47 -
48 - def handle_call(%Request{} = request, _from, state) do
49 - response =
50 - request
51 - |> Request.add_param(:key, state.api_key)
52 - |> Request.eval()
53 - |> api_call()
54 -
55 - {:reply, response, state}
56 - end
57 -
58 - defp api_call(url) when not is_nil(url) do
59 - Logger.info("GET: " <> url)
60 -
61 - with {:ok, response} <- HTTPoison.get(url),
62 - {:ok, body} <- Map.fetch(response, :body),
63 - {:ok, result} <- Poison.decode(body) do
64 - {response.status_code, result}
65 - else
66 - :error ->
67 - {:error, "http response has no body"}
68 -
69 - {:error, %HTTPoison.Error{}} ->
70 - {:error, "http request failed"}
71 -
72 - _ ->
73 - {:error, "contained json could not be decoded"}
74 - end
75 - end
76 -
77 - defp api_call(_request), do: raise("Not implemented")
78 -
79 - defp pagination_loop(request, acc \\ %{}) do
80 - request
81 - |> Request.eval()
82 - |> api_call()
83 - |> case do
84 - {200, response} ->
85 - unless Enum.empty?(response) do
86 - request
87 - |> Request.increment_page()
88 - |> pagination_loop(Map.merge(acc, response))
89 - else
90 - {200, acc}
91 - end
92 -
93 - {:error, _} = response ->
94 - response
95 -
96 - {code, response} ->
97 - {code, Map.merge(acc, response)}
98 - end
99 - end
100 - end
  @@ -1,16 +0,0 @@
1 - defmodule FigureEight.Entity do
2 - @callback cast(response :: map()) :: struct() | map()
3 - @callback request(conditions :: map()) :: FigureEight.Request.t()
4 -
5 - def cast(response), do: response
6 -
7 - def from_iso8601(nil), do: nil
8 -
9 - def from_iso8601(iso_string) when is_bitstring(iso_string) do
10 - DateTime.from_iso8601(iso_string)
11 - |> case do
12 - {:ok, datetime, _offset} -> datetime
13 - _ -> iso_string
14 - end
15 - end
16 - end
Loading more files…