Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
1be39abeaf | |||
3dbef08a74 | |||
bac33b304e | |||
9c24e1651b | |||
7ddac90b29 | |||
305e8f29c9 | |||
d7822675a3 |
@ -12,7 +12,7 @@ by adding `microsoft_translator` to your list of dependencies in `mix.exs`:
|
|||||||
```elixir
|
```elixir
|
||||||
def deps do
|
def deps do
|
||||||
[
|
[
|
||||||
{:microsoft_translator, "~> 0.1.0"}
|
{:microsoft_translator, "~> 0.1.5"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
defmodule MicrosoftTranslator do
|
defmodule MicrosoftTranslator do
|
||||||
@moduledoc """
|
@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
|
alias MicrosoftTranslator.Client
|
||||||
@ -11,6 +11,7 @@ defmodule MicrosoftTranslator do
|
|||||||
Return a map with language code (use it for translations) and native language name
|
Return a map with language code (use it for translations) and native language name
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
MicrosoftTranslator.detect()
|
||||||
%{
|
%{
|
||||||
languages: [
|
languages: [
|
||||||
%{code: "af", "name":"Afrikaans","nativeName":"Afrikaans"},
|
%{code: "af", "name":"Afrikaans","nativeName":"Afrikaans"},
|
||||||
@ -32,7 +33,6 @@ defmodule MicrosoftTranslator do
|
|||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
MicrosoftTranslator.detect("Криївка")
|
MicrosoftTranslator.detect("Криївка")
|
||||||
# Response
|
|
||||||
%{languageCode: "uk"}
|
%{languageCode: "uk"}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -43,7 +43,6 @@ defmodule MicrosoftTranslator do
|
|||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
MicrosoftTranslator.detect(%{text: "Капелюх"})
|
MicrosoftTranslator.detect(%{text: "Капелюх"})
|
||||||
# Response
|
|
||||||
%{languageCode: "uk"}
|
%{languageCode: "uk"}
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
defmodule MicrosoftTranslator.Client do
|
defmodule MicrosoftTranslator.Client do
|
||||||
@empty_state %{data: [], done: false}
|
@attempt_delay 3_000
|
||||||
@base_host "api.cognitive.microsofttranslator.com"
|
@base_host "api.cognitive.microsofttranslator.com"
|
||||||
@base_path "/"
|
@base_path "/"
|
||||||
@api_methods %{
|
@api_methods %{
|
||||||
languages: %{
|
languages: %{
|
||||||
method: "GET",
|
method: :get,
|
||||||
path: "languages"
|
path: "languages"
|
||||||
},
|
},
|
||||||
detect: %{
|
detect: %{
|
||||||
method: "POST",
|
method: :post,
|
||||||
path: "detect"
|
path: "detect"
|
||||||
},
|
},
|
||||||
translate: %{
|
translate: %{
|
||||||
method: "POST",
|
method: :post,
|
||||||
path: "translate"
|
path: "translate"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,83 +68,63 @@ defmodule MicrosoftTranslator.Client do
|
|||||||
|
|
||||||
defp transform_body(_, params), do: params
|
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)
|
Jason.decode!(body, keys: :atoms)
|
||||||
|> transform_response(api_method)
|
|> process_response(api_method)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp transform_response(response, :detect) do
|
defp parse(%Mojito.Error{reason: :timeout}, api_method) do
|
||||||
result =
|
%{error: %{code: :timeout, message: "timeout"}}
|
||||||
response
|
|> process_response(api_method)
|
||||||
|> List.first()
|
end
|
||||||
|> Map.fetch(:language)
|
|
||||||
|
|
||||||
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}
|
{:ok, language} -> %{languageCode: language}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp transform_response(response, :translate) do
|
defp transform_response(response, :translate) when is_map(response),
|
||||||
result =
|
do: Map.take(response, ~w(translations)a)
|
||||||
response
|
|
||||||
|> List.first()
|
|
||||||
|> Map.take([:translations])
|
|
||||||
end
|
|
||||||
|
|
||||||
defp transform_response(response, :languages) do
|
|
||||||
%{dictionary: dictionary} = response
|
|
||||||
|
|
||||||
|
defp transform_response(%{dictionary: dictionary}, :languages) do
|
||||||
dictionary
|
dictionary
|
||||||
|> Enum.map(fn {key, %{name: name, nativeName: native, dir: dir}} ->
|
|> Enum.map(fn {key, %{name: name, nativeName: native, dir: dir}} ->
|
||||||
%{code: "#{key}", name: name, nativeName: native, dir: dir}
|
%{code: "#{key}", name: name, nativeName: native, dir: dir}
|
||||||
end)
|
end)
|
||||||
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
|
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),
|
case Mojito.request(method, url, headers, body) do
|
||||||
{:ok, conn, _ref} <- Mint.HTTP.request(conn, method, path, headers, body) do
|
{:ok, response} ->
|
||||||
handle_response(conn, @empty_state)
|
response
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp handle_response(conn, state) do
|
{:error, %Mojito.Error{reason: :timeout} = response} ->
|
||||||
receive do
|
if attempt < 2 do
|
||||||
message ->
|
:timer.sleep(@attempt_delay)
|
||||||
case Mint.HTTP.stream(conn, message) do
|
IO.inspect(url, label: "Attempt #{attempt + 1}")
|
||||||
{:ok, conn, responses} ->
|
fetch(api_method, headers, body, params, attempt + 1)
|
||||||
case Enum.reduce(responses, state, &handle_res/2) do
|
else
|
||||||
# Loop ends here
|
response
|
||||||
%{done: true} = state -> {:ok, state}
|
|
||||||
%{done: false} = state -> handle_response(conn, state)
|
|
||||||
end
|
|
||||||
|
|
||||||
{:error, _, reason, _} ->
|
|
||||||
{:error, reason}
|
|
||||||
|
|
||||||
:unknown ->
|
|
||||||
exit({:unexpected, message})
|
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
4
mix.exs
4
mix.exs
@ -2,7 +2,7 @@ defmodule MicrosoftTranslator.MixProject do
|
|||||||
use Mix.Project
|
use Mix.Project
|
||||||
|
|
||||||
@name "MicrosoftTranslator"
|
@name "MicrosoftTranslator"
|
||||||
@version "0.1.0"
|
@version "0.1.5"
|
||||||
# @repo_url "https://github.com/negrienko/microsoft_translator"
|
# @repo_url "https://github.com/negrienko/microsoft_translator"
|
||||||
@repo_url "https://gl.negrienko.com/negrienko/microsoft_translator"
|
@repo_url "https://gl.negrienko.com/negrienko/microsoft_translator"
|
||||||
@homepage_url "https://negrienko.com/all/microsoft-translator/"
|
@homepage_url "https://negrienko.com/all/microsoft-translator/"
|
||||||
@ -46,7 +46,7 @@ defmodule MicrosoftTranslator.MixProject do
|
|||||||
{:joken, "~> 2.2.0"},
|
{:joken, "~> 2.2.0"},
|
||||||
{:jose, "~> 1.10.1"},
|
{:jose, "~> 1.10.1"},
|
||||||
{:jason, "~> 1.2.0"},
|
{:jason, "~> 1.2.0"},
|
||||||
{:mint, "~> 1.1.0"},
|
{:mojito, "~> 0.7.3"},
|
||||||
{:castore, "~> 0.1.6"},
|
{:castore, "~> 0.1.6"},
|
||||||
{:ex_spec, "~> 2.0.1", only: :test},
|
{:ex_spec, "~> 2.0.1", only: :test},
|
||||||
{:ex_doc, "~> 0.21.3", only: :dev},
|
{:ex_doc, "~> 0.21.3", only: :dev},
|
||||||
|
4
mix.lock
4
mix.lock
@ -16,12 +16,12 @@
|
|||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [: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"},
|
"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"},
|
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
|
||||||
"ojson": {:hex, :ojson, "1.0.0", "fd28614eadaec00a15cdb2f53f29d8717a812a508ddb80d202f2f2e2aaeabbcc", [:mix, :rebar3], [], "hexpm"},
|
"ojson": {:hex, :ojson, "1.0.0", "fd28614eadaec00a15cdb2f53f29d8717a812a508ddb80d202f2f2e2aaeabbcc", [:mix, :rebar3], [], "hexpm"},
|
||||||
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
|
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
|
||||||
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "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"},
|
"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"},
|
"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"},
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user