translation 0.1 → 0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +50 -0
- data/lib/translation.rb +75 -0
- data/lib/translation/client.rb +27 -0
- data/lib/translation/client/base_operation.rb +49 -0
- data/lib/translation/client/base_operation/create_new_mo_files_step.rb +22 -0
- data/lib/translation/client/base_operation/dump_haml_gettext_keys_step.rb +44 -0
- data/lib/translation/client/base_operation/dump_slim_gettext_keys_step.rb +43 -0
- data/lib/translation/client/base_operation/save_new_po_files_step.rb +31 -0
- data/lib/translation/client/base_operation/save_new_yaml_files_step.rb +37 -0
- data/lib/translation/client/base_operation/save_special_yaml_files_step.rb +53 -0
- data/lib/translation/client/init_operation.rb +42 -0
- data/lib/translation/client/init_operation/cleanup_yaml_files_step.rb +52 -0
- data/lib/translation/client/init_operation/create_yaml_po_files_step.rb +53 -0
- data/lib/translation/client/init_operation/update_and_collect_po_files_step.rb +33 -0
- data/lib/translation/client/init_operation/update_pot_file_step.rb +18 -0
- data/lib/translation/client/purge_operation.rb +13 -0
- data/lib/translation/client/sync_operation.rb +41 -0
- data/lib/translation/client/sync_operation/create_yaml_pot_file_step.rb +46 -0
- data/lib/translation/client/sync_operation/update_and_collect_pot_file_step.rb +18 -0
- data/lib/translation/config.rb +20 -0
- data/lib/translation/controller.rb +18 -0
- data/lib/translation/flat_hash.rb +112 -0
- data/lib/translation/railtie.rb +37 -0
- data/lib/translation/tasks.rb +31 -0
- data/lib/translation/yaml_conversion.rb +81 -0
- metadata +104 -11
- data/README.rdoc +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d9ba5b1f146ab9c345be6542b3c2b02a7645855
|
4
|
+
data.tar.gz: ecb4386329547f2b0894146b69374c650f2dcd10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f1af0d393bee32f48cd04b5a453436d7e353e83ca0c26fcbb7133997301a9f296b31305c3a2d76600b9ce909c87b3076a5ab25aa8c88ad5706122a69a9f8240
|
7
|
+
data.tar.gz: 952f4b1cbf1bdbe7083d8997aaad7f41b25bd9865bbb1cb76d02e96ec8d14dcef74206803224f1cc7b1efd2cfee55c24d56cd8553c4b8dbf9cda1259ff1996b8
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# gem for [Rails Translation](http://rails.translation.io)
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
Add this gem to your [Rails](http://rubyonrails.org) app to translate it with [Rails Translation](http://rails.translation.io).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add the gem to your project's Gemfile :
|
10
|
+
|
11
|
+
gem 'translation'
|
12
|
+
|
13
|
+
Then :
|
14
|
+
|
15
|
+
* Create a translation project from the UI.
|
16
|
+
* Copy the initializer into your Rails app (`config/initializers/translation.rb`)
|
17
|
+
|
18
|
+
And finish by inititalizing your translation project with :
|
19
|
+
|
20
|
+
bundle exec rake translation:init
|
21
|
+
|
22
|
+
## Synchronization
|
23
|
+
|
24
|
+
To get new translations from Rails Translation and to send new translatable strings, simply run :
|
25
|
+
|
26
|
+
bundle exec rake translation:sync
|
27
|
+
|
28
|
+
## Purge
|
29
|
+
|
30
|
+
If you need to remove unused keys taking the current branch as reference :
|
31
|
+
|
32
|
+
bundle exec rake translation:purge
|
33
|
+
|
34
|
+
Note that this operation will also perform a sync at the same time.
|
35
|
+
|
36
|
+
Warning : all keys that are not present in the current branch will be **permanently deleted both on Rails Translation and in your app**.
|
37
|
+
|
38
|
+
## Tests
|
39
|
+
|
40
|
+
To run the specs :
|
41
|
+
|
42
|
+
bundle
|
43
|
+
bundle exec rspec
|
44
|
+
|
45
|
+
## Credits
|
46
|
+
|
47
|
+
The [translation gem](https://rubygems.org/gems/translation) in released under MIT license by [Aurélien Malisart](http://aurelien.malisart.be) and [Michaël Hoste](http://80limit.com) (see MIT-LICENSE
|
48
|
+
file).
|
49
|
+
|
50
|
+
(c) http://rails.translation.io
|
data/lib/translation.rb
CHANGED
@@ -1,2 +1,77 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
require 'gettext'
|
4
|
+
require 'gettext/po'
|
5
|
+
require 'gettext/po_parser'
|
6
|
+
require 'gettext/tools'
|
7
|
+
require 'gettext/text_domain_manager'
|
8
|
+
|
1
9
|
module Translation
|
10
|
+
GETTEXT_METHODS = [
|
11
|
+
:_, :n_, :p_, :s_, :np_, :ns_, :N_, :Nn,
|
12
|
+
:gettext, :sgettext, :ngettext, :nsgettext, :pgettext, :npgettext
|
13
|
+
]
|
14
|
+
|
15
|
+
TEXT_DOMAIN = 'app'
|
16
|
+
SOURCE_FILES_PATTERN = '**/*.{rb,erb,html.erb,xml.erb}'
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'translation/config'
|
20
|
+
require 'translation/railtie'
|
21
|
+
require 'translation/client'
|
22
|
+
require 'translation/flat_hash'
|
23
|
+
require 'translation/yaml_conversion'
|
24
|
+
|
25
|
+
require 'translation/controller'
|
26
|
+
|
27
|
+
module Translation
|
28
|
+
module Proxy
|
29
|
+
include GetText
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
attr_reader :config, :client
|
34
|
+
|
35
|
+
def configure(&block)
|
36
|
+
if Rails.env.development?
|
37
|
+
GetText::TextDomainManager.cached = false
|
38
|
+
end
|
39
|
+
|
40
|
+
@config ||= Config.new
|
41
|
+
|
42
|
+
yield @config
|
43
|
+
|
44
|
+
Proxy.bindtextdomain(TEXT_DOMAIN, {
|
45
|
+
:path => @config.locales_path,
|
46
|
+
:charset => 'utf-8'
|
47
|
+
})
|
48
|
+
|
49
|
+
Proxy.textdomain(TEXT_DOMAIN)
|
50
|
+
Object.delegate *GETTEXT_METHODS, :to => Proxy
|
51
|
+
|
52
|
+
@client = Client.new(@config.api_key, @config.endpoint)
|
53
|
+
|
54
|
+
return true
|
55
|
+
end
|
56
|
+
|
57
|
+
def pot_path
|
58
|
+
File.join(Translation.config.locales_path, "#{TEXT_DOMAIN}.pot")
|
59
|
+
end
|
60
|
+
|
61
|
+
def info(message, level = 0, verbose_level = 0)
|
62
|
+
verbose = @config.try(:verbose) || 0
|
63
|
+
if verbose >= verbose_level
|
64
|
+
indent = (1..level).to_a.collect { " " }.join('')
|
65
|
+
puts "#{indent}* #{message}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def normalize_path(relative_or_absolute_path)
|
70
|
+
File.expand_path(relative_or_absolute_path).gsub("#{Dir.pwd}/", '')
|
71
|
+
end
|
72
|
+
|
73
|
+
def version
|
74
|
+
Gem::Specification::find_by_name('translation').version.to_s
|
75
|
+
end
|
76
|
+
end
|
2
77
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'translation/client/base_operation'
|
2
|
+
require 'translation/client/init_operation'
|
3
|
+
require 'translation/client/sync_operation'
|
4
|
+
require 'translation/client/purge_operation'
|
5
|
+
|
6
|
+
module Translation
|
7
|
+
class Client
|
8
|
+
attr_reader :api_key, :endpoint
|
9
|
+
|
10
|
+
def initialize(api_key, endpoint)
|
11
|
+
@api_key = api_key
|
12
|
+
@endpoint = endpoint
|
13
|
+
end
|
14
|
+
|
15
|
+
def init
|
16
|
+
Translation::Client::InitOperation.new(self).run
|
17
|
+
end
|
18
|
+
|
19
|
+
def sync
|
20
|
+
Translation::Client::SyncOperation.new(self).run
|
21
|
+
end
|
22
|
+
|
23
|
+
def purge
|
24
|
+
Translation::Client::SyncOperation.new(self).run(true)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'translation/client/base_operation/save_new_po_files_step'
|
2
|
+
require 'translation/client/base_operation/create_new_mo_files_step'
|
3
|
+
require 'translation/client/base_operation/save_new_yaml_files_step'
|
4
|
+
require 'translation/client/base_operation/save_special_yaml_files_step'
|
5
|
+
require 'translation/client/base_operation/dump_haml_gettext_keys_step'
|
6
|
+
require 'translation/client/base_operation/dump_slim_gettext_keys_step'
|
7
|
+
|
8
|
+
module Translation
|
9
|
+
class Client
|
10
|
+
class BaseOperation
|
11
|
+
attr_accessor :client, :params
|
12
|
+
|
13
|
+
GETTEXT_ENTRY_RE = Regexp.new('(?:' + Translation::GETTEXT_METHODS.join('|') + ')\([^)]+\)?\)')
|
14
|
+
|
15
|
+
def initialize(client, perform_real_requests = true)
|
16
|
+
@client = client
|
17
|
+
@params = {
|
18
|
+
'gem_version' => Translation.version,
|
19
|
+
'target_languages[]' => Translation.config.target_locales.map(&:to_s)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def perform_request(uri, params)
|
26
|
+
begin
|
27
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
28
|
+
http.read_timeout = 500
|
29
|
+
|
30
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
31
|
+
request.set_form_data(params)
|
32
|
+
|
33
|
+
response = http.request(request)
|
34
|
+
parsed_response = JSON.parse(response.body)
|
35
|
+
|
36
|
+
if response.code.to_i == 200
|
37
|
+
return parsed_response
|
38
|
+
elsif response.code.to_i == 400 && parsed_response.has_key?('error')
|
39
|
+
$stderr.puts "[Error] #{parsed_response['error']}"
|
40
|
+
else
|
41
|
+
$stderr.puts "[Error] Unknown error."
|
42
|
+
end
|
43
|
+
rescue Errno::ECONNREFUSED
|
44
|
+
$stderr.puts "[Error] Server not responding."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class BaseOperation
|
4
|
+
class CreateNewMoFilesStep
|
5
|
+
def initialize(locales_path)
|
6
|
+
@locales_path = locales_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
Translation.info "Creating new MO files."
|
11
|
+
|
12
|
+
Dir["#{@locales_path}/*/#{TEXT_DOMAIN}.po"].each do |po_path|
|
13
|
+
mo_path = "#{File.dirname(po_path)}/LC_MESSAGES/app.mo"
|
14
|
+
Translation.info mo_path, 2, 2
|
15
|
+
FileUtils.mkdir_p(File.dirname(mo_path))
|
16
|
+
GetText::Tools::MsgFmt.run(po_path, '-o', mo_path)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class BaseOperation
|
4
|
+
class DumpHamlGettextKeysStep
|
5
|
+
def initialize(haml_source_files)
|
6
|
+
@haml_source_files = haml_source_files
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
if @haml_source_files.any? && defined?(Haml)
|
11
|
+
Translation.info "Extracting Gettext entries from HAML files."
|
12
|
+
|
13
|
+
File.open(File.join('tmp', 'translation-haml-gettext.rb'), 'w') do |file|
|
14
|
+
extracted_gettext_entries.each do |entry|
|
15
|
+
file.puts "#{entry}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def extracted_gettext_entries
|
24
|
+
entries = []
|
25
|
+
|
26
|
+
@haml_source_files.each do |haml_file_path|
|
27
|
+
Translation.info haml_file_path, 2, 2
|
28
|
+
|
29
|
+
haml_data = File.read(haml_file_path)
|
30
|
+
ruby_data = Haml::Engine.new(haml_data).precompiled
|
31
|
+
|
32
|
+
ruby_data.scan(GETTEXT_ENTRY_RE).each do |entry|
|
33
|
+
entries << entry
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Translation.info "#{entries.size} entries found", 2, 2
|
38
|
+
|
39
|
+
entries
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class BaseOperation
|
4
|
+
class DumpSlimGettextKeysStep
|
5
|
+
def initialize(slim_source_files)
|
6
|
+
@slim_source_files = slim_source_files
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
if @slim_source_files.any? && defined?(Slim)
|
11
|
+
Translation.info "Extracting Gettext entries from SLIM files."
|
12
|
+
|
13
|
+
File.open(File.join('tmp', 'translation-slim-gettext.rb'), 'w') do |file|
|
14
|
+
extracted_gettext_entries.each do |entry|
|
15
|
+
file.puts "#{entry}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def extracted_gettext_entries
|
24
|
+
entries = []
|
25
|
+
|
26
|
+
@slim_source_files.each do |slim_file_path|
|
27
|
+
Translation.info slim_file_path, 2, 2
|
28
|
+
|
29
|
+
ruby_data = Slim::Template.new(slim_file_path, {}).precompiled_template
|
30
|
+
|
31
|
+
ruby_data.scan(GETTEXT_ENTRY_RE).each do |entry|
|
32
|
+
entries << entry
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Translation.info "#{entries.size} entries found", 2, 2
|
37
|
+
|
38
|
+
entries
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class BaseOperation
|
4
|
+
class SaveNewPoFilesStep
|
5
|
+
def initialize(target_locales, locales_path, parsed_response)
|
6
|
+
@target_locales = target_locales
|
7
|
+
@locales_path = locales_path
|
8
|
+
@parsed_response = parsed_response
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
Translation.info "Saving new PO files."
|
13
|
+
|
14
|
+
@target_locales.each do |target_locale|
|
15
|
+
if @parsed_response.has_key?("po_data_#{target_locale}")
|
16
|
+
po_path = File.join(@locales_path, target_locale.to_s.gsub('-', '_'), "#{TEXT_DOMAIN}.po")
|
17
|
+
FileUtils.mkdir_p(File.dirname(po_path))
|
18
|
+
Translation.info po_path, 2, 2
|
19
|
+
|
20
|
+
File.open(po_path, 'wb') do |file|
|
21
|
+
file.write(@parsed_response["po_data_#{target_locale}"])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
return self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class BaseOperation
|
4
|
+
class SaveNewYamlFilesStep
|
5
|
+
def initialize(target_locales, yaml_locales_path, parsed_response)
|
6
|
+
@target_locales = target_locales
|
7
|
+
@yaml_locales_path = yaml_locales_path
|
8
|
+
@parsed_response = parsed_response
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
Translation.info "Saving new translation YAML files."
|
13
|
+
|
14
|
+
@target_locales.each do |target_locale|
|
15
|
+
if @parsed_response.has_key?("yaml_po_data_#{target_locale}")
|
16
|
+
FileUtils.mkdir_p(@yaml_locales_path)
|
17
|
+
yaml_path = File.join(@yaml_locales_path, "translation.#{target_locale}.yml")
|
18
|
+
Translation.info yaml_path, 2, 2
|
19
|
+
yaml_data = YAMLConversion.get_yaml_data_from_po_data(@parsed_response["yaml_po_data_#{target_locale}"], target_locale)
|
20
|
+
|
21
|
+
top_comment = <<EOS
|
22
|
+
# WARNING. THIS FILE WAS AUTO-GENERATED BY THE TRANSLATION GEM.
|
23
|
+
# IF YOU UPDATE IT, YOUR CHANGES WILL BE LOST AT THE NEXT SYNC.
|
24
|
+
EOS
|
25
|
+
|
26
|
+
File.open(yaml_path, 'wb') do |file|
|
27
|
+
file.write("---\n")
|
28
|
+
file.write(top_comment)
|
29
|
+
file.write(yaml_data.split("---\n", 2).last)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class BaseOperation
|
4
|
+
class SaveSpecialYamlFilesStep
|
5
|
+
|
6
|
+
def initialize(source_locale, target_locales, yaml_locales_path, yaml_file_paths)
|
7
|
+
@source_locale = source_locale
|
8
|
+
@target_locales = target_locales
|
9
|
+
@yaml_locales_path = yaml_locales_path
|
10
|
+
@yaml_file_paths = yaml_file_paths
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
Translation.info "Saving new localization YAML files (with non-string values)."
|
15
|
+
all_flat_translations = {}
|
16
|
+
|
17
|
+
@yaml_file_paths.each do |file_path|
|
18
|
+
all_flat_translations.merge!(
|
19
|
+
YAMLConversion.get_flat_translations_for_yaml_file(file_path)
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
all_flat_special_translations = all_flat_translations.select do |key, value|
|
24
|
+
!value.is_a?(String) && !value.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
source_flat_special_translations = all_flat_special_translations.select do |key|
|
28
|
+
key.start_with?("#{@source_locale}.")
|
29
|
+
end
|
30
|
+
|
31
|
+
@target_locales.each do |target_locale|
|
32
|
+
yaml_path = File.join(@yaml_locales_path, "localization.#{target_locale}.yml")
|
33
|
+
|
34
|
+
Translation.info yaml_path, 2, 2
|
35
|
+
flat_translations = {}
|
36
|
+
|
37
|
+
source_flat_special_translations.each_pair do |key, value|
|
38
|
+
target_key = key.gsub(/\A#{@source_locale}\./, "#{target_locale}.")
|
39
|
+
flat_translations[target_key] = all_flat_special_translations[target_key]
|
40
|
+
end
|
41
|
+
|
42
|
+
yaml_data = YAMLConversion.get_yaml_data_from_flat_translations(flat_translations)
|
43
|
+
|
44
|
+
File.open(yaml_path, 'wb') do |file|
|
45
|
+
file.write(yaml_data)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'translation/client/init_operation/update_pot_file_step'
|
2
|
+
require 'translation/client/init_operation/update_and_collect_po_files_step'
|
3
|
+
require 'translation/client/init_operation/create_yaml_po_files_step'
|
4
|
+
require 'translation/client/init_operation/cleanup_yaml_files_step'
|
5
|
+
|
6
|
+
module Translation
|
7
|
+
class Client
|
8
|
+
class InitOperation < BaseOperation
|
9
|
+
def run
|
10
|
+
haml_source_files = Dir['**/*.{haml}']
|
11
|
+
slim_source_files = Dir['**/*.{slim}']
|
12
|
+
|
13
|
+
BaseOperation::DumpHamlGettextKeysStep.new(haml_source_files).run
|
14
|
+
BaseOperation::DumpSlimGettextKeysStep.new(slim_source_files).run
|
15
|
+
|
16
|
+
source_files = Dir[SOURCE_FILES_PATTERN]
|
17
|
+
pot_path = Translation.pot_path
|
18
|
+
source_locale = Translation.config.source_locale
|
19
|
+
target_locales = Translation.config.target_locales
|
20
|
+
locales_path = Translation.config.locales_path
|
21
|
+
yaml_locales_path = 'config/locales'
|
22
|
+
yaml_file_paths = I18n.load_path
|
23
|
+
|
24
|
+
UpdatePotFileStep.new(pot_path, source_files).run
|
25
|
+
UpdateAndCollectPoFilesStep.new(target_locales, pot_path, locales_path).run(params)
|
26
|
+
CreateYamlPoFilesStep.new(source_locale, target_locales, yaml_file_paths).run(params)
|
27
|
+
|
28
|
+
Translation.info "Sending data to server"
|
29
|
+
uri = URI("http://#{client.endpoint}/projects/#{client.api_key}/init")
|
30
|
+
parsed_response = perform_request(uri, params)
|
31
|
+
|
32
|
+
unless parsed_response.nil?
|
33
|
+
BaseOperation::SaveNewPoFilesStep.new(target_locales, locales_path, parsed_response).run
|
34
|
+
BaseOperation::SaveNewYamlFilesStep.new(target_locales, yaml_locales_path, parsed_response).run
|
35
|
+
BaseOperation::SaveSpecialYamlFilesStep.new(source_locale, target_locales, yaml_locales_path, yaml_file_paths).run
|
36
|
+
CleanupYamlFilesStep.new(source_locale, target_locales, yaml_file_paths, yaml_locales_path).run
|
37
|
+
BaseOperation::CreateNewMoFilesStep.new(locales_path).run
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class InitOperation < BaseOperation
|
4
|
+
class CleanupYamlFilesStep
|
5
|
+
def initialize(source_locale, target_locales, yaml_file_paths, yaml_locales_path)
|
6
|
+
@source_locale = source_locale
|
7
|
+
@target_locales = target_locales
|
8
|
+
@yaml_file_paths = yaml_file_paths
|
9
|
+
@yaml_locales_path = yaml_locales_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
@yaml_file_paths.each do |locale_file_path|
|
14
|
+
in_project = locale_file_path_in_project?(locale_file_path)
|
15
|
+
|
16
|
+
protected_file = @target_locales.any? do |target_locale|
|
17
|
+
paths = [
|
18
|
+
File.join(@yaml_locales_path, "translation.#{target_locale}.yml").to_s,
|
19
|
+
File.join(@yaml_locales_path, "localization.#{target_locale}.yml").to_s
|
20
|
+
]
|
21
|
+
|
22
|
+
paths.include?(locale_file_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
if in_project && !protected_file
|
26
|
+
content_hash = YAML::load(File.read(locale_file_path))
|
27
|
+
new_content_hash = content_hash.keep_if { |k| k.to_s == @source_locale.to_s }
|
28
|
+
|
29
|
+
if new_content_hash.keys.any?
|
30
|
+
Translation.info "Rewriting #{locale_file_path}", 2, 2
|
31
|
+
File.open(locale_file_path, 'wb') do |file|
|
32
|
+
file.write(new_content_hash.to_yaml)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
Translation.info "Removing #{locale_file_path}", 2, 2
|
36
|
+
FileUtils.rm(locale_file_path)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def locale_file_path_in_project?(locale_file_path)
|
45
|
+
Translation.normalize_path(locale_file_path).start_with?(
|
46
|
+
Translation.normalize_path(@yaml_locales_path)
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class InitOperation < BaseOperation
|
4
|
+
class CreateYamlPoFilesStep
|
5
|
+
def initialize(source_locale, target_locales, yaml_file_paths)
|
6
|
+
@source_locale = source_locale
|
7
|
+
@target_locales = target_locales
|
8
|
+
@yaml_file_paths = yaml_file_paths
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(params)
|
12
|
+
Translation.info "Importing translations from YAML files."
|
13
|
+
all_flat_translations = {}
|
14
|
+
|
15
|
+
@yaml_file_paths.each do |file_path|
|
16
|
+
Translation.info file_path, 2, 2
|
17
|
+
all_flat_translations.merge!(YAMLConversion.get_flat_translations_for_yaml_file(file_path))
|
18
|
+
end
|
19
|
+
|
20
|
+
all_flat_string_translations = all_flat_translations.select do |key, value|
|
21
|
+
key.present? && value.is_a?(String) && !value.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
source_flat_string_tanslations = all_flat_string_translations.select do |key|
|
25
|
+
key.start_with?("#{@source_locale}.") && !key.start_with?("#{@source_locale}.faker.")
|
26
|
+
end
|
27
|
+
|
28
|
+
@target_locales.each do |target_locale|
|
29
|
+
po_representation = GetText::PO.new
|
30
|
+
|
31
|
+
source_flat_string_tanslations.each_pair do |key, value|
|
32
|
+
target_key = key.gsub(/\A#{Translation.config.source_locale}\./, "#{target_locale}.")
|
33
|
+
msgid = value
|
34
|
+
msgstr = all_flat_string_translations[target_key]
|
35
|
+
|
36
|
+
unless msgid.blank?
|
37
|
+
po_entry = GetText::POEntry.new(:msgctxt)
|
38
|
+
po_entry.msgid = msgid
|
39
|
+
po_entry.msgstr = msgstr
|
40
|
+
po_entry.msgctxt = key.split('.', 2).last
|
41
|
+
#po_entry.references = [ value[:locale_file_path] ]
|
42
|
+
|
43
|
+
po_representation[po_entry.msgctxt, po_entry.msgid] = po_entry
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
params["yaml_po_data_#{target_locale}"] = po_representation.to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class InitOperation < BaseOperation
|
4
|
+
class UpdateAndCollectPoFilesStep
|
5
|
+
def initialize(target_locales, pot_path, locales_path)
|
6
|
+
@target_locales = target_locales
|
7
|
+
@pot_path = pot_path
|
8
|
+
@locales_path = locales_path
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(params)
|
12
|
+
Translation.info "Updating PO files."
|
13
|
+
|
14
|
+
@target_locales.each do |target_locale|
|
15
|
+
po_path = "#{@locales_path}/#{target_locale.gsub('-', '_')}/#{TEXT_DOMAIN}.po"
|
16
|
+
Translation.info po_path, 2, 2
|
17
|
+
|
18
|
+
if File.exist?(po_path)
|
19
|
+
GetText::Tools::MsgMerge.run(po_path, @pot_path, '-o', po_path, '--no-fuzzy-matching', '--no-obsolete-entries')
|
20
|
+
else
|
21
|
+
FileUtils.mkdir_p(File.dirname(po_path))
|
22
|
+
GetText::Tools::MsgInit.run('-i', @pot_path, '-o', po_path, '-l', target_locale, '--no-translator')
|
23
|
+
end
|
24
|
+
|
25
|
+
params["po_data_#{target_locale}"] = File.read(po_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
return self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class InitOperation < BaseOperation
|
4
|
+
class UpdatePotFileStep
|
5
|
+
def initialize(pot_path, source_files)
|
6
|
+
@pot_path = pot_path
|
7
|
+
@source_files = source_files
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
Translation.info "Updating POT file."
|
12
|
+
FileUtils.mkdir_p(File.dirname(@pot_path))
|
13
|
+
GetText::Tools::XGetText.run(*@source_files, '-o', @pot_path, '--msgid-bugs-address', 'contact@translation.io',)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'translation/client/sync_operation/update_and_collect_pot_file_step'
|
2
|
+
require 'translation/client/sync_operation/create_yaml_pot_file_step'
|
3
|
+
|
4
|
+
module Translation
|
5
|
+
class Client
|
6
|
+
class SyncOperation < BaseOperation
|
7
|
+
def run(purge = false)
|
8
|
+
haml_source_files = Dir['**/*.{haml}']
|
9
|
+
slim_source_files = Dir['**/*.{slim}']
|
10
|
+
|
11
|
+
BaseOperation::DumpHamlGettextKeysStep.new(haml_source_files).run
|
12
|
+
BaseOperation::DumpSlimGettextKeysStep.new(slim_source_files).run
|
13
|
+
|
14
|
+
source_files = Dir[SOURCE_FILES_PATTERN]
|
15
|
+
pot_path = Translation.pot_path
|
16
|
+
source_locale = Translation.config.source_locale
|
17
|
+
target_locales = Translation.config.target_locales
|
18
|
+
locales_path = Translation.config.locales_path
|
19
|
+
yaml_locales_path = 'config/locales'
|
20
|
+
yaml_file_paths = I18n.load_path
|
21
|
+
|
22
|
+
UpdateAndCollectPotFileStep.new(pot_path, source_files).run(params)
|
23
|
+
CreateYamlPotFileStep.new(source_locale, yaml_file_paths).run(params)
|
24
|
+
|
25
|
+
if purge
|
26
|
+
params['purge'] = 'true'
|
27
|
+
end
|
28
|
+
|
29
|
+
uri = URI("http://#{client.endpoint}/projects/#{client.api_key}/sync")
|
30
|
+
parsed_response = perform_request(uri, params)
|
31
|
+
|
32
|
+
unless parsed_response.nil?
|
33
|
+
BaseOperation::SaveNewPoFilesStep.new(target_locales, locales_path, parsed_response).run
|
34
|
+
BaseOperation::CreateNewMoFilesStep.new(locales_path).run
|
35
|
+
BaseOperation::SaveNewYamlFilesStep.new(target_locales, yaml_locales_path, parsed_response).run
|
36
|
+
BaseOperation::SaveSpecialYamlFilesStep.new(source_locale, target_locales, yaml_locales_path, yaml_file_paths).run
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class SyncOperation < BaseOperation
|
4
|
+
class CreateYamlPotFileStep
|
5
|
+
def initialize(source_locale, yaml_file_paths)
|
6
|
+
@source_locale = source_locale
|
7
|
+
@yaml_file_paths = yaml_file_paths
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(params)
|
11
|
+
Translation.info "Generating POT file from YAML files."
|
12
|
+
all_flat_translations = {}
|
13
|
+
|
14
|
+
@yaml_file_paths.each do |file_path|
|
15
|
+
Translation.info file_path, 2, 2
|
16
|
+
all_flat_translations.merge!(
|
17
|
+
YAMLConversion.get_flat_translations_for_yaml_file(file_path)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
source_flat_string_tanslations = all_flat_translations.select do |key, value|
|
22
|
+
value.is_a?(String) && key.start_with?("#{@source_locale}.") && !key.start_with?("#{@source_locale}.faker.")
|
23
|
+
end
|
24
|
+
|
25
|
+
pot_representation = GetText::PO.new
|
26
|
+
|
27
|
+
source_flat_string_tanslations.each_pair do |key, value|
|
28
|
+
msgid = value
|
29
|
+
|
30
|
+
unless msgid.blank?
|
31
|
+
pot_entry = GetText::POEntry.new(:msgctxt)
|
32
|
+
pot_entry.msgid = msgid
|
33
|
+
pot_entry.msgstr = ''
|
34
|
+
pot_entry.msgctxt = key.split('.', 2).last
|
35
|
+
#pot_entry.references = [ value[:locale_file_path] ]
|
36
|
+
|
37
|
+
pot_representation[pot_entry.msgctxt, pot_entry.msgid] = pot_entry
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
params['yaml_pot_data'] = pot_representation.to_s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Translation
|
2
|
+
class Client
|
3
|
+
class SyncOperation < BaseOperation
|
4
|
+
class UpdateAndCollectPotFileStep
|
5
|
+
def initialize(pot_path, source_files)
|
6
|
+
@pot_path = pot_path
|
7
|
+
@source_files = source_files
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(params)
|
11
|
+
Translation.info "Updating POT file."
|
12
|
+
GetText::Tools::XGetText.run(*@source_files, '-o', @pot_path)
|
13
|
+
params['pot_data'] = File.read(@pot_path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Translation
|
2
|
+
class Config
|
3
|
+
attr_accessor :api_key, :locales_path
|
4
|
+
attr_accessor :source_locale, :target_locales
|
5
|
+
attr_accessor :endpoint
|
6
|
+
attr_accessor :verbose
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
self.locales_path = File.join('config', 'locales', 'gettext')
|
10
|
+
self.source_locale = :en
|
11
|
+
self.target_locales = []
|
12
|
+
self.endpoint = 'api.translation.io/api'
|
13
|
+
self.verbose = 1
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
"#{api_key} — #{source_locale} => #{target_locales.join(' + ')}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Translation
|
2
|
+
module Controller
|
3
|
+
def set_locale
|
4
|
+
requested_locale = params[:locale] ||
|
5
|
+
session[:locale] ||
|
6
|
+
cookies[:locale] ||
|
7
|
+
request.env['HTTP_ACCEPT_LANGUAGE'] ||
|
8
|
+
I18n.default_locale
|
9
|
+
|
10
|
+
if requested_locale.to_sym.in?(I18n.available_locales)
|
11
|
+
session[:locale] = requested_locale
|
12
|
+
I18n.locale = requested_locale
|
13
|
+
else
|
14
|
+
redirect_to :root, :locale => I18n.default_locale
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Translation
|
2
|
+
module FlatHash
|
3
|
+
class << self
|
4
|
+
def to_flat_hash(hash)
|
5
|
+
get_flat_hash_for_level(hash)
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_hash(flat_hash)
|
9
|
+
hash = {}
|
10
|
+
|
11
|
+
flat_hash.each_pair do |key, value|
|
12
|
+
build_hash_with_flat(hash, key, value)
|
13
|
+
end
|
14
|
+
|
15
|
+
hash
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def build_hash_with_flat(hash, key_string, value)
|
21
|
+
current_object = hash
|
22
|
+
splitted = key_string.split(/\.|\[/, 2)
|
23
|
+
current_key = splitted[0] # first is always a hash
|
24
|
+
key_string = splitted[1]
|
25
|
+
|
26
|
+
if key_string.blank? # if only one key like { 'en' => 'salut' }
|
27
|
+
current_object[current_key] = value
|
28
|
+
else
|
29
|
+
# Put back '[' if needed
|
30
|
+
if key_string.count(']') > key_string.count('[')
|
31
|
+
key_string = '[' + key_string
|
32
|
+
end
|
33
|
+
|
34
|
+
while key_string != ''
|
35
|
+
# Next is array
|
36
|
+
if key_string[0] == '['
|
37
|
+
array_pos = key_string.split(']', 2)[0]
|
38
|
+
array_pos = array_pos.split('[', 2)[1].to_i
|
39
|
+
|
40
|
+
key_string = key_string.split(']', 2).count == 2 ? key_string.split(']', 2)[1] : ""
|
41
|
+
key_string = key_string[1..-1] if key_string[0] == '.'
|
42
|
+
|
43
|
+
if no_key?(current_object, current_key)
|
44
|
+
current_object[current_key] = []
|
45
|
+
end
|
46
|
+
|
47
|
+
current_object = current_object[current_key]
|
48
|
+
current_key = array_pos
|
49
|
+
|
50
|
+
# array is terminal
|
51
|
+
if key_string == ''
|
52
|
+
current_object[array_pos] = value
|
53
|
+
end
|
54
|
+
# next is hash
|
55
|
+
elsif key_string[0] != '[' && (key_string.include?('.') or key_string.include?('['))
|
56
|
+
splitted = key_string.split(/\.|\[/, 2)
|
57
|
+
new_key = splitted[0]
|
58
|
+
key_string = splitted[1]
|
59
|
+
|
60
|
+
# Put back '[' if needed
|
61
|
+
if key_string.count(']') > key_string.count('[')
|
62
|
+
key_string = '[' + key_string
|
63
|
+
end
|
64
|
+
|
65
|
+
if no_key?(current_object, current_key)
|
66
|
+
current_object[current_key] = {}
|
67
|
+
end
|
68
|
+
current_object = current_object[current_key]
|
69
|
+
current_key = new_key
|
70
|
+
# next (last) is value
|
71
|
+
else
|
72
|
+
new_key = key_string
|
73
|
+
|
74
|
+
if no_key?(current_object, current_key)
|
75
|
+
current_object[current_key] = {}
|
76
|
+
end
|
77
|
+
current_object = current_object[current_key]
|
78
|
+
current_object[new_key] = value
|
79
|
+
|
80
|
+
key_string = ''
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def no_key?(array_or_hash, key)
|
87
|
+
(array_or_hash.is_a?(Hash) && !array_or_hash.has_key?(key)) || !array_or_hash[key]
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_flat_hash_for_level(value, parent_key = nil)
|
91
|
+
flat_hash = {}
|
92
|
+
|
93
|
+
if value.is_a? Hash
|
94
|
+
value.each_pair do |key, value|
|
95
|
+
current_level_key = [ parent_key, key ].reject(&:blank?).join('.')
|
96
|
+
flat_hash.merge!(get_flat_hash_for_level(value, current_level_key))
|
97
|
+
end
|
98
|
+
elsif value.is_a? Array
|
99
|
+
value.each_with_index do |item, index|
|
100
|
+
flat_hash.merge!(get_flat_hash_for_level(item, "#{parent_key}[#{index}]"))
|
101
|
+
end
|
102
|
+
else
|
103
|
+
flat_hash[parent_key] = value
|
104
|
+
end
|
105
|
+
|
106
|
+
flat_hash
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
require 'i18n/config'
|
3
|
+
|
4
|
+
require 'gettext'
|
5
|
+
require 'gettext/po'
|
6
|
+
require 'gettext/po_parser'
|
7
|
+
|
8
|
+
module Translation
|
9
|
+
class Railtie < Rails::Railtie
|
10
|
+
rake_tasks do
|
11
|
+
require 'translation/tasks'
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer 'translation.rails_extensions' do
|
15
|
+
ActionController::Base.send(:include, Translation::Controller)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module I18n
|
21
|
+
class Config
|
22
|
+
def locale=(locale)
|
23
|
+
I18n.enforce_available_locales!(locale)
|
24
|
+
@locale = locale.to_sym rescue nil
|
25
|
+
GetText.locale = locale.to_s.gsub('-', '_').to_sym
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module GetText
|
31
|
+
class POParser < Racc::Parser
|
32
|
+
def initialize
|
33
|
+
@ignore_fuzzy = true
|
34
|
+
@report_warning = false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'gettext/tools'
|
2
|
+
|
3
|
+
namespace :translation do
|
4
|
+
task :config => :environment do
|
5
|
+
puts Translation.config
|
6
|
+
end
|
7
|
+
|
8
|
+
task :init => :environment do
|
9
|
+
if Translation.client
|
10
|
+
Translation.client.init
|
11
|
+
else
|
12
|
+
Translation.info "[Error] Client cannot be built. Did you set up the initializer?"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
task :sync => :environment do
|
17
|
+
if Translation.client
|
18
|
+
Translation.client.sync
|
19
|
+
else
|
20
|
+
Translation.info "[Error] Client cannot be built. Did you set up the initializer?"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
task :purge => :environment do
|
25
|
+
if Translation.client
|
26
|
+
Translation.client.purge
|
27
|
+
else
|
28
|
+
Translation.info "[Error] Client cannot be built. Did you set up the initializer?"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Translation
|
2
|
+
module YAMLConversion
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def get_pot_data_from_yaml(source_locale = nil, yaml_file_paths = nil)
|
6
|
+
source_locale = Translation.config.source_locale if source_locale.blank?
|
7
|
+
yaml_file_paths = I18n.load_path if yaml_file_paths.nil?
|
8
|
+
|
9
|
+
source_translations = YAMLConversion.get_flat_translations_for_locale(source_locale, yaml_file_paths)
|
10
|
+
pot_representation = GetText::PO.new
|
11
|
+
|
12
|
+
source_translations.each_pair do |key, value|
|
13
|
+
msgid = value
|
14
|
+
|
15
|
+
unless msgid.blank?
|
16
|
+
pot_entry = GetText::POEntry.new(:msgctxt)
|
17
|
+
pot_entry.msgid = msgid
|
18
|
+
pot_entry.msgctxt = key.split('.', 2).last
|
19
|
+
#pot_entry.references = [ value[:locale_file_path] ]
|
20
|
+
|
21
|
+
pot_representation[ pot_entry.msgctxt, pot_entry.msgid ] = pot_entry
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
pot_representation.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_yaml_data_from_po_data(po_data, target_locale)
|
29
|
+
parser = GetText::POParser.new
|
30
|
+
po_representation = GetText::PO.new
|
31
|
+
flat_translations = {}
|
32
|
+
|
33
|
+
parser.parse(po_data, po_representation)
|
34
|
+
|
35
|
+
po_representation.each do |po_entry|
|
36
|
+
flat_translations["#{target_locale}.#{po_entry.msgctxt}"] = po_entry.msgstr
|
37
|
+
end
|
38
|
+
|
39
|
+
translations = YAMLConversion.get_yaml_data_from_flat_translations(flat_translations)
|
40
|
+
|
41
|
+
return translations
|
42
|
+
end
|
43
|
+
|
44
|
+
# Shortcut methods
|
45
|
+
|
46
|
+
def get_flat_translations_for_locale(locale, yaml_file_paths = nil)
|
47
|
+
yaml_file_paths = I18n.load_path if yaml_file_paths.blank?
|
48
|
+
|
49
|
+
all_flat_translations = {}
|
50
|
+
|
51
|
+
yaml_file_paths.each do |yaml_file_path|
|
52
|
+
content = File.read(yaml_file_path)
|
53
|
+
translations = YAML::load(content)
|
54
|
+
|
55
|
+
if translations.has_key?(locale.to_s)
|
56
|
+
flat_translations = FlatHash.to_flat_hash(translations)
|
57
|
+
all_flat_translations.merge!(flat_translations)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
return all_flat_translations
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_flat_translations_for_yaml_file(file_path)
|
65
|
+
yaml_data = File.read(file_path)
|
66
|
+
return get_flat_translations_for_yaml_data(yaml_data)
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_flat_translations_for_yaml_data(yaml_data)
|
70
|
+
translations = YAML::load(yaml_data)
|
71
|
+
return FlatHash.to_flat_hash(translations)
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_yaml_data_from_flat_translations(flat_translations)
|
75
|
+
translations = FlatHash.to_hash(flat_translations)
|
76
|
+
return translations.to_yaml
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
metadata
CHANGED
@@ -1,39 +1,131 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: translation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aurelien Malisart
|
8
|
-
-
|
8
|
+
- Michael Hoste
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gettext
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - '
|
18
|
+
- - '>='
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 3.1.
|
20
|
+
version: 3.1.2
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - '
|
25
|
+
- - '>='
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 3.1.
|
27
|
+
version: 3.1.2
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rails
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: haml
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: slim
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
28
98
|
description: translation.io connector
|
29
99
|
email: contact@translation.io
|
30
100
|
executables: []
|
31
101
|
extensions: []
|
32
|
-
extra_rdoc_files:
|
33
|
-
- README.rdoc
|
102
|
+
extra_rdoc_files: []
|
34
103
|
files:
|
104
|
+
- lib/translation/client/base_operation/create_new_mo_files_step.rb
|
105
|
+
- lib/translation/client/base_operation/dump_haml_gettext_keys_step.rb
|
106
|
+
- lib/translation/client/base_operation/dump_slim_gettext_keys_step.rb
|
107
|
+
- lib/translation/client/base_operation/save_new_po_files_step.rb
|
108
|
+
- lib/translation/client/base_operation/save_new_yaml_files_step.rb
|
109
|
+
- lib/translation/client/base_operation/save_special_yaml_files_step.rb
|
110
|
+
- lib/translation/client/base_operation.rb
|
111
|
+
- lib/translation/client/init_operation/cleanup_yaml_files_step.rb
|
112
|
+
- lib/translation/client/init_operation/create_yaml_po_files_step.rb
|
113
|
+
- lib/translation/client/init_operation/update_and_collect_po_files_step.rb
|
114
|
+
- lib/translation/client/init_operation/update_pot_file_step.rb
|
115
|
+
- lib/translation/client/init_operation.rb
|
116
|
+
- lib/translation/client/purge_operation.rb
|
117
|
+
- lib/translation/client/sync_operation/create_yaml_pot_file_step.rb
|
118
|
+
- lib/translation/client/sync_operation/update_and_collect_pot_file_step.rb
|
119
|
+
- lib/translation/client/sync_operation.rb
|
120
|
+
- lib/translation/client.rb
|
121
|
+
- lib/translation/config.rb
|
122
|
+
- lib/translation/controller.rb
|
123
|
+
- lib/translation/flat_hash.rb
|
124
|
+
- lib/translation/railtie.rb
|
125
|
+
- lib/translation/tasks.rb
|
126
|
+
- lib/translation/yaml_conversion.rb
|
35
127
|
- lib/translation.rb
|
36
|
-
- README.
|
128
|
+
- README.md
|
37
129
|
homepage: http://rails.translation.io
|
38
130
|
licenses:
|
39
131
|
- MIT
|
@@ -54,8 +146,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
146
|
version: '0'
|
55
147
|
requirements: []
|
56
148
|
rubyforge_project:
|
57
|
-
rubygems_version: 2.
|
149
|
+
rubygems_version: 2.0.0
|
58
150
|
signing_key:
|
59
151
|
specification_version: 4
|
60
152
|
summary: translation.io connector
|
61
153
|
test_files: []
|
154
|
+
has_rdoc: false
|
data/README.rdoc
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
= Description
|
2
|
-
|
3
|
-
...
|
4
|
-
|
5
|
-
= Basic Usage
|
6
|
-
|
7
|
-
...
|
8
|
-
|
9
|
-
= Installation
|
10
|
-
|
11
|
-
In your project's Gemfile :
|
12
|
-
|
13
|
-
gem 'translation'
|
14
|
-
|
15
|
-
= Credits
|
16
|
-
|
17
|
-
This plugin in released under MIT license by Aurélien Malisart and Michaël Hoste (see MIT-LICENSE
|
18
|
-
file).
|
19
|
-
|
20
|
-
(c) http://rails.translation.io
|