Compare commits

...

7 Commits

Author SHA1 Message Date
1be39abeaf 0.1.5 2020-06-30 07:48:19 +03:00
3dbef08a74 0.1.4 2020-06-30 07:31:04 +03:00
bac33b304e Attempts 2020-06-30 07:30:23 +03:00
9c24e1651b Simple error processing 2020-06-29 05:00:31 +03:00
7ddac90b29 Using Mojito instead Mint 2020-06-25 04:41:56 +03:00
305e8f29c9 0.1.1 2020-06-25 04:09:27 +03:00
d7822675a3 Doc fix 2020-06-19 10:55:41 +03:00
5 changed files with 49 additions and 70 deletions

View File

@ -12,7 +12,7 @@ by adding `microsoft_translator` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:microsoft_translator, "~> 0.1.0"}
{:microsoft_translator, "~> 0.1.5"}
]
end
```

View File

@ -1,6 +1,6 @@
defmodule MicrosoftTranslator do
@moduledoc """
Basic functions for requests to Yandex Translate API on Yandex Cloud
Basic functions for requests to Microsoft Translator API on Microsoft Azure
"""
alias MicrosoftTranslator.Client
@ -11,6 +11,7 @@ defmodule MicrosoftTranslator do
Return a map with language code (use it for translations) and native language name
```elixir
MicrosoftTranslator.detect()
%{
languages: [
%{code: "af", "name":"Afrikaans","nativeName":"Afrikaans"},
@ -32,7 +33,6 @@ defmodule MicrosoftTranslator do
```elixir
MicrosoftTranslator.detect("Криївка")
# Response
%{languageCode: "uk"}
```
@ -43,7 +43,6 @@ defmodule MicrosoftTranslator do
```elixir
MicrosoftTranslator.detect(%{text: "Капелюх"})
# Response
%{languageCode: "uk"}
```
"""

View File

@ -1,18 +1,18 @@
defmodule MicrosoftTranslator.Client do
@empty_state %{data: [], done: false}
@attempt_delay 3_000
@base_host "api.cognitive.microsofttranslator.com"
@base_path "/"
@api_methods %{
languages: %{
method: "GET",
method: :get,
path: "languages"
},
detect: %{
method: "POST",
method: :post,
path: "detect"
},
translate: %{
method: "POST",
method: :post,
path: "translate"
}
}
@ -68,83 +68,63 @@ defmodule MicrosoftTranslator.Client do
defp transform_body(_, params), do: params
defp parse({:ok, %{data: body}}, api_method) do
defp parse(%{body: body}, api_method) do
Jason.decode!(body, keys: :atoms)
|> transform_response(api_method)
|> process_response(api_method)
end
defp transform_response(response, :detect) do
result =
response
|> List.first()
|> Map.fetch(:language)
defp parse(%Mojito.Error{reason: :timeout}, api_method) do
%{error: %{code: :timeout, message: "timeout"}}
|> process_response(api_method)
end
case result do
defp process_response(response, api_method) do
case response do
%{error: %{code: code, message: message}} ->
%{error: %{code: code, message: message}}
list when is_list(list) and api_method in ~w(detect translate)a ->
list
|> List.first()
|> transform_response(api_method)
map when is_map(map) and api_method in ~w(languages)a ->
transform_response(map, api_method)
end
end
defp transform_response(response, :detect) when is_map(response) do
case Map.fetch(response, :language) do
{:ok, language} -> %{languageCode: language}
end
end
defp transform_response(response, :translate) do
result =
response
|> List.first()
|> Map.take([:translations])
end
defp transform_response(response, :languages) do
%{dictionary: dictionary} = response
defp transform_response(response, :translate) when is_map(response),
do: Map.take(response, ~w(translations)a)
defp transform_response(%{dictionary: dictionary}, :languages) do
dictionary
|> Enum.map(fn {key, %{name: name, nativeName: native, dir: dir}} ->
%{code: "#{key}", name: name, nativeName: native, dir: dir}
end)
end
def fetch(api_method, headers, body, params) do
def fetch(api_method, headers, body, params, attempt \\ 0) do
method = @api_methods[api_method].method
path = @base_path <> @api_methods[api_method].path <> params
url = "https://#{@base_host}#{@base_path}#{@api_methods[api_method].path}#{params}"
with {:ok, conn} <- Mint.HTTP.connect(:https, @base_host, 443),
{:ok, conn, _ref} <- Mint.HTTP.request(conn, method, path, headers, body) do
handle_response(conn, @empty_state)
end
end
case Mojito.request(method, url, headers, body) do
{:ok, response} ->
response
defp handle_response(conn, state) do
receive do
message ->
case Mint.HTTP.stream(conn, message) do
{:ok, conn, responses} ->
case Enum.reduce(responses, state, &handle_res/2) do
# Loop ends here
%{done: true} = state -> {:ok, state}
%{done: false} = state -> handle_response(conn, state)
end
{:error, _, reason, _} ->
{:error, reason}
:unknown ->
exit({:unexpected, message})
{:error, %Mojito.Error{reason: :timeout} = response} ->
if attempt < 2 do
:timer.sleep(@attempt_delay)
IO.inspect(url, label: "Attempt #{attempt + 1}")
fetch(api_method, headers, body, params, attempt + 1)
else
response
end
end
end
defp handle_res({:status, _, status}, state),
do: Map.put(state, :status, status)
defp handle_res({:headers, _, headers}, state),
do: Map.put(state, :headers, headers)
defp handle_res({:data, _, data}, state),
do: Map.update!(state, :data, fn acc -> [data | acc] end)
defp handle_res({:done, _}, state) do
Map.update!(state, :data, fn acc ->
acc
|> Enum.reverse()
|> Enum.join("")
end)
|> Map.put(:done, true)
end
end

View File

@ -2,7 +2,7 @@ defmodule MicrosoftTranslator.MixProject do
use Mix.Project
@name "MicrosoftTranslator"
@version "0.1.0"
@version "0.1.5"
# @repo_url "https://github.com/negrienko/microsoft_translator"
@repo_url "https://gl.negrienko.com/negrienko/microsoft_translator"
@homepage_url "https://negrienko.com/all/microsoft-translator/"
@ -46,7 +46,7 @@ defmodule MicrosoftTranslator.MixProject do
{:joken, "~> 2.2.0"},
{:jose, "~> 1.10.1"},
{:jason, "~> 1.2.0"},
{:mint, "~> 1.1.0"},
{:mojito, "~> 0.7.3"},
{:castore, "~> 0.1.6"},
{:ex_spec, "~> 2.0.1", only: :test},
{:ex_doc, "~> 0.21.3", only: :dev},

View File

@ -16,12 +16,12 @@
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
"mint": {:hex, :mint, "1.1.0", "1fd0189edd9e3ffdbd7fcd8bc3835902b987a63ec6c4fd1aa8c2a56e2165f252", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bfd316c3789340b682d5679a8116bcf2112e332447bdc20c1d62909ee45f48d"},
"mojito": {:hex, :mojito, "0.3.0", "806cd3c1832333a9ee784e7ea2799863fbe4de55ecb4623a8f4ef870c2844cc6", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 0.2.1", [hex: :mint, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm"},
"mojito": {:hex, :mojito, "0.7.3", "7356f3b7697d79520a243b48cf0bf8bd1152b2e9cdb6ff7cf22cd0769f32dd40", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "433479d8ef1c882fafe864ac6d7b08249f321fc46bdcc8db78691bc1ddcf234a"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
"ojson": {:hex, :ojson, "1.0.0", "fd28614eadaec00a15cdb2f53f29d8717a812a508ddb80d202f2f2e2aaeabbcc", [:mix, :rebar3], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"remix": {:hex, :remix, "0.0.2", "f06115659d8ede8d725fae1708920ef73353a1b39efe6a232d2a38b1f2902109", [:mix], [], "hexpm", "5f5555646ed4fca83fab8620735150aa0bc408c5a17a70d28cfa7086bc6f497c"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},