Current section
Files
Jump to
Current section
Files
lib/mix/tasks/getatrex.ex
defmodule Mix.Tasks.Getatrex do
@moduledoc """
Runs locale translation routine
"""
use Mix.Task
@shortdoc "Translates gettext locale with Google Cloud Translate API"
@doc """
Runs the routine
1. Check whether target locale exists, files errors.po, default.po
2. Start reading `default.po` in the stream
3. Collect translation groups by comments(location in templates) + msgid line(original) + msgstr line(translated)
4. When translation group is collected - translate and save to msgstr line
5. When translation is done - write group to disk
6. When translation failed - write not translated group to disk (to re-run this later)
7. All read/write are sync (to respect the order)
8.
"""
def run([to_lang | tail]) when not is_nil(to_lang) do
if String.starts_with?(to_lang, "-") do
run()
else
{opts, _positional, _} =
OptionParser.parse(tail,
switches: [domain: :keep],
aliases: [d: :domain]
)
domains = normalize_domains(Keyword.get_values(opts, :domain))
Enum.each(domains, fn domain ->
# checking whether local exists and run if file exists
to_lang
|> locale_path_po(domain)
|> File.exists?()
|> run_with_file(to_lang, domain)
end)
end
end
def run(_), do: run()
def run_with_file(file_exists, to_lang, domain) when file_exists == false or file_exists == nil do
Mix.shell.info "Warning!"
Mix.shell.info "Locale filename #{locale_path_po(to_lang, domain)} does not exists."
Mix.shell.info "Please create '#{to_lang}' locale with gettext first:"
Mix.shell.info "Follow the instructions:"
Mix.shell.info ""
Mix.shell.info "$ mix gettext.extract"
Mix.shell.info "$ mix gettext.merge priv/gettext"
Mix.shell.info "$ mix gettext.merge priv/gettext --locale #{to_lang}"
Mix.shell.info ""
Mix.shell.info "More info here: https://github.com/elixir-lang/gettext#workflow"
end
def run_with_file(true, to_lang, domain) do
Mix.shell.info "Starting translation gettext locale #{to_lang} (#{domain}.po)"
source_path = locale_path_po(to_lang, domain)
target_path = translated_locale_path_po(to_lang, domain)
case Getatrex.PO.translate_file(source_path, target_path, to_lang) do
{:ok, stats} ->
Mix.shell.info(
"Done! Translated #{stats.translated} message(s), skipped #{stats.skipped}, cached #{stats.cached}, errors #{stats.errors}."
)
{:error, reason} ->
Mix.raise("Translation failed: #{inspect(reason)}")
end
end
def run do
Mix.shell.info "Call this task in the following way:"
Mix.shell.info ""
Mix.shell.info "\t$ mix getatrex es"
Mix.shell.info "\t$ mix getatrex es --domain errors"
Mix.shell.info "\t$ mix getatrex es --domain default --domain errors"
Mix.shell.info ""
Mix.shell.info "where `es` - target language (should be created by gettext before getatrex)"
Mix.shell.info ""
Mix.shell.info "Please read README.md https://github.com/alexfilatov/getatrex#getting-started"
end
@doc """
Returns path to the locale generated by gettext
"""
def locale_path_default_po(to_lang) do
locale_path_po(to_lang, "default")
end
@doc """
Returns path for translated locale
"""
def translated_locale_path_default_po(to_lang) do
translated_locale_path_po(to_lang, "default")
end
def locale_path_po(to_lang, domain) do
"./priv/gettext/#{to_lang}/LC_MESSAGES/#{domain}.po"
end
def translated_locale_path_po(to_lang, domain) do
"./priv/gettext/#{to_lang}/LC_MESSAGES/translated_#{domain}.po"
end
defp normalize_domains(nil), do: ["default"]
defp normalize_domains(domains) do
domains
|> List.wrap()
|> Enum.flat_map(&String.split(&1, ",", trim: true))
|> Enum.map(&String.trim/1)
|> Enum.reject(&(&1 == ""))
|> Enum.uniq()
|> case do
[] -> ["default"]
list -> list
end
end
end