interpret 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,7 +23,7 @@ module Interpret
23
23
  tree = LazyHash.build_hash
24
24
  all_trans = all_trans.map{|x| x.key.split(".")[0..-2].join(".")}.uniq
25
25
  all_trans.each do |x|
26
- LazyHash.lazy_add(tree, x, {})
26
+ LazyHash.add(tree, x, {})
27
27
  end
28
28
 
29
29
  # Generate a new clean hash without the proc's from LazyHash.
@@ -38,7 +38,7 @@ module Interpret
38
38
  res = LazyHash.build_hash
39
39
 
40
40
  translations.each do |e|
41
- LazyHash.lazy_add(res, "#{e.locale}.#{e.key}", e.value)
41
+ LazyHash.add(res, "#{e.locale}.#{e.key}", e.value)
42
42
  end
43
43
  if res.keys.size != 1
44
44
  raise IndexError, "Generated hash must have only one root key. Your translation data in datrabase may be corrupted."
@@ -61,26 +61,20 @@ module Interpret
61
61
  raise ArgumentError, "the YAML file must contain an unique first key representing the locale" unless hash.keys.count == 1
62
62
 
63
63
  lang = hash.keys.first
64
- to_remove = locale(lang).all
65
- to_remove.each do |x|
66
- x.destroy
67
- end
64
+ delete_all(:locale => lang)
65
+
68
66
  records = parse_hash(hash.first[1], lang)
69
67
  # TODO: Replace with activerecord-import bulk inserts
70
68
  transaction do
71
- records.each {|x| x.save!}
69
+ records.each do |x|
70
+ x.save!
71
+ end
72
72
  end
73
73
  end
74
74
 
75
75
  # Dump all contents from *.yml locale files into the database.
76
76
  # CAUTION: All existing data will be erased!
77
77
  #
78
- # It will create a "#{locale}.yml.backup" file into config/locales
79
- # for each language present in the database, in case you want to
80
- # recover some of your just-erased translations.
81
- # If you don't want backups, set:
82
- #
83
- # Interpret.options[:dump_without_backup] = true
84
78
  def dump
85
79
  files = Dir[Rails.root.join("config", "locales", "*.yml").to_s]
86
80
  delete_all
@@ -139,18 +133,23 @@ module Interpret
139
133
  #
140
134
  # - First of all, get the locale keys for the main language from yml files.
141
135
  # - For all of these locale keys, do:
142
- # - If a key is present in the db, but not in the new ones, remove
143
- # it. You have removed it from the new content layout, so it's no longer
144
- # needed.
145
136
  # - If the key is not present in the db, it's new. So, create a new
146
- # entry for that key in each language. Look if a translation for that
147
- # key exists in yml files for each language, if it exists, use it. If
148
- # not, left it empty.
137
+ # entry for that key in the main language. If the key also exists in
138
+ # some other languages in yml files, also create the entry for that
139
+ # languages. But, do not create entries for the languages that does
140
+ # not have this key. Later you will be notified about that missing
141
+ # translations.
149
142
  # - If the key already exists in the db, do nothing. Maybe somone has
150
143
  # changed that content in production, and you don't want to lose
151
144
  # that. Or maybe you do want to change that content, because you
152
145
  # just added the correct sentence in the yml files. It's up to you to
153
146
  # do the right thing.
147
+ # Also, if the key is missing in other languages in database but
148
+ # present in yml files, create the new entry for that language.
149
+ # - If a key is present in the db, but not in the new ones, remove
150
+ # it. You have removed it from the new content layout, so it's no longer
151
+ # needed.
152
+ #
154
153
  def update
155
154
  files = Dir[Rails.root.join("config", "locales", "*.yml").to_s]
156
155
 
@@ -165,8 +164,7 @@ module Interpret
165
164
  end
166
165
  end
167
166
 
168
- @main = @languages[I18n.default_locale.to_s].clone
169
- sync(@main)
167
+ sync(@languages[I18n.default_locale.to_s])
170
168
  end
171
169
 
172
170
  private
@@ -178,16 +176,15 @@ module Interpret
178
176
  end
179
177
 
180
178
  hash.keys.each do |x|
181
- existing.delete(x)
182
-
183
179
  if hash[x].kind_of?(Hash)
184
180
  sync(hash[x], "#{prefix}#{x}.", existing[x])
185
181
  else
182
+ existing.delete(x)
186
183
  old = locale(I18n.default_locale).find_by_key("#{prefix}#{x}")
187
184
 
188
185
  unless old
189
186
  # Creates the new entry
190
- create_new_translation("#{prefix}#{x}")
187
+ create_new_translation("#{prefix}#{x}", hash[x])
191
188
  else
192
189
  # Check if the entry exists in the other languages
193
190
  check_in_other_langs("#{prefix}#{x}")
@@ -200,37 +197,33 @@ module Interpret
200
197
  end
201
198
  end
202
199
 
203
- # Check if the the given key exists in all languages except @main. If
204
- # not, create an entry.
200
+ # Check if the given key exists in @languages for locales other than
201
+ # I18n.default_locale. Create the existing ones.
205
202
  def check_in_other_langs(key)
206
203
  (@languages.keys - [I18n.default_locale]).each do |lang|
207
204
  trans = locale(lang).find_by_key(key)
208
205
  if trans.nil?
209
- create! :locale => lang,
210
- :key => key,
211
- :value => "untranslated"
212
- Interpret.logger.info "Created inexistent key [#{key}] for lang [#{lang}]"
206
+ if value = get_value_from_hash(@languages[lang], key)
207
+ create! :locale => lang, :key => key, :value => value
208
+ Interpret.logger.info "New key created [#{key}] for language [#{lang}]"
209
+ end
213
210
  end
214
211
  end
215
212
  end
216
213
 
217
- def create_new_translation(missing_key)
218
- @languages.keys.each do |lang|
219
- origin_hash = @languages[lang].clone
220
- value = nil
221
- missing_key.split(".")[0..-2].each do |key|
222
- if origin_hash[key].nil?
223
- value = "untranslated"
224
- break
225
- end
226
- origin_hash = origin_hash[key]
227
- end
228
- value ||= origin_hash[missing_key.split(".").last]
229
- create! :locale => lang,
230
- :key => missing_key,
231
- :value => value
214
+ def get_value_from_hash(hash, key)
215
+ key.split(".")[0..-2].each do |k|
216
+ break if hash.nil?
217
+ hash = hash[k]
232
218
  end
233
- Interpret.logger.info "New key created [#{missing_key}] for languages #{@languages.keys.inspect}"
219
+ hash.nil? ? nil : hash[key.split(".").last]
220
+ end
221
+
222
+ def create_new_translation(missing_key, main_value)
223
+ create! :locale => I18n.default_locale, :key => missing_key, :value => main_value
224
+ Interpret.logger.info "New key created [#{missing_key}] for language [#{I18n.default_locale}]"
225
+
226
+ check_in_other_langs(missing_key)
234
227
  end
235
228
 
236
229
  def remove_unused_keys(hash, prefix = "")
data/interpret.gemspec CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  s.add_dependency "ya2yaml", ">= 0.30.0"
26
26
  s.add_dependency "will_paginate", ">= 3.0.pre2"
27
27
  s.add_dependency "best_in_place", ">= 0.1.7"
28
+ s.add_dependency "lazyhash", ">= 0.1.1"
28
29
 
29
30
  s.add_development_dependency "rspec-rails", "~> 2.5"
30
31
  end
data/lib/interpret.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'best_in_place'
2
2
  require 'will_paginate'
3
- require 'interpret/lazy_hash'
3
+ require 'lazyhash'
4
4
 
5
5
  module Interpret
6
6
  mattr_accessor :backend
@@ -1,3 +1,3 @@
1
1
  module Interpret
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Interpret::Translation do
@@ -7,6 +8,7 @@ en:
7
8
  p1: Hello world!
8
9
  folder1:
9
10
  pr1: Hi
11
+ content: Some large text content
10
12
  folder2:
11
13
  pr1: Some other text here
12
14
  folder3:
@@ -20,19 +22,93 @@ en:
20
22
  """
21
23
  }
22
24
 
25
+ let(:es_yml) {"""
26
+ es:
27
+ folder2:
28
+ pr1: Algun otro texto aqui
29
+ content: Un largo parrafo con contenido
30
+ folder3:
31
+ pr1: Mas frases aleatorias
32
+ sub:
33
+ name: Esta es una subcarpeta de segundo nivel
34
+ subsub:
35
+ name: Con otra carpeta anidada en su interior
36
+ other:
37
+ name: carpeta
38
+ """
39
+ }
40
+
41
+ let(:new_en_yml) {"""
42
+ en:
43
+ p1: Hello modified world! This new translation should not be copied into database
44
+ new_key: This new key should be created with this english text
45
+ new_key_in_en: This new key that only exists in english should be created only in english
46
+
47
+ folder1:
48
+ pr1: Hi
49
+ folder2:
50
+ pr1: Some other text here
51
+ folder3:
52
+ pr1: More phrases
53
+ sub:
54
+ name: This is a 2 level subfolder
55
+ subsub:
56
+ name: With another nested folder inside
57
+ other:
58
+ name: folder
59
+ """
60
+ }
61
+
62
+ let(:new_es_yml) {"""
63
+ es:
64
+ p1: Hola mon! Esta nueva traduccion al español deberia copiarse en base de datos porque no existe previamente en :es, aunque si en :en
65
+ new_key: Esta nueva clave debe crearse con este texto en español
66
+
67
+ folder1:
68
+ pr1: Nueva traduccion que tambien debe copiarse
69
+ folder2:
70
+ pr1: Algun otro texto aqui
71
+ content: Un largo parrafo con contenido
72
+ folder3:
73
+ pr1: Mas frases aleatorias
74
+ sub:
75
+ name: Esta es una subcarpeta de segundo nivel
76
+ subsub:
77
+ name: Con otra carpeta anidada en su interior
78
+ other:
79
+ name: carpeta
80
+ """
81
+ }
82
+
83
+ # Convert a locale file into database translations
23
84
  def file2db(string_file)
24
- hash = YAML.load string_file
85
+ def parse_hash(dict, locale, prefix = "")
86
+ res = []
87
+ dict.keys.each do |x|
88
+ if dict[x].kind_of?(Hash)
89
+ res += parse_hash(dict[x], locale, "#{prefix}#{x}.")
90
+ else
91
+ res << Interpret::Translation.new(:locale => locale, :key => "#{prefix}#{x}", :value => dict[x])
92
+ end
93
+ end
94
+ res
95
+ end
25
96
 
97
+ hash = YAML.load string_file
26
98
  lang = hash.keys.first
27
- records = Interpret::Translation.send(:parse_hash, hash.first[1], lang)
28
99
  Interpret::Translation.transaction do
29
- records.each {|x| x.save!}
100
+ parse_hash(hash.first[1], lang).map{|x| x.save!}
30
101
  end
31
102
  end
32
103
 
104
+ before do
105
+ I18n.stub!(:default_locale).and_return('en')
106
+ end
107
+
33
108
  describe ".get_tree" do
34
109
  it "should return a hash representing a tree folder structure of the i18n keys" do
35
110
  file2db(en_yml)
111
+
36
112
  Interpret::Translation.get_tree('en').should == {'index' => {
37
113
  'folder1' => {},
38
114
  'folder2' => {},
@@ -49,20 +125,114 @@ en:
49
125
  describe ".export" do
50
126
  it "should return a hash representing the yml locale file for the given translations" do
51
127
  file2db(en_yml)
128
+
52
129
  translations = Interpret::Translation.all
53
130
  Interpret::Translation.export(translations).should == YAML.load(en_yml)
54
131
  end
55
132
  end
56
133
 
57
- describe ".import" do
58
- pending
134
+ describe ".update" do
135
+ before(:all) do
136
+ # Supose the database has the default contents, look at the top of this
137
+ # file for en_yml simulated locale file
138
+ file2db(en_yml)
139
+ file2db(es_yml)
140
+ end
141
+
142
+ before do
143
+ Dir.stub!(:"[]").and_return(['/path/to/en.yml', '/path/to/es.yml'])
144
+ YAML.should_receive(:load_file).twice.and_return(YAML.load(new_en_yml), YAML.load(new_es_yml))
145
+ end
146
+
147
+ context "when a key exists in database but not in yml files [for I18n.default_locale]" do
148
+ it "should remove that key from database for I18n.default_locale" do
149
+ Interpret::Translation.update
150
+ Interpret::Translation.locale('en').find_by_key("folder1.content").should be_nil
151
+ end
152
+
153
+ it "should remove that key if it exists for any other language in database" do
154
+ Interpret::Translation.update
155
+ Interpret::Translation.locale('es').find_by_key("folder1.content").should be_nil
156
+ end
157
+ end
158
+
159
+ context "when a key exists in yml files but not in database [for I18.default_locale]" do
160
+ it "should create the key for I18n.default_locale with the value from yml files" do
161
+ Interpret::Translation.update
162
+ translation = Interpret::Translation.locale('en').find_by_key("new_key")
163
+ translation.value.should == "This new key should be created with this english text"
164
+ end
165
+
166
+ it "should not create an entry for a key in a language that do not have it" do
167
+ Interpret::Translation.update
168
+ Interpret::Translation.locale('es').find_by_key("new_key_in_en").should be_nil
169
+ end
170
+
171
+ it "should look for that key in other languages from yml files and create the existing ones." do
172
+ Interpret::Translation.update
173
+ translation = Interpret::Translation.locale('es').find_by_key("new_key")
174
+ translation.value.should == "Esta nueva clave debe crearse con este texto en español"
175
+ end
176
+ end
177
+
178
+ context "when a key exists in both yml files and database [for I18n.default_locale]" do
179
+ it "should not override the contents of the existing database translations" do
180
+ Interpret::Translation.update
181
+ translation = Interpret::Translation.locale('en').find_by_key("p1")
182
+ translation.value.should == "Hello world!"
183
+ end
184
+
185
+ it "should check if there is a language (other than I18n.default_locale) for which that key is new, and create the entry." do
186
+ Interpret::Translation.update
187
+ translation = Interpret::Translation.locale('es').find_by_key("p1").should_not be_nil
188
+ end
189
+ end
59
190
  end
60
191
 
61
192
  describe ".dump" do
62
- pending
193
+ it "should dump all contents from yml files into database" do
194
+ # Initial database state
195
+ file2db(en_yml)
196
+ file2db(es_yml)
197
+
198
+ Dir.stub!(:"[]").and_return(['/path/to/en.yml', '/path/to/es.yml'])
199
+ YAML.should_receive(:load_file).twice.and_return(YAML.load(new_en_yml), YAML.load(new_es_yml))
200
+ Interpret::Translation.dump
201
+
202
+ # We use export to check for the existing database contents, which is
203
+ # also tested in this spec file
204
+ en_trans = Interpret::Translation.locale('en').all
205
+ Interpret::Translation.export(en_trans).should == YAML.load(new_en_yml)
206
+
207
+ es_trans = Interpret::Translation.locale('es').all
208
+ Interpret::Translation.export(es_trans).should == YAML.load(new_es_yml)
209
+ end
63
210
  end
64
211
 
65
- describe ".update" do
66
- pending
212
+ describe ".import" do
213
+ before do
214
+ @file = new_en_yml
215
+ end
216
+
217
+ it "should dump the contents for the given file into database" do
218
+ file2db(en_yml)
219
+ @file.stub!(:content_type).and_return("text/plain")
220
+ Interpret::Translation.import(@file)
221
+
222
+ en_trans = Interpret::Translation.locale('en').all
223
+ Interpret::Translation.export(en_trans).should == YAML.load(new_en_yml)
224
+ end
225
+
226
+ it "should not modify the database contents for other languages" do
227
+ Interpret::Translation.delete_all
228
+ file2db(en_yml)
229
+ file2db(es_yml)
230
+
231
+ @file.stub!(:content_type).and_return("text/plain")
232
+ Interpret::Translation.import(@file)
233
+
234
+ es_trans = Interpret::Translation.locale('es').all
235
+ Interpret::Translation.export(es_trans).should == YAML.load(es_yml)
236
+ end
67
237
  end
68
238
  end
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interpret
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 2
9
- version: 0.1.2
4
+ prerelease:
5
+ version: 0.1.3
10
6
  platform: ruby
11
7
  authors:
12
8
  - Roger Campos
@@ -14,7 +10,7 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2011-02-15 00:00:00 +01:00
13
+ date: 2011-02-18 00:00:00 +01:00
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
@@ -25,10 +21,6 @@ dependencies:
25
21
  requirements:
26
22
  - - ~>
27
23
  - !ruby/object:Gem::Version
28
- segments:
29
- - 3
30
- - 0
31
- - 3
32
24
  version: 3.0.3
33
25
  type: :runtime
34
26
  version_requirements: *id001
@@ -40,10 +32,6 @@ dependencies:
40
32
  requirements:
41
33
  - - ~>
42
34
  - !ruby/object:Gem::Version
43
- segments:
44
- - 0
45
- - 5
46
- - 0
47
35
  version: 0.5.0
48
36
  type: :runtime
49
37
  version_requirements: *id002
@@ -55,8 +43,6 @@ dependencies:
55
43
  requirements:
56
44
  - - ">="
57
45
  - !ruby/object:Gem::Version
58
- segments:
59
- - 0
60
46
  version: "0"
61
47
  type: :runtime
62
48
  version_requirements: *id003
@@ -68,10 +54,6 @@ dependencies:
68
54
  requirements:
69
55
  - - ">="
70
56
  - !ruby/object:Gem::Version
71
- segments:
72
- - 0
73
- - 30
74
- - 0
75
57
  version: 0.30.0
76
58
  type: :runtime
77
59
  version_requirements: *id004
@@ -83,10 +65,6 @@ dependencies:
83
65
  requirements:
84
66
  - - ">="
85
67
  - !ruby/object:Gem::Version
86
- segments:
87
- - 3
88
- - 0
89
- - pre2
90
68
  version: 3.0.pre2
91
69
  type: :runtime
92
70
  version_requirements: *id005
@@ -98,27 +76,31 @@ dependencies:
98
76
  requirements:
99
77
  - - ">="
100
78
  - !ruby/object:Gem::Version
101
- segments:
102
- - 0
103
- - 1
104
- - 7
105
79
  version: 0.1.7
106
80
  type: :runtime
107
81
  version_requirements: *id006
108
82
  - !ruby/object:Gem::Dependency
109
- name: rspec-rails
83
+ name: lazyhash
110
84
  prerelease: false
111
85
  requirement: &id007 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 0.1.1
91
+ type: :runtime
92
+ version_requirements: *id007
93
+ - !ruby/object:Gem::Dependency
94
+ name: rspec-rails
95
+ prerelease: false
96
+ requirement: &id008 !ruby/object:Gem::Requirement
112
97
  none: false
113
98
  requirements:
114
99
  - - ~>
115
100
  - !ruby/object:Gem::Version
116
- segments:
117
- - 2
118
- - 5
119
101
  version: "2.5"
120
102
  type: :development
121
- version_requirements: *id007
103
+ version_requirements: *id008
122
104
  description: Manage your app translations with an i18n active_record backend
123
105
  email:
124
106
  - roger@itnig.net
@@ -157,7 +139,6 @@ files:
157
139
  - lib/interpret/capistrano.rb
158
140
  - lib/interpret/engine.rb
159
141
  - lib/interpret/helpers.rb
160
- - lib/interpret/lazy_hash.rb
161
142
  - lib/interpret/logger.rb
162
143
  - lib/interpret/version.rb
163
144
  - lib/tasks/interpret.rake
@@ -235,21 +216,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
235
216
  requirements:
236
217
  - - ">="
237
218
  - !ruby/object:Gem::Version
238
- segments:
239
- - 0
240
219
  version: "0"
241
220
  required_rubygems_version: !ruby/object:Gem::Requirement
242
221
  none: false
243
222
  requirements:
244
223
  - - ">="
245
224
  - !ruby/object:Gem::Version
246
- segments:
247
- - 0
248
225
  version: "0"
249
226
  requirements: []
250
227
 
251
228
  rubyforge_project: interpret
252
- rubygems_version: 1.3.7
229
+ rubygems_version: 1.5.2
253
230
  signing_key:
254
231
  specification_version: 3
255
232
  summary: Manage your app translations with an i18n active_record backend
@@ -1,21 +0,0 @@
1
- # Gist from: https://gist.github.com/745617
2
- module LazyHash
3
- class << self
4
- def lazy_add(hash, key, value, pre = nil)
5
- skeys = key.split(".")
6
- f = skeys.shift
7
- if skeys.empty?
8
- pre.nil? ? hash.send("[]=", f, value) : pre.send("[]=", f, value)
9
- else
10
- pre = pre.nil? ? hash.send("[]", f) : pre.send("[]", f)
11
- lazy_add(hash, skeys.join("."), value, pre)
12
- end
13
- end
14
-
15
- def build_hash
16
- lazy = lambda { |h,k| h[k] = Hash.new(&lazy) }
17
- Hash.new(&lazy)
18
- end
19
- end
20
- end
21
-