class ZendeskAppsTools::Translate

Constants

LOCALE_BASE_ENDPOINT
LOCALE_ENDPOINT

Public Class Methods

source_root() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 73
def self.source_root
  File.expand_path(File.join(File.dirname(__FILE__), '../..'))
end

Public Instance Methods

array_to_nested_hash(array) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 142
def array_to_nested_hash(array)
  array.each_with_object({}) do |item, result|
    keys = item['key'].split('.')
    current = result
    keys[0..-2].each do |key|
      current = (current[key] ||= {})
    end
    current[keys[-1]] = { 'title' => item['title'], 'value' => item['value'] }
    result
  end
end
build_pseudotranslation(translations_hash, package_name) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 154
def build_pseudotranslation(translations_hash, package_name)
  titles       = to_flattened_namespaced_hash(translations_hash, :title)
  values       = to_flattened_namespaced_hash(translations_hash, :value)
  translations = titles.each { |k, v| titles[k] = { 'title' => v, 'value' => "[日本#{values[k]}éñđ]" } }
  translations['app.package'] = package_name # don't pseudo translate the package name
  nest_translations_hash(translations, '')
end
en_hash() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 212
def en_hash
  @en_hash ||= begin
    return nil unless en_yaml
    package = /^txt.apps.([^\.]+)/.match(en_yaml['parts'][0]['translation']['key'])[1]
    translations = en_yaml['parts'].map { |part| part['translation'] }
    translations.select! do |translation|
      obsolete = translation['obsolete']
      next true unless obsolete
      Date.parse(obsolete.to_s) > Date.today
    end
    en_hash = array_to_nested_hash(translations)['txt']['apps'][package]
    en_hash['app']['package'] = package
    en_hash
  end
end
en_json() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 197
def en_json
  @en_json ||= begin
    path = "#{destination_root}/translations/en.json"
    JSON.parse(File.open(path).read) if File.exist? path
  end
end
en_yaml() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 204
def en_yaml
  @en_yaml ||= begin
    path = "#{destination_root}/translations/en.yml"
    require 'yaml'
    YAML.load_file(path) if File.exist? path
  end
end
escape_special_characters(v) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 125
def escape_special_characters(v)
  v.gsub('"', '\"')
end
fetch_locale_async(locale, app_package) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 78
def fetch_locale_async(locale, app_package)
  Thread.new do
    say("Fetching #{locale['locale']}")
    json = Faraday.get("#{locale['url']}?include=translations&packages=app_#{app_package}").body
    json_or_die(json)['locale']
  end
end
locale_list() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 162
def locale_list
  say('Fetching translations...')
  require 'net/http'
  require 'faraday'

  if options[:locales]
    content = read_file(options[:locales])
    locales = JSON.parse(content)
    return locales.map do |locale|
      { 'locale' => locale, 'url' => "#{LOCALE_BASE_ENDPOINT}/#{locale}.json" }
    end
  end

  locale_response = Faraday.get(LOCALE_ENDPOINT)

  return json_or_die(locale_response.body)['locales'] if locale_response.status == 200
  if locale_response.status == 401
    say_error_and_exit 'Authentication failed.'
  else
    say_error_and_exit "Failed to download locales, got HTTP status #{locale_response.status}."
  end
end
nest_translations_hash(translations_hash, key_prefix) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 94
def nest_translations_hash(translations_hash, key_prefix)
  result = {}

  translations_hash.each do |full_key, value|
    parts       = full_key.gsub(key_prefix, '').split('.')
    parts_count = parts.size - 1
    context     = result

    parts.each_with_index do |part, i|
      if parts_count == i
        context[part] = value
      else
        context = context[part] ||= {}
      end
    end
  end

  result
end
package_name(error_out: false) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 234
def package_name(error_out: false)
  package = en_hash && en_hash['app']['package']
  return package if package
  say_error_and_exit 'No package defined inside en.yml.' if error_out
end
package_name_for_update() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 189
def package_name_for_update
  options[:package_name] ||
    package_name(error_out: options[:unattended]) ||
    get_value_from_stdin('What is the package name for this app? (without leading app_)',
                         valid_regex: /^[a-z_]+$/,
                         error_msg: 'Invalid package name, try again:')
end
package_name_from_json(error_out: false) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 228
def package_name_from_json(error_out: false)
  package = en_json && en_json['app']['package']
  return package if package
  say_error_and_exit 'No package defined inside en.json.' if error_out
end
pseudotranslate() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 64
def pseudotranslate
  setup_path(options[:path]) if options[:path]

  package = package_name(error_out: true)

  pseudo = build_pseudotranslation(en_hash, package)
  write_json('translations/fr.json', pseudo)
end
read_file(path) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 185
def read_file(path)
  File.read(File.expand_path(path))
end
setup_path(path) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 86
def setup_path(path)
  @destination_stack << relative_to_original_destination_root(path) unless @destination_stack.last == path
end
to_flattened_namespaced_hash(hash, target_key) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 129
def to_flattened_namespaced_hash(hash, target_key)
  require 'zendesk_apps_support/build_translation'
  @includer_class ||= Class.new { include ZendeskAppsSupport::BuildTranslation }
  target_key_constant = case target_key
                        when :title
                          @includer_class::I18N_TITLE_KEY
                        when :value
                          @includer_class::I18N_VALUE_KEY
                        end
  (@includer ||= @includer_class.new)
    .to_flattened_namespaced_hash(hash, target_key_constant)
end
to_json() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 35
def to_json
  setup_path(options[:path]) if options[:path]
  write_json('translations/en.json', en_hash)
end
to_yml() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 18
def to_yml
  setup_path(options[:path]) if options[:path]
  manifest = JSON.parse(File.open("#{destination_root}/manifest.json").read)
  app_name = manifest['name']

  unless app_name
    app_name = get_value_from_stdin('What is the name of this app?', error_msg: 'Invalid name, try again:')
  end

  package = package_name_from_json(error_out: true)
  en_json['app'].delete('package')

  write_yml(en_json, app_name, package)
end
update() click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 44
def update
  setup_path(options[:path]) if options[:path]
  app_package = package_name_for_update
  locale_list
    .map { |locale| fetch_locale_async locale, app_package }
    .each do |locale_thread|
      locale = locale_thread.value
      translations = locale['translations']

      locale_name = ZendeskAppsTools::LocaleIdentifier.new(locale['locale']).locale_id
      write_json(
        "translations/#{locale_name}.json",
        nest_translations_hash(translations, "txt.apps.#{app_package}.")
      )
    end
  say('Translations updated', :green)
end
write_json(filename, translations_hash) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 90
def write_json(filename, translations_hash)
  create_file(filename, JSON.pretty_generate(translations_hash).force_encoding('ASCII-8BIT') + "\n", force: options[:unattended])
end
write_yml(en_json, app_name, package_name) click to toggle source
# File lib/zendesk_apps_tools/translate.rb, line 114
def write_yml(en_json, app_name, package_name)
  titles        = to_flattened_namespaced_hash(en_json, :title)
  values        = to_flattened_namespaced_hash(en_json, :value)
  @translations = titles.each do |k, v|
    titles[k] = { 'title' => v, 'value' => escape_special_characters(values[k]) }
  end
  @app_name     = app_name
  @package_name = package_name
  template(File.join(Translate.source_root, 'templates/translation.erb.tt'), 'translations/en.yml')
end