Packages

Translate strings using the Bing HTTP API. Requires that you have a Client ID and Secret. See README.md for information.

Current section

Files

Jump to
bing_translator lib bing_translator translator.ex
Raw

lib/bing_translator/translator.ex

defmodule BingTranslator.Translator do
use Timex
use HTTPoison.Base
@access_token_uri "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13"
@speak_uri "http://api.microsofttranslator.com/v2/Http.svc/Speak"
@detect_uri "http://api.microsofttranslator.com/V2/Http.svc/Detect"
@translate_uri "http://api.microsofttranslator.com/V2/Http.svc/Translate"
@translate_array_uri "http://api.microsofttranslator.com/V2/Http.svc/TranslateArray"
@lang_code_list_uri "http://api.microsofttranslator.com/V2/Http.svc/GetLanguagesForTranslate"
def translate(text, options \\ []) do
params = %{
text: text,
to: options[:to],
from: options[:from],
category: "general",
contentType: "text/plain"
}
result(@translate_uri, params).body
|> Floki.find("string") |> Floki.text
end
def detect(text) do
params = %{
text: text,
category: "general",
contentType: "text/plain"
}
result(@detect_uri, params).body
|> Floki.find("string") |> Floki.text
end
# format: "audio/wav" [default] or "audio/mp3"
# language: valid translator language code
# options: "MinSize" [default] or "MaxQuality"
def speak(text, options \\ []) do
params = %{
text: text,
format: options[:format],
language: options[:language]
}
result(@speak_uri, params, %{"Content-Type" => options[:format]}).body
end
def supported_language_codes do
result(@lang_code_list_uri, %{}).body
|> Floki.find("string") |> Enum.map(fn(lang) -> Floki.text(lang) end)
end
def get_access_token! do
config = BingTranslator.Config.get
token = config.token
case token && token[:access_token] && Time.now(:secs) < token[:expires_in] do
true ->
token
_ ->
body = {:form, [
client_id: config.client_id,
client_secret: config.client_secret,
scope: "http://api.microsofttranslator.com",
grant_type: "client_credentials"
]
}
token =
post!(@access_token_uri, body)
|> parse_token
BingTranslator.Config.set_token(token)
token
end
end
defp parse_token(response) do
response.body
|> Poison.decode!
|> Enum.filter(fn{k, _} ->
k in ["expires_in", "access_token"]
end)
|> Enum.map(fn{k, v} ->
value =
case k do
"expires_in" ->
Time.now(:secs) + String.to_integer(v)
_ ->
v
end
{String.to_atom(k), value}
end)
end
defp result(url, params, headers \\ []) do
auth = "Bearer #{get_access_token![:access_token]}"
headers =
headers
|> Enum.into(%{})
|> Map.merge(%{"Authorization" => auth})
get!("#{url}?#{URI.encode_query(params)}", headers)
end
end