translatomatic 0.1.1 → 0.1.2
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/.gitattributes +19 -0
- data/.gitignore +0 -0
- data/.travis.yml +7 -7
- data/.yardopts +9 -0
- data/Gemfile +4 -4
- data/Guardfile +0 -0
- data/README.de.md +61 -16
- data/README.es.md +60 -15
- data/README.fr.md +61 -16
- data/README.it.md +60 -15
- data/README.ja.md +59 -14
- data/README.ko.md +137 -0
- data/README.md +58 -13
- data/README.ms.md +137 -0
- data/README.pt.md +137 -0
- data/README.ru.md +137 -0
- data/README.sv.md +137 -0
- data/README.zh.md +137 -0
- data/bin/setup +8 -8
- data/bin/translatomatic +6 -6
- data/bin/travis +1 -1
- data/config/locales/translatomatic/de.yml +104 -0
- data/config/locales/translatomatic/en.yml +101 -0
- data/config/locales/translatomatic/es.yml +105 -0
- data/config/locales/translatomatic/fr.yml +105 -0
- data/config/locales/translatomatic/it.yml +103 -0
- data/config/locales/translatomatic/ja.yml +102 -0
- data/config/locales/translatomatic/ko.yml +101 -0
- data/config/locales/translatomatic/ms.yml +103 -0
- data/config/locales/translatomatic/pt.yml +105 -0
- data/config/locales/translatomatic/ru.yml +103 -0
- data/config/locales/translatomatic/sv.yml +103 -0
- data/config/locales/translatomatic/zh.yml +102 -0
- data/db/migrate/201712170000_initial.rb +2 -1
- data/lib/translatomatic/cli/base.rb +73 -0
- data/lib/translatomatic/cli/common_options.rb +14 -0
- data/lib/translatomatic/cli/config.rb +81 -0
- data/lib/translatomatic/cli/database.rb +29 -0
- data/lib/translatomatic/cli/main.rb +112 -0
- data/lib/translatomatic/cli/translate.rb +146 -0
- data/lib/translatomatic/cli.rb +8 -216
- data/lib/translatomatic/config.rb +143 -0
- data/lib/translatomatic/converter.rb +196 -149
- data/lib/translatomatic/converter_stats.rb +18 -14
- data/lib/translatomatic/database.rb +35 -37
- data/lib/translatomatic/escaped_unicode.rb +1 -1
- data/lib/translatomatic/extractor/base.rb +2 -0
- data/lib/translatomatic/extractor/ruby.rb +1 -0
- data/lib/translatomatic/extractor.rb +1 -0
- data/lib/translatomatic/http_request.rb +43 -14
- data/lib/translatomatic/locale.rb +28 -4
- data/lib/translatomatic/logger.rb +21 -13
- data/lib/translatomatic/model/locale.rb +5 -1
- data/lib/translatomatic/model/text.rb +2 -0
- data/lib/translatomatic/model.rb +1 -0
- data/lib/translatomatic/option.rb +75 -10
- data/lib/translatomatic/progress_updater.rb +7 -3
- data/lib/translatomatic/resource_file/base.rb +41 -18
- data/lib/translatomatic/resource_file/html.rb +11 -14
- data/lib/translatomatic/resource_file/markdown.rb +13 -12
- data/lib/translatomatic/resource_file/plist.rb +3 -14
- data/lib/translatomatic/resource_file/properties.rb +21 -3
- data/lib/translatomatic/resource_file/resw.rb +1 -0
- data/lib/translatomatic/resource_file/text.rb +1 -0
- data/lib/translatomatic/resource_file/xcode_strings.rb +23 -14
- data/lib/translatomatic/resource_file/xml.rb +34 -22
- data/lib/translatomatic/resource_file/yaml.rb +39 -5
- data/lib/translatomatic/resource_file.rb +7 -5
- data/lib/translatomatic/string.rb +40 -12
- data/lib/translatomatic/tmx/document.rb +11 -12
- data/lib/translatomatic/tmx/translation_unit.rb +5 -1
- data/lib/translatomatic/tmx.rb +2 -0
- data/lib/translatomatic/translation.rb +30 -0
- data/lib/translatomatic/translation_result.rb +45 -45
- data/lib/translatomatic/translator/base.rb +128 -83
- data/lib/translatomatic/translator/frengly.rb +62 -57
- data/lib/translatomatic/translator/google.rb +35 -31
- data/lib/translatomatic/translator/microsoft.rb +41 -33
- data/lib/translatomatic/translator/my_memory.rb +68 -64
- data/lib/translatomatic/translator/yandex.rb +56 -39
- data/lib/translatomatic/translator.rb +99 -63
- data/lib/translatomatic/util.rb +31 -1
- data/lib/translatomatic/version.rb +4 -1
- data/lib/translatomatic.rb +17 -0
- data/translatomatic.gemspec +5 -4
- metadata +56 -16
@@ -1,171 +1,216 @@
|
|
1
|
+
# The converter ties together functionality from translators,
|
2
|
+
# resource files, and the database to convert files from one
|
3
|
+
# language to another.
|
1
4
|
class Translatomatic::Converter
|
2
5
|
|
3
|
-
|
4
|
-
attr_reader :options
|
5
|
-
private
|
6
|
-
include Translatomatic::DefineOptions
|
7
|
-
end
|
8
|
-
|
9
|
-
define_options(
|
10
|
-
{ name: :translator, type: :string, aliases: "-t",
|
11
|
-
desc: "Translator implementation to use",
|
12
|
-
enum: Translatomatic::Translator.names },
|
13
|
-
{ name: :dry_run, type: :boolean, aliases: "-n", desc:
|
14
|
-
"Print actions without performing translations or writing files" },
|
15
|
-
{ name: :use_database, type: :boolean, default: true, desc:
|
16
|
-
"Store and retrieve translations in the database" }
|
17
|
-
)
|
18
|
-
|
19
|
-
# @return [Translatomatic::ConverterStats] translation statistics
|
20
|
-
attr_reader :stats
|
21
|
-
|
22
|
-
# @return [Array<Translatomatic::Model::Text>] A list of translations saved to the database
|
6
|
+
# @return [Array<Translatomatic::Model::Text>] A list of translations saved to the database
|
23
7
|
attr_reader :db_translations
|
24
8
|
|
25
9
|
# Create a converter to translate files
|
26
10
|
#
|
27
|
-
# @param options
|
11
|
+
# @param options [Hash<Symbol,Object>] converter and/or translator options.
|
28
12
|
def initialize(options = {})
|
29
13
|
@dry_run = options[:dry_run]
|
30
|
-
@
|
31
|
-
@
|
32
|
-
|
33
|
-
|
34
|
-
use_db = options.include?(:use_database) ? options[:use_database] : true
|
35
|
-
@use_db = use_db && ActiveRecord::Base.connected?
|
14
|
+
@listener = options[:listener]
|
15
|
+
@translators = Translatomatic::Translator.resolve(options[:translator], options)
|
16
|
+
raise t("converter.translator_required") if @translators.empty?
|
17
|
+
@translators.each { |i| i.listener = @listener } if @listener
|
36
18
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@
|
44
|
-
|
45
|
-
@from_translator = 0
|
46
|
-
@db_translations = []
|
47
|
-
end
|
19
|
+
# use database by default if we're connected to a database
|
20
|
+
use_db = options.include?(:use_database) ? options[:use_database] : true
|
21
|
+
@use_db = use_db && ActiveRecord::Base.connected?
|
22
|
+
log.debug(t("converter.database_disabled")) unless @use_db
|
23
|
+
|
24
|
+
@db_translations = []
|
25
|
+
@translations = {} # map of original text to Translation
|
26
|
+
end
|
48
27
|
|
49
28
|
# @return [Translatomatic::ConverterStats] Translation statistics
|
50
29
|
def stats
|
51
|
-
Translatomatic::ConverterStats.new(@
|
30
|
+
@stats ||= Translatomatic::ConverterStats.new(@translations)
|
52
31
|
end
|
53
32
|
|
54
|
-
# Translate
|
55
|
-
#
|
33
|
+
# Translate properties of source_file to the target locale.
|
34
|
+
# Does not write changes to disk.
|
56
35
|
#
|
57
|
-
# @param [String, Translatomatic::ResourceFile]
|
58
|
-
# @param [String]
|
36
|
+
# @param file [String, Translatomatic::ResourceFile] File to translate
|
37
|
+
# @param to_locale [String] The target locale, e.g. "fr"
|
59
38
|
# @return [Translatomatic::ResourceFile] The translated resource file
|
60
|
-
def translate(
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
log.info("translating #{source} to #{target}")
|
83
|
-
properties = translate_properties(source.properties, source.locale, target.locale)
|
84
|
-
target.properties = properties
|
85
|
-
unless @dry_run
|
86
|
-
target.path.parent.mkpath
|
87
|
-
target.save
|
88
|
-
end
|
89
|
-
target
|
39
|
+
def translate(file, to_locale)
|
40
|
+
file = resource_file(file)
|
41
|
+
to_locale = parse_locale(to_locale)
|
42
|
+
|
43
|
+
# do nothing if target language is the same as source language
|
44
|
+
return file if file.locale.language == to_locale.language
|
45
|
+
|
46
|
+
result = Translatomatic::TranslationResult.new(file, to_locale)
|
47
|
+
|
48
|
+
# translate using strings from the database first
|
49
|
+
each_translator(result) { translate_properties_with_db(result) }
|
50
|
+
# send remaining unknown strings to translator
|
51
|
+
each_translator(result) { translate_properties_with_translator(result) }
|
52
|
+
|
53
|
+
log.debug(t("converter.stats", from_db: stats.from_db,
|
54
|
+
from_translator: stats.from_translator,
|
55
|
+
untranslated: result.untranslated.length))
|
56
|
+
@listener.untranslated_texts(result.untranslated) if @listener
|
57
|
+
|
58
|
+
file.properties = result.properties
|
59
|
+
file.locale = to_locale
|
60
|
+
file
|
90
61
|
end
|
91
|
-
|
92
|
-
# Translate values in the hash of properties.
|
93
|
-
# Uses existing translations from the database if available.
|
94
|
-
#
|
95
|
-
# @param [Hash] properties Text to translate
|
96
|
-
# @param [String, Locale] from_locale The locale of the given properties
|
97
|
-
# @param [String, Locale] to_locale The target locale for translations
|
98
|
-
# @return [Hash] Translated properties
|
99
|
-
def translate_properties(properties, from_locale, to_locale)
|
100
|
-
from_locale = parse_locale(from_locale)
|
101
|
-
to_locale = parse_locale(to_locale)
|
102
|
-
|
103
|
-
# sanity check
|
104
|
-
return properties if from_locale.language == to_locale.language
|
105
|
-
|
106
|
-
result = Translatomatic::TranslationResult.new(properties,
|
107
|
-
from_locale, to_locale)
|
108
62
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
63
|
+
# Translates a resource file and writes results to a target resource file.
|
64
|
+
# The path of the target resource file is automatically determined.
|
65
|
+
#
|
66
|
+
# @param source [Translatomatic::ResourceFile] The source
|
67
|
+
# @param to_locale [String] The target locale, e.g. "fr"
|
68
|
+
# @return [Translatomatic::ResourceFile] The translated resource file
|
69
|
+
def translate_to_file(source, to_locale)
|
70
|
+
# Automatically determines the target filename based on target locale.
|
71
|
+
source = resource_file(source)
|
72
|
+
target = Translatomatic::ResourceFile.load(source.path)
|
73
|
+
target.path = source.locale_path(to_locale)
|
74
|
+
|
75
|
+
log.info(t("converter.translating", source: source,
|
76
|
+
source_locale: source.locale, target: target, target_locale: to_locale))
|
77
|
+
translate(target, to_locale)
|
78
|
+
unless @dry_run
|
79
|
+
target.path.parent.mkpath
|
80
|
+
target.save
|
81
|
+
end
|
82
|
+
target
|
120
83
|
end
|
121
84
|
|
122
|
-
private
|
85
|
+
private
|
123
86
|
|
124
|
-
include Translatomatic::Util
|
87
|
+
include Translatomatic::Util
|
88
|
+
include Translatomatic::DefineOptions
|
125
89
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
90
|
+
define_options(
|
91
|
+
{ name: :dry_run, type: :boolean, aliases: "-n",
|
92
|
+
desc: t("converter.dry_run")
|
93
|
+
},
|
94
|
+
{ name: :use_database, type: :boolean, default: true,
|
95
|
+
desc: t("converter.use_database")
|
96
|
+
}
|
97
|
+
)
|
133
98
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
99
|
+
def each_translator(result)
|
100
|
+
@translators.each do |translator|
|
101
|
+
break if result.untranslated.empty?
|
102
|
+
@current_translator = translator
|
103
|
+
yield
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Attempt to restore interpolated variable names in the translation.
|
108
|
+
# If variable names cannot be restored, sets the translation result to nil.
|
109
|
+
# @param result [Translatomatic::TranslationResult] translation result
|
110
|
+
# @param translation [Translatomatic::Translation] translation
|
111
|
+
# @return [void]
|
112
|
+
def restore_variables(result, translation)
|
113
|
+
file = result.file
|
114
|
+
return unless file.supports_variable_interpolation?
|
115
|
+
|
116
|
+
# find variables in the original string
|
117
|
+
variables = string_variables(translation.original, file.locale, file)
|
118
|
+
# find variables in the translated string
|
119
|
+
translated_variables = string_variables(translation.result, result.to_locale, file)
|
120
|
+
|
121
|
+
if variables.length == translated_variables.length
|
122
|
+
# we can restore variables. sort by largest offset first.
|
123
|
+
# not using translation() method as that adds to @translations hash.
|
124
|
+
conversions = variables.zip(translated_variables).collect {
|
125
|
+
|v1, v2| Translatomatic::Translation.new(v1, v2)
|
126
|
+
}
|
127
|
+
conversions.sort_by! { |t| -t.original.offset }
|
128
|
+
conversions.each do |conversion|
|
129
|
+
v1 = conversion.original
|
130
|
+
v2 = conversion.result
|
131
|
+
translation.result[v2.offset, v2.length] = v1.value
|
138
132
|
end
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
@listener.translated_texts(db_texts) if @listener
|
133
|
+
else
|
134
|
+
# unable to restore interpolated variable names
|
135
|
+
log.debug("#{@current_translator.name}: unable to restore variables: #{translation.result}")
|
136
|
+
translation.result = nil # mark result as invalid
|
144
137
|
end
|
145
|
-
db_texts
|
146
138
|
end
|
147
139
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
140
|
+
def string_variables(value, locale, file)
|
141
|
+
string(value, locale).substrings(file.variable_regex)
|
142
|
+
end
|
143
|
+
|
144
|
+
def resource_file(path)
|
145
|
+
if path.kind_of?(Translatomatic::ResourceFile::Base)
|
146
|
+
path
|
147
|
+
else
|
148
|
+
file = Translatomatic::ResourceFile.load(path)
|
149
|
+
raise t("converter.file_unsupported", file: path) unless file
|
150
|
+
file
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# update result with translations from the database.
|
155
|
+
def translate_properties_with_db(result)
|
156
|
+
db_texts = []
|
157
|
+
unless database_disabled?
|
158
|
+
translations = []
|
159
|
+
untranslated = hashify(result.untranslated)
|
160
|
+
db_texts = find_database_translations(result, result.untranslated.to_a)
|
161
|
+
db_texts.each do |db_text|
|
162
|
+
from_text = db_text.from_text.value
|
163
|
+
if untranslated[from_text]
|
164
|
+
translation = translation(untranslated[from_text], db_text.value, true)
|
165
|
+
restore_variables(result, translation)
|
166
|
+
translations << translation
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
result.update_strings(translations)
|
171
|
+
@listener.translated_texts(db_texts) if @listener
|
172
|
+
end
|
173
|
+
db_texts
|
174
|
+
end
|
175
|
+
|
176
|
+
# update result with translations from the translator.
|
177
|
+
def translate_properties_with_translator(result)
|
178
|
+
untranslated = result.untranslated.to_a.select { |i| translatable?(i) }
|
152
179
|
translated = []
|
153
|
-
@from_translator += untranslated.length
|
154
180
|
if !untranslated.empty? && !@dry_run
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
181
|
+
untranslated_strings = untranslated.collect { |i| i.to_s }
|
182
|
+
log.debug("translating: #{untranslated_strings}")
|
183
|
+
translated = @current_translator.translate(untranslated_strings,
|
184
|
+
result.from_locale, result.to_locale
|
185
|
+
)
|
186
|
+
|
187
|
+
# create list of translations, filtering out invalid translations
|
188
|
+
translations = []
|
189
|
+
untranslated.zip(translated).each do |from, to|
|
190
|
+
translation = translation(from, to, false)
|
191
|
+
restore_variables(result, translation)
|
192
|
+
translations << translation
|
160
193
|
end
|
161
|
-
|
162
|
-
|
194
|
+
|
195
|
+
result.update_strings(translations)
|
196
|
+
unless database_disabled?
|
197
|
+
save_database_translations(result, translations)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
translated
|
163
201
|
end
|
164
202
|
|
165
|
-
def
|
166
|
-
|
203
|
+
def translation(from, to, from_database = false)
|
204
|
+
translator = @current_translator.name
|
205
|
+
t = Translatomatic::Translation.new(from, to, translator, from_database)
|
206
|
+
@translations[from] = t
|
207
|
+
t
|
167
208
|
end
|
168
209
|
|
210
|
+
def database_disabled?
|
211
|
+
!@use_db
|
212
|
+
end
|
213
|
+
|
169
214
|
def parse_locale(locale)
|
170
215
|
Translatomatic::Locale.parse(locale)
|
171
216
|
end
|
@@ -175,42 +220,44 @@ class Translatomatic::Converter
|
|
175
220
|
!string.empty? && !string.match(/^[\d,]+$/)
|
176
221
|
end
|
177
222
|
|
178
|
-
def save_database_translations(result,
|
223
|
+
def save_database_translations(result, translations)
|
179
224
|
ActiveRecord::Base.transaction do
|
180
225
|
from = db_locale(result.from_locale)
|
181
226
|
to = db_locale(result.to_locale)
|
182
|
-
|
183
|
-
|
227
|
+
translations.each do |translation|
|
228
|
+
next if translation.result.nil? # skip invalid translations
|
229
|
+
save_database_translation(from, to, translation)
|
184
230
|
end
|
185
231
|
end
|
186
232
|
end
|
187
233
|
|
188
|
-
def save_database_translation(from_locale, to_locale,
|
234
|
+
def save_database_translation(from_locale, to_locale, translation)
|
189
235
|
original_text = Translatomatic::Model::Text.find_or_create_by!(
|
190
236
|
locale: from_locale,
|
191
|
-
value:
|
237
|
+
value: translation.original.to_s
|
192
238
|
)
|
193
239
|
|
194
240
|
text = Translatomatic::Model::Text.find_or_create_by!(
|
195
241
|
locale: to_locale,
|
196
|
-
value:
|
242
|
+
value: translation.result.to_s,
|
197
243
|
from_text: original_text,
|
198
|
-
translator: @
|
199
|
-
)
|
200
|
-
@db_translations += [original_text, text]
|
244
|
+
translator: @current_translator.name
|
245
|
+
)
|
246
|
+
@db_translations += [original_text, text]
|
201
247
|
text
|
202
248
|
end
|
203
249
|
|
204
250
|
def find_database_translations(result, untranslated)
|
205
251
|
from = db_locale(result.from_locale)
|
206
252
|
to = db_locale(result.to_locale)
|
207
|
-
|
208
|
-
# convert untranslated set to strings
|
253
|
+
|
209
254
|
Translatomatic::Model::Text.where({
|
210
|
-
locale: to,
|
211
|
-
|
212
|
-
|
213
|
-
|
255
|
+
locale: to,
|
256
|
+
translator: @current_translator.name,
|
257
|
+
from_texts_texts: {
|
258
|
+
locale_id: from,
|
259
|
+
# convert untranslated set to strings
|
260
|
+
value: untranslated.collect { |i| i.to_s }
|
214
261
|
}
|
215
262
|
}).joins(:from_text)
|
216
263
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# Translation statistics
|
2
2
|
class Translatomatic::ConverterStats
|
3
|
+
include Translatomatic::Util
|
3
4
|
|
4
|
-
# @return [
|
5
|
+
# @return [Array<Translatomatic::Translation>] A list of all translations
|
5
6
|
attr_reader :translations
|
6
7
|
|
7
8
|
# @return [Number] The number of translations that came from the database.
|
@@ -9,19 +10,22 @@ class Translatomatic::ConverterStats
|
|
9
10
|
|
10
11
|
# @return [Number] The number of translations that came from the translator.
|
11
12
|
attr_reader :from_translator
|
13
|
+
|
14
|
+
# @return [Number] The number of untranslated strings
|
15
|
+
attr_reader :untranslated
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def initialize(translations)
|
20
|
+
@translations = translations.values
|
21
|
+
@from_db = @translations.count { |i| i.from_database && i.result }
|
22
|
+
@from_translator = @translations.count { |i| !i.from_database && i.result }
|
23
|
+
@untranslated = @translations.count { |i| i.result == nil }
|
24
|
+
end
|
12
25
|
|
13
|
-
def
|
14
|
-
@translations
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def +(other)
|
20
|
-
self.class.new(@from_db + other.from_db, @from_translator + other.from_translator)
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_s
|
24
|
-
"Total translations: #{@translations} " +
|
25
|
-
"(#{@from_db} from database, #{@from_translator} from translator)"
|
26
|
+
def to_s
|
27
|
+
t("converter.total_translations", total: @translations.length,
|
28
|
+
from_db: @from_db, from_translator: @from_translator,
|
29
|
+
untranslated: @untranslated)
|
26
30
|
end
|
27
31
|
end
|
@@ -1,29 +1,23 @@
|
|
1
1
|
require 'active_record'
|
2
|
-
|
2
|
+
|
3
|
+
# Database functions
|
3
4
|
class Translatomatic::Database
|
4
5
|
|
5
|
-
include Translatomatic::Util
|
6
|
-
|
7
6
|
class << self
|
8
|
-
|
9
|
-
|
10
|
-
# @param [Hash<Symbol,Object>] options Database options
|
11
|
-
# @return True if we can connect to the database
|
7
|
+
# @param options [Hash<Symbol,Object>] Database options
|
8
|
+
# @return [boolean] True if we can connect to the database
|
12
9
|
def enabled?(options = {})
|
13
10
|
new(options).connect
|
14
11
|
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
include Translatomatic::DefineOptions
|
19
12
|
end
|
20
13
|
|
21
14
|
def initialize(options = {})
|
22
|
-
@env = options[:database_env] || DEFAULT_ENV
|
23
|
-
@db_config = database_config(@env, options)
|
15
|
+
@env = options[:database_env] || DEFAULT_ENV
|
16
|
+
@db_config = database_config(@env, options)
|
24
17
|
@env_config = @db_config
|
25
|
-
raise "
|
26
|
-
|
18
|
+
raise t("database.no_environment",
|
19
|
+
env: @env, file: db_config_path) unless @env_config[@env]
|
20
|
+
@env_config = @env_config[@env] || {}
|
27
21
|
|
28
22
|
ActiveRecord::Base.configurations = @db_config
|
29
23
|
ActiveRecord::Tasks::DatabaseTasks.env = @env
|
@@ -70,7 +64,7 @@ class Translatomatic::Database
|
|
70
64
|
return false unless connect
|
71
65
|
ActiveRecord::Migrator.migrate(MIGRATIONS_PATH)
|
72
66
|
ActiveRecord::Base.clear_cache!
|
73
|
-
log.debug "
|
67
|
+
log.debug t("database.migrated")
|
74
68
|
end
|
75
69
|
|
76
70
|
# Create the database
|
@@ -78,10 +72,11 @@ class Translatomatic::Database
|
|
78
72
|
def create
|
79
73
|
begin
|
80
74
|
ActiveRecord::Tasks::DatabaseTasks.create(@env_config)
|
81
|
-
log.debug "
|
75
|
+
log.debug t("database.created")
|
82
76
|
true
|
83
|
-
rescue LoadError => e
|
84
|
-
log.debug "
|
77
|
+
rescue LoadError => e
|
78
|
+
log.debug t("database.could_not_create")
|
79
|
+
log.error e.message
|
85
80
|
false
|
86
81
|
end
|
87
82
|
end
|
@@ -91,10 +86,13 @@ class Translatomatic::Database
|
|
91
86
|
def drop
|
92
87
|
disconnect
|
93
88
|
ActiveRecord::Tasks::DatabaseTasks.drop(@env_config)
|
94
|
-
log.debug "
|
89
|
+
log.debug t("database.deleted")
|
95
90
|
end
|
96
91
|
|
97
|
-
private
|
92
|
+
private
|
93
|
+
|
94
|
+
include Translatomatic::Util
|
95
|
+
include Translatomatic::DefineOptions
|
98
96
|
|
99
97
|
def sqlite_database_exists?
|
100
98
|
@env_config['adapter'] == 'sqlite3' && File.exist?(@env_config['database'])
|
@@ -113,11 +111,11 @@ class Translatomatic::Database
|
|
113
111
|
DEFAULT_ENV = "production"
|
114
112
|
|
115
113
|
define_options(
|
116
|
-
{ name: :database_config,
|
114
|
+
{ name: :database_config, desc: t("database.config_file"),
|
117
115
|
default: DEFAULT_CONFIG },
|
118
|
-
{ name: :database_env,
|
116
|
+
{ name: :database_env, desc: t("database.env"),
|
119
117
|
default: DEFAULT_ENV })
|
120
|
-
|
118
|
+
|
121
119
|
# return path to database config
|
122
120
|
def database_config_path(options)
|
123
121
|
if options[:database_env] == "test"
|
@@ -127,19 +125,19 @@ class Translatomatic::Database
|
|
127
125
|
else
|
128
126
|
DEFAULT_CONFIG
|
129
127
|
end
|
130
|
-
end
|
131
|
-
|
132
|
-
# return database config as a hash
|
133
|
-
def database_config(env, options)
|
134
|
-
if options[:database_config].kind_of?(Hash)
|
135
|
-
return { env => options[:database_config] }
|
136
|
-
end
|
137
|
-
|
138
|
-
db_config_path = database_config_path(options)
|
139
|
-
dbconfig = File.read(db_config_path)
|
140
|
-
dbconfig.gsub!(/\$HOME/, Dir.home)
|
141
|
-
dbconfig.gsub!(/\$GEM_ROOT/, GEM_ROOT)
|
142
|
-
YAML::load(dbconfig) || {}
|
128
|
+
end
|
129
|
+
|
130
|
+
# return database config as a hash
|
131
|
+
def database_config(env, options)
|
132
|
+
if options[:database_config].kind_of?(Hash)
|
133
|
+
return { env => options[:database_config] }
|
134
|
+
end
|
135
|
+
|
136
|
+
db_config_path = database_config_path(options)
|
137
|
+
dbconfig = File.read(db_config_path)
|
138
|
+
dbconfig.gsub!(/\$HOME/, Dir.home)
|
139
|
+
dbconfig.gsub!(/\$GEM_ROOT/, GEM_ROOT)
|
140
|
+
YAML::load(dbconfig) || {}
|
143
141
|
end
|
144
142
|
|
145
143
|
end
|
@@ -41,7 +41,7 @@ module Translatomatic::EscapedUnicode
|
|
41
41
|
)+ |
|
42
42
|
[\x80-\xc1\xf5-\xff] # invalid
|
43
43
|
)/nx) { |c|
|
44
|
-
c.size == 1 and raise "
|
44
|
+
c.size == 1 and raise t("unicode.invalid_byte", byte: c)
|
45
45
|
s = c.encode("utf-16be", "utf-8").unpack('H*')[0]
|
46
46
|
s.force_encoding(::Encoding::ASCII_8BIT)
|
47
47
|
s.gsub!(/.{4}/n, '\\\\u\&')
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Translatomatic::Extractor
|
2
|
+
# Base class for string extraction functionality
|
2
3
|
class Base
|
3
4
|
|
4
5
|
def initialize(path)
|
@@ -6,6 +7,7 @@ module Translatomatic::Extractor
|
|
6
7
|
@contents = @path.read
|
7
8
|
end
|
8
9
|
|
10
|
+
# @return [Array<String>] All strings found
|
9
11
|
def extract
|
10
12
|
@contents.scan(/\"(.*?[^\\])"|'(.*?[^\\])'/).flatten.compact
|
11
13
|
end
|