Current section
Files
Jump to
Current section
Files
lib/yandex_cloud/translate.ex
defmodule YandexCloud.Translate do
@moduledoc """
Client requests to Translate service
"""
@cloud_base_url "https://translate.api.cloud.yandex.net/translate/v1/"
@doc """
Get available languages for translation.
## Example
iex> YandexCloud.Translate.languages(%{iam_token: ""})
{:ok, %{"languages" => [%{"language" => "az"}, %{...}, ...]}}
### Options
iam_token - IAM-token, required
folder_id - folder ID of your account at YandexCloud, optional
"""
@spec languages(map()) :: {:ok, %{}}
def languages(%{} = options), do: call("languages", options)
@doc """
Detect language for text.
## Example
iex> YandexCloud.Translate.detect(%{iam_token: "", text: "Hello"})
{:ok, %{"language" => "en"}}
### Options
iam_token - IAM-token, required
folder_id - folder ID of your account at YandexCloud, otional]
text - text for detection, required
hint - list of possible languages, optional, example - "en,ru"
"""
@spec detect(map()) :: {:ok, %{}}
def detect(%{} = options), do: call("detect", options)
@doc """
Translate word or phrase.
## Example
iex> YandexCloud.Translate.translate(%{iam_token: iam_token, text: "hello world", source: "en", target: "es"})
{:ok, %{"translations" => [%{"text" => "hola mundo"}]}}
### Options
iam_token - IAM-token, required
folder_id - folder ID of your account at YandexCloud, optional
text - text for detection, required
source - source language, ISO 639-1 format (like "en"), optional
target - target language, ISO 639-1 format (like "ru"), required
format - text format, one of the [plain|html], default - plain, optional
"""
@spec translate(map()) :: {:ok, %{}}
def translate(%{} = options), do: call("translate", options)
# perform request
defp call(type, args) do
type
|> fetch(args)
|> parse()
end
# MAIN FUNCTIONS
# make request
defp fetch(type, args) do
case HTTPoison.post(@cloud_base_url <> type, body(args, type), headers(args[:iam_token])) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} -> {:ok, body}
{:ok, %HTTPoison.Response{body: body}} -> {:error, body}
{:error, %HTTPoison.Error{reason: reason}} -> {:error, reason}
end
end
# parse results
defp parse({result, response}), do: {result, Poison.Parser.parse!(response)}
# ADDITIONAL FUNCTIONS
# generate body for request
defp body(args, type) do
args
|> Map.merge(%{folderId: cloud_folder_id(args[:folder_id])})
|> Stream.filter(fn {key, _} -> Enum.member?(valid_args(type), key) end)
|> Stream.map(fn {key, value} -> "#{key}=#{URI.encode_www_form(value)}" end)
|> Enum.join("&")
#args
#|> Keyword.put(:folderId, cloud_folder_id(args[:folder_id]))
#|> Stream.filter(fn {key, _} -> Enum.member?(valid_args(type), key) end)
#|> Stream.map(fn {key, value} -> "#{key}=#{URI.encode_www_form(value)}" end)
#|> Enum.join("&")
end
# list with available options based on request type
defp valid_args(type) do
case type do
"languages" -> [:folderId]
"detect" -> [:folderId, :text, :hint]
"translate" -> [:folderId, :text, :source, :target, :format]
_ -> []
end
end
defp cloud_folder_id(nil), do: Application.get_env(:yandex_cloud, :translate_folder_id) || ""
defp cloud_folder_id(folder_id), do: folder_id
# define headers for request
defp headers(iam_token), do: [{"Content-Type", "application/x-www-form-urlencoded"}, {"Authorization", "Bearer #{iam_token}"}]
end