translate-rails3-plus 0.0.11 → 0.0.12

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