translate-rails3-plus 0.0.11 → 0.0.12

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.
data/lib/translate.rb CHANGED
@@ -1,17 +1,17 @@
1
- require 'ya2yaml'
2
-
3
- module Translate
4
- class Engine < Rails::Engine
5
- end if defined?(Rails) && Rails::VERSION::MAJOR >= 3
6
-
7
- class << self
8
- # For configuring Google Translate API key
9
- attr_accessor :api_key
10
- # For configuring Bing Application id
11
- attr_accessor :app_id
12
- end
13
- end
14
-
15
- Dir[File.join(File.dirname(__FILE__), "translate", "*.rb")].each do |file|
16
- require file
17
- end
1
+ require 'ya2yaml'
2
+
3
+ module Translate
4
+ class Engine < Rails::Engine
5
+ end if defined?(Rails) && Rails::VERSION::MAJOR >= 3
6
+
7
+ class << self
8
+ # For configuring Google Translate API key
9
+ attr_accessor :api_key
10
+ # For configuring Bing Application id
11
+ attr_accessor :app_id
12
+ end
13
+ end
14
+
15
+ Dir[File.join(File.dirname(__FILE__), "translate", "*.rb")].each do |file|
16
+ require file
17
+ end
@@ -1,35 +1,35 @@
1
- require 'fileutils'
2
-
3
- class Translate::File
4
- attr_accessor :path
5
-
6
- def initialize(path)
7
- self.path = path
8
- end
9
-
10
- def write(keys)
11
- FileUtils.mkdir_p File.dirname(path)
12
- File.open(path, "w") do |file|
13
- file.puts keys_to_yaml(Translate::File.deep_stringify_keys(keys))
14
- end
15
- end
16
-
17
- def read
18
- File.exists?(path) ? YAML::load(IO.read(path)) : {}
19
- end
20
-
21
- # Stringifying keys for prettier YAML
22
- def self.deep_stringify_keys(hash)
23
- hash.inject({}) { |result, (key, value)|
24
- value = deep_stringify_keys(value) if value.is_a? Hash
25
- result[(key.to_s rescue key) || key] = value
26
- result
27
- }
28
- end
29
-
30
- private
31
- def keys_to_yaml(keys)
32
- # Using ya2yaml, if available, for UTF8 support
33
- keys.respond_to?(:ya2yaml) ? keys.ya2yaml(:escape_as_utf8 => true) : keys.to_yaml
34
- end
35
- end
1
+ require 'fileutils'
2
+
3
+ class Translate::File
4
+ attr_accessor :path
5
+
6
+ def initialize(path)
7
+ self.path = path
8
+ end
9
+
10
+ def write(keys)
11
+ FileUtils.mkdir_p File.dirname(path)
12
+ File.open(path, "w") do |file|
13
+ file.puts keys_to_yaml(Translate::File.deep_stringify_keys(keys))
14
+ end
15
+ end
16
+
17
+ def read
18
+ File.exists?(path) ? YAML::load(IO.read(path)) : {}
19
+ end
20
+
21
+ # Stringifying keys for prettier YAML
22
+ def self.deep_stringify_keys(hash)
23
+ hash.inject({}) { |result, (key, value)|
24
+ value = deep_stringify_keys(value) if value.is_a? Hash
25
+ result[(key.to_s rescue key) || key] = value
26
+ result
27
+ }
28
+ end
29
+
30
+ private
31
+ def keys_to_yaml(keys)
32
+ # Using ya2yaml, if available, for UTF8 support
33
+ keys.respond_to?(:ya2yaml) ? keys.ya2yaml(:escape_as_utf8 => true) : keys.to_yaml
34
+ end
35
+ end
@@ -1,194 +1,194 @@
1
- require 'pathname'
2
-
3
- class Translate::Keys
4
- # Allows keys extracted from lookups in files to be cached
5
- def self.files
6
- @@files ||= Translate::Keys.new.files
7
- end
8
-
9
- # Allows flushing of the files cache
10
- def self.files=(files)
11
- @@files = files
12
- end
13
-
14
- def files
15
- @files ||= extract_files
16
- end
17
- alias_method :to_hash, :files
18
-
19
- def keys
20
- files.keys
21
- end
22
- alias_method :to_a, :keys
23
-
24
- def i18n_keys(locale)
25
- I18n.backend.send(:init_translations) unless I18n.backend.initialized?
26
- Translate::Keys.to_shallow_hash(I18n.backend.send(:translations)[locale.to_sym]).keys.sort
27
- end
28
-
29
- def duplicate_keys
30
- Translate::Keys.translated_locales.inject({}) do |missing, locale|
31
- missing[locale] = i18n_keys(I18n.default_locale).map do |key|
32
- I18n.backend.send(:lookup, locale, key) == I18n.backend.send(:lookup, I18n.default_locale, key) ? key : nil
33
- end.compact
34
- missing
35
- end
36
- end
37
-
38
- def untranslated_keys
39
- Translate::Keys.translated_locales.inject({}) do |missing, locale|
40
- missing[locale] = i18n_keys(I18n.default_locale).map do |key|
41
- I18n.backend.send(:lookup, locale, key).nil? ? key : nil
42
- end.compact
43
- missing
44
- end
45
- end
46
-
47
- def missing_keys
48
- locale = I18n.default_locale; yaml_keys = {}
49
- yaml_keys = Translate::Storage.file_paths(locale).inject({}) do |keys, path|
50
- keys = keys.deep_merge(Translate::File.new(path).read[locale.to_s])
51
- end
52
- files.reject { |key, file| self.class.contains_key?(yaml_keys, key) }
53
- end
54
-
55
- def self.translated_locales
56
- I18n.available_locales.reject { |locale| [:root, I18n.default_locale.to_sym].include?(locale) }
57
- end
58
-
59
- # Checks if a nested hash contains the keys in dot separated I18n key.
60
- #
61
- # Example:
62
- #
63
- # hash = {
64
- # :foo => {
65
- # :bar => {
66
- # :baz => 1
67
- # }
68
- # }
69
- # }
70
- #
71
- # contains_key?("foo", key) # => true
72
- # contains_key?("foo.bar", key) # => true
73
- # contains_key?("foo.bar.baz", key) # => true
74
- # contains_key?("foo.bar.baz.bla", key) # => false
75
- #
76
- def self.contains_key?(hash, key)
77
- keys = key.to_s.split(".")
78
- return false if keys.empty?
79
- !keys.inject(HashWithIndifferentAccess.new(hash)) do |memo, key|
80
- memo.is_a?(Hash) ? memo.try(:[], key) : nil
81
- end.nil?
82
- end
83
-
84
- # Convert something like:
85
- #
86
- # {
87
- # :pressrelease => {
88
- # :label => {
89
- # :one => "Pressmeddelande"
90
- # }
91
- # }
92
- # }
93
- #
94
- # to:
95
- #
96
- # {'pressrelease.label.one' => "Pressmeddelande"}
97
- #
98
- def self.to_shallow_hash(hash)
99
- hash.inject({}) do |shallow_hash, (key, value)|
100
- if value.is_a?(Hash)
101
- to_shallow_hash(value).each do |sub_key, sub_value|
102
- shallow_hash[[key, sub_key].join(".")] = sub_value
103
- end
104
- else
105
- shallow_hash[key.to_s] = value
106
- end
107
- shallow_hash
108
- end
109
- end
110
-
111
- # Convert something like:
112
- #
113
- # {'pressrelease.label.one' => "Pressmeddelande"}
114
- #
115
- # to:
116
- #
117
- # {
118
- # :pressrelease => {
119
- # :label => {
120
- # :one => "Pressmeddelande"
121
- # }
122
- # }
123
- # }
124
- def self.to_deep_hash(hash)
125
- hash.inject({}) do |deep_hash, (key, value)|
126
- keys = key.to_s.split('.').reverse
127
- leaf_key = keys.shift
128
- key_hash = keys.inject({leaf_key.to_sym => value}) { |hash, key| {key.to_sym => hash} }
129
- deep_merge!(deep_hash, key_hash)
130
- deep_hash
131
- end
132
- end
133
-
134
- # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
135
- def self.deep_merge!(hash1, hash2)
136
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
137
- hash1.merge!(hash2, &merger)
138
- end
139
-
140
- # Convert something like:
141
- #
142
- # {'0' => "elem 1", '1' => "elem 2"}
143
- #
144
- # to:
145
- #
146
- # ["elem 1", "elem 2"]
147
- #
148
- def self.arraylize(input_hash)
149
- input_hash.inject([]) do |constructed_array, (key, value)|
150
- constructed_array << value
151
- constructed_array
152
- end
153
- end
154
-
155
- private
156
-
157
- def extract_files
158
- files_to_scan.inject(HashWithIndifferentAccess.new) do |files, file|
159
- keys = IO.read(file)
160
- if keys.respond_to? "encode"
161
- keys = keys.encode("UTF-8").force_encoding("UTF-8")
162
- end
163
- error_count = 0
164
- begin
165
- encoded_keys = keys.scan(i18n_lookup_pattern)
166
- rescue => e
167
- unless error_count > 1
168
- if keys.respond_to? 'encode!'
169
- keys.encode!('utf-8', 'utf-8', :invalid => :replace)
170
- end
171
- error_count += 1
172
- retry
173
- else
174
- puts "cannot fix: #{e} on : #{file}"
175
- end
176
- end
177
- encoded_keys.flatten.map(&:to_sym).each do |key|
178
- files[key] ||= []
179
- path = Pathname.new(File.expand_path(file)).relative_path_from(Pathname.new(Rails.root)).to_s
180
- files[key] << path if !files[key].include?(path)
181
- end
182
- files
183
- end
184
- end
185
-
186
- def i18n_lookup_pattern
187
- /\b(?:I18n\.t|I18n\.translate|t)(?:\s|\():?'([a-z0-9_]+.[a-z0-9_.]+)'\)?/
188
- end
189
-
190
- def files_to_scan
191
- Dir.glob(File.join(Translate::Storage.root_dir, "{app,config,lib}", "**","*.{rb,erb,rhtml}")) +
192
- Dir.glob(File.join(Translate::Storage.root_dir, "public", "javascripts", "**","*.js"))
193
- end
194
- end
1
+ require 'pathname'
2
+
3
+ class Translate::Keys
4
+ # Allows keys extracted from lookups in files to be cached
5
+ def self.files
6
+ @@files ||= Translate::Keys.new.files
7
+ end
8
+
9
+ # Allows flushing of the files cache
10
+ def self.files=(files)
11
+ @@files = files
12
+ end
13
+
14
+ def files
15
+ @files ||= extract_files
16
+ end
17
+ alias_method :to_hash, :files
18
+
19
+ def keys
20
+ files.keys
21
+ end
22
+ alias_method :to_a, :keys
23
+
24
+ def i18n_keys(locale)
25
+ I18n.backend.send(:init_translations) unless I18n.backend.initialized?
26
+ Translate::Keys.to_shallow_hash(I18n.backend.send(:translations)[locale.to_sym]).keys.sort
27
+ end
28
+
29
+ def duplicate_keys
30
+ Translate::Keys.translated_locales.inject({}) do |missing, locale|
31
+ missing[locale] = i18n_keys(I18n.default_locale).map do |key|
32
+ I18n.backend.send(:lookup, locale, key) == I18n.backend.send(:lookup, I18n.default_locale, key) ? key : nil
33
+ end.compact
34
+ missing
35
+ end
36
+ end
37
+
38
+ def untranslated_keys
39
+ Translate::Keys.translated_locales.inject({}) do |missing, locale|
40
+ missing[locale] = i18n_keys(I18n.default_locale).map do |key|
41
+ I18n.backend.send(:lookup, locale, key).nil? ? key : nil
42
+ end.compact
43
+ missing
44
+ end
45
+ end
46
+
47
+ def missing_keys
48
+ locale = I18n.default_locale; yaml_keys = {}
49
+ yaml_keys = Translate::Storage.file_paths(locale).inject({}) do |keys, path|
50
+ keys = keys.deep_merge(Translate::File.new(path).read[locale.to_s])
51
+ end
52
+ files.reject { |key, file| self.class.contains_key?(yaml_keys, key) }
53
+ end
54
+
55
+ def self.translated_locales
56
+ I18n.available_locales.reject { |locale| [:root, I18n.default_locale.to_sym].include?(locale) }
57
+ end
58
+
59
+ # Checks if a nested hash contains the keys in dot separated I18n key.
60
+ #
61
+ # Example:
62
+ #
63
+ # hash = {
64
+ # :foo => {
65
+ # :bar => {
66
+ # :baz => 1
67
+ # }
68
+ # }
69
+ # }
70
+ #
71
+ # contains_key?("foo", key) # => true
72
+ # contains_key?("foo.bar", key) # => true
73
+ # contains_key?("foo.bar.baz", key) # => true
74
+ # contains_key?("foo.bar.baz.bla", key) # => false
75
+ #
76
+ def self.contains_key?(hash, key)
77
+ keys = key.to_s.split(".")
78
+ return false if keys.empty?
79
+ !keys.inject(HashWithIndifferentAccess.new(hash)) do |memo, key|
80
+ memo.is_a?(Hash) ? memo.try(:[], key) : nil
81
+ end.nil?
82
+ end
83
+
84
+ # Convert something like:
85
+ #
86
+ # {
87
+ # :pressrelease => {
88
+ # :label => {
89
+ # :one => "Pressmeddelande"
90
+ # }
91
+ # }
92
+ # }
93
+ #
94
+ # to:
95
+ #
96
+ # {'pressrelease.label.one' => "Pressmeddelande"}
97
+ #
98
+ def self.to_shallow_hash(hash)
99
+ hash.inject({}) do |shallow_hash, (key, value)|
100
+ if value.is_a?(Hash)
101
+ to_shallow_hash(value).each do |sub_key, sub_value|
102
+ shallow_hash[[key, sub_key].join(".")] = sub_value
103
+ end
104
+ else
105
+ shallow_hash[key.to_s] = value
106
+ end
107
+ shallow_hash
108
+ end
109
+ end
110
+
111
+ # Convert something like:
112
+ #
113
+ # {'pressrelease.label.one' => "Pressmeddelande"}
114
+ #
115
+ # to:
116
+ #
117
+ # {
118
+ # :pressrelease => {
119
+ # :label => {
120
+ # :one => "Pressmeddelande"
121
+ # }
122
+ # }
123
+ # }
124
+ def self.to_deep_hash(hash)
125
+ hash.inject({}) do |deep_hash, (key, value)|
126
+ keys = key.to_s.split('.').reverse
127
+ leaf_key = keys.shift
128
+ key_hash = keys.inject({leaf_key.to_sym => value}) { |hash, key| {key.to_sym => hash} }
129
+ deep_merge!(deep_hash, key_hash)
130
+ deep_hash
131
+ end
132
+ end
133
+
134
+ # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
135
+ def self.deep_merge!(hash1, hash2)
136
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
137
+ hash1.merge!(hash2, &merger)
138
+ end
139
+
140
+ # Convert something like:
141
+ #
142
+ # {'0' => "elem 1", '1' => "elem 2"}
143
+ #
144
+ # to:
145
+ #
146
+ # ["elem 1", "elem 2"]
147
+ #
148
+ def self.arraylize(input_hash)
149
+ input_hash.inject([]) do |constructed_array, (key, value)|
150
+ constructed_array << value
151
+ constructed_array
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ def extract_files
158
+ files_to_scan.inject(HashWithIndifferentAccess.new) do |files, file|
159
+ keys = IO.read(file)
160
+ if keys.respond_to? "encode"
161
+ keys = keys.encode("UTF-8").force_encoding("UTF-8")
162
+ end
163
+ error_count = 0
164
+ begin
165
+ encoded_keys = keys.scan(i18n_lookup_pattern)
166
+ rescue => e
167
+ unless error_count > 1
168
+ if keys.respond_to? 'encode!'
169
+ keys.encode!('utf-8', 'utf-8', :invalid => :replace)
170
+ end
171
+ error_count += 1
172
+ retry
173
+ else
174
+ puts "cannot fix: #{e} on : #{file}"
175
+ end
176
+ end
177
+ encoded_keys.flatten.map(&:to_sym).each do |key|
178
+ files[key] ||= []
179
+ path = Pathname.new(File.expand_path(file)).relative_path_from(Pathname.new(Rails.root)).to_s
180
+ files[key] << path if !files[key].include?(path)
181
+ end
182
+ files
183
+ end
184
+ end
185
+
186
+ def i18n_lookup_pattern
187
+ /\b(?:I18n\.t|I18n\.translate|t)(?:\s|\():?'([a-z0-9_]+.[a-z0-9_.]+)'\)?/
188
+ end
189
+
190
+ def files_to_scan
191
+ Dir.glob(File.join(Translate::Storage.root_dir, "{app,config,lib}", "**","*.{rb,erb,rhtml}")) +
192
+ Dir.glob(File.join(Translate::Storage.root_dir, "public", "javascripts", "**","*.js"))
193
+ end
194
+ end