Files
phoenix-ausblick/lib/outlook/translators.ex
2023-02-11 20:12:03 +01:00

106 lines
2.9 KiB
Elixir

defmodule Outlook.Translators do
@moduledoc """
The Translators context.
"""
import Ecto.Query, warn: false
alias Outlook.Repo
alias Outlook.InternalTree.TranslationUnit
alias Outlook.Translators.{DeeplAccount,Deepl}
alias OutlookWeb.HtmlDocComponent
def list_deepl_accounts do
Repo.all(DeeplAccount)
end
def get_deepl_account!(id), do: Repo.get!(DeeplAccount, id)
def get_deepl_auth_key(user) do
deepl_account_for_user(user)
|> select([:auth_key])
|> Repo.one()
|> Map.get(:auth_key)
end
def create_deepl_account(attrs \\ %{}) do
%DeeplAccount{}
|> DeeplAccount.changeset(attrs)
|> Repo.insert()
end
def update_deepl_account(%DeeplAccount{} = deepl_account, attrs) do
deepl_account
|> DeeplAccount.changeset(attrs)
|> Repo.update()
end
def delete_deepl_account(%DeeplAccount{} = deepl_account) do
Repo.delete(deepl_account)
end
def change_deepl_account(%DeeplAccount{} = deepl_account, attrs \\ %{}) do
DeeplAccount.changeset(deepl_account, attrs)
end
def increase_our_character_count(user, billed_characters) do
deepl_account_for_user(user)
|> Repo.update_all([inc: [our_character_count: billed_characters]])
end
def translate(translation, current_user) do
%{language: target_lang,
article: %{content: article_tree, language: source_lang}
} = translation
article_as_html = prepare_article(article_tree)
auth_key = get_deepl_auth_key(current_user.id)
args = [
self(),
article_as_html,
%{
source_lang: source_lang,
target_lang: target_lang,
auth_key: auth_key
}
]
Task.start_link(Deepl, :translate, args)
end
def process_translation_result(result, tunit_ids, current_user) do
increase_our_character_count(current_user, result.billed_characters)
process_translation(result.translation, tunit_ids)
end
defp deepl_account_for_user(user) when is_struct(user), do: deepl_account_for_user(user.id)
defp deepl_account_for_user(user_id) do
DeeplAccount |> where(user_id: ^user_id)
end
defp prepare_article(tree) do
# Logger.info "so far."
HtmlDocComponent.render_doc(%{tree: tree, tunit_tag: "tunit"})
|> Phoenix.HTML.Safe.to_iodata()
|> IO.iodata_to_binary()
end
def process_translation(translation, tunit_ids) do
tunit_map = translation
|> Floki.parse_fragment!
|> Floki.find("tunit")
|> Enum.map(fn {_,atts,cont} ->
%TranslationUnit{
nid: Enum.find(atts, fn {k,_} -> k == "nid" end) |> Tuple.to_list |> Enum.at(1),
content: Floki.raw_html(cont),
status: :untranslated
}
end)
|> Enum.map(fn tunit -> {tunit.nid, tunit} end)
|> Enum.into(%{})
case Enum.sort(Map.keys(tunit_map)) == Enum.sort(tunit_ids) do
true -> {:ok, tunit_map}
false -> {:error, "keys don't equal the originals"}
end
end
end