Initial commit

This commit is contained in:
2020-06-07 17:00:56 +03:00
commit f3b057a7be
32 changed files with 1096 additions and 0 deletions

22
lib/translator/base.ex Normal file
View File

@@ -0,0 +1,22 @@
defmodule Localizator.Translator.Base do
@typedoc """
Plain Text
"""
@type text :: String.t()
@typedoc """
Locale
"""
@type locale :: String.t()
@type from :: locale
@type to :: locale
@typedoc """
Error Message
"""
@type message :: String.t()
@callback detect(text) :: {:ok, locale} | {:error, message}
@callback translate(text, to) :: {:ok, text} | {:error, message}
@callback translate(text, to, from) :: {:ok, text} | {:error, message}
end

View File

@@ -0,0 +1,31 @@
defmodule Localizator.Translator.Direction do
alias Localizator.Commons
defstruct [:from, :to]
@typedoc """
Locale
"""
@type locale :: String.t() | Atom.t()
@type from :: locale
@type from_may_be_nil :: from | nil
@type to :: locale
@type direction :: {from, to} | to | %{from: from, to: to} | %{to: to}
@type direction_struct :: %{to: to, from: from_may_be_nil}
@spec get(direction) :: direction_struct
def get(direction) do
direction_map =
case direction do
[from: from, to: to] -> %{to: "#{to}", from: "#{from}"}
[from, to] -> %{to: "#{to}", from: "#{from}"}
{from, to} -> %{to: "#{to}", from: "#{from}"}
%{from: from, to: to} -> %{to: "#{to}", from: "#{from}"}
%{to: to} -> %{to: "#{to}", from: nil}
[to: to] -> %{to: "#{to}", from: nil}
to -> %{to: "#{to}", from: nil}
end
Commons.struct_from_map(direction_map, as: %__MODULE__{})
end
end

View File

@@ -0,0 +1,47 @@
defmodule Localizator.Translator do
alias Localizator.Translator.Direction
@typedoc """
Locale
"""
@type locale :: String.t()
@type from :: locale
@type from_may_be_nil :: from | nil
@type to :: locale
@type direction :: {from, to} | to | %{from: from, to: to} | %{to: to}
@type direction_map :: %{to: to, from: from_may_be_nil}
@typedoc """
Translation service
"""
@type translator :: Atom.t()
@typedoc """
Translation services list
"""
@type translators :: [translator]
@typedoc """
Translation resource
"""
@type resource :: String.t() | Map.t() | List.t()
@type source :: resource
@type result :: resource
@typedoc """
Error Message
"""
@type message :: String.t()
@spec list() :: translators
def list(), do: Application.get_env(:localizator, :translators)
@spec default() :: translator
def default(), do: list() |> List.first()
@spec translate(source, direction, translator) :: {:ok, result} | {:error, message}
def translate(source, direction, translator \\ default()) do
map = Direction.get(direction)
translator.translate(source, map.to, map.from)
end
end

40
lib/translator/yandex.ex Normal file
View File

@@ -0,0 +1,40 @@
defmodule Localizator.Translator.Yandex do
@type text :: String.t()
@type locale :: String.t()
@type from :: locale
@type to :: locale
@type message :: String.t()
@behaviour Localizator.Translator.Base
@impl true
@spec detect(text) :: {:ok, locale} | {:error, message}
def detect(text) when is_bitstring(text) do
case YandexTranslate.detect(text) do
%{languageCode: locale} -> {:ok, locale}
%{} -> {:error, "Couldn't detect language"}
end
end
@impl true
@spec translate(text, to) :: {:ok, text} | {:error, message}
def translate(text, to, from \\ nil)
def translate(text, to, from) when is_bitstring(text) and is_bitstring(to) do
translator_response =
case from do
nil -> YandexTranslate.translate(text, to)
_ -> YandexTranslate.translate(text, to, from)
end
case translator_response do
%{translations: translations} ->
translations
|> List.first()
|> Map.fetch(:text)
%{message: message} ->
{:error, message}
end
end
end