translation 0.1 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|