translatomatic 0.1.0 → 0.1.1
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 +5 -5
- data/.gitattributes +1 -0
- data/.gitignore +15 -12
- data/.rspec +3 -3
- data/.travis.yml +32 -50
- data/CODE_OF_CONDUCT.md +74 -74
- data/Gemfile +29 -5
- data/Guardfile +48 -0
- data/LICENSE.txt +21 -21
- data/README.de.md +92 -0
- data/README.es.md +92 -0
- data/README.fr.md +92 -0
- data/README.it.md +92 -0
- data/README.ja.md +92 -0
- data/README.md +96 -74
- data/Rakefile +6 -6
- data/bin/setup +8 -8
- data/bin/translatomatic +6 -6
- data/bin/travis +26 -0
- data/db/database.yml +9 -9
- data/db/migrate/201712170000_initial.rb +24 -23
- data/lib/translatomatic/cli.rb +204 -80
- data/lib/translatomatic/config.rb +12 -26
- data/lib/translatomatic/converter.rb +206 -142
- data/lib/translatomatic/converter_stats.rb +27 -27
- data/lib/translatomatic/database.rb +139 -99
- data/lib/translatomatic/escaped_unicode.rb +90 -90
- data/lib/translatomatic/extractor/base.rb +14 -0
- data/lib/translatomatic/extractor/ruby.rb +5 -0
- data/lib/translatomatic/extractor.rb +4 -0
- data/lib/translatomatic/http_request.rb +133 -0
- data/lib/translatomatic/locale.rb +52 -0
- data/lib/translatomatic/logger.rb +28 -0
- data/lib/translatomatic/model/locale.rb +21 -22
- data/lib/translatomatic/model/text.rb +17 -13
- data/lib/translatomatic/model.rb +4 -4
- data/lib/translatomatic/option.rb +24 -24
- data/lib/translatomatic/progress_updater.rb +15 -0
- data/lib/translatomatic/resource_file/base.rb +169 -137
- data/lib/translatomatic/resource_file/html.rb +46 -28
- data/lib/translatomatic/resource_file/markdown.rb +54 -0
- data/lib/translatomatic/resource_file/plist.rb +30 -29
- data/lib/translatomatic/resource_file/properties.rb +72 -60
- data/lib/translatomatic/resource_file/resw.rb +30 -0
- data/lib/translatomatic/resource_file/text.rb +29 -28
- data/lib/translatomatic/resource_file/xcode_strings.rb +71 -65
- data/lib/translatomatic/resource_file/xml.rb +79 -59
- data/lib/translatomatic/resource_file/yaml.rb +82 -80
- data/lib/translatomatic/resource_file.rb +76 -74
- data/lib/translatomatic/string.rb +160 -0
- data/lib/translatomatic/tmx/document.rb +100 -0
- data/lib/translatomatic/tmx/translation_unit.rb +19 -0
- data/lib/translatomatic/tmx.rb +4 -0
- data/lib/translatomatic/translation_result.rb +75 -57
- data/lib/translatomatic/translator/base.rb +83 -47
- data/lib/translatomatic/translator/frengly.rb +57 -64
- data/lib/translatomatic/translator/google.rb +31 -30
- data/lib/translatomatic/translator/microsoft.rb +33 -32
- data/lib/translatomatic/translator/my_memory.rb +64 -55
- data/lib/translatomatic/translator/yandex.rb +39 -37
- data/lib/translatomatic/translator.rb +63 -63
- data/lib/translatomatic/util.rb +15 -24
- data/lib/translatomatic/version.rb +4 -3
- data/lib/translatomatic.rb +32 -27
- data/translatomatic.gemspec +43 -45
- metadata +52 -18
- data/Gemfile.lock +0 -137
data/lib/translatomatic/cli.rb
CHANGED
@@ -1,92 +1,216 @@
|
|
1
|
-
require "thor"
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
class Translatomatic::CLI < Thor
|
4
|
+
include Translatomatic::Util
|
5
|
+
|
6
|
+
package_name "Translatomatic"
|
7
|
+
map %W[-v --version] => :version
|
8
|
+
map %W[-L --list] => :translators
|
9
|
+
|
10
|
+
desc "translate file locale...", "Translate files to target locales"
|
11
|
+
method_option :translator, enum: Translatomatic::Translator.names
|
12
|
+
method_option :source_locale, desc: "The locale of the source file"
|
13
|
+
method_option :debug, type: :boolean, desc: "Enable debugging output"
|
14
|
+
method_option :wank, type: :boolean, default: true, desc: "Enable Progress bar"
|
15
|
+
method_option :share, type: :boolean, default: false, desc:
|
16
|
+
"Share translations with translators that support upload"
|
17
|
+
Translatomatic::Converter.options.each do |option|
|
18
|
+
method_option option.name, option.to_hash
|
19
|
+
end
|
20
|
+
Translatomatic::Database.options.each do |option|
|
21
|
+
method_option option.name, option.to_hash
|
22
|
+
end
|
23
|
+
Translatomatic::Translator.modules.each do |mod|
|
24
|
+
mod.options.each do |option|
|
25
|
+
method_option option.name, option.to_hash
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def translate(file, *locales)
|
29
|
+
run do
|
30
|
+
log.info("Dry run: files will not be translated or written") if options[:dry_run]
|
31
|
+
raise "One or more locales required" if locales.empty?
|
32
|
+
|
33
|
+
config.logger.level = Logger::DEBUG if options[:debug]
|
34
|
+
|
35
|
+
# load source file
|
36
|
+
raise "File not found: #{file}" unless File.exist?(file)
|
37
|
+
source = Translatomatic::ResourceFile.load(file, options[:source_locale])
|
38
|
+
raise "Unsupported file type #{file}" unless source
|
39
|
+
|
40
|
+
# set up database
|
41
|
+
Translatomatic::Database.new(options)
|
42
|
+
|
43
|
+
# select translator
|
44
|
+
translator = select_translator(options)
|
45
|
+
log.info("Using translator #{translator.name}")
|
46
|
+
log.debug("Locales: #{locales}, Properties: #{source.properties.length}")
|
47
|
+
|
48
|
+
# set up converter
|
49
|
+
translation_count = calculate_translation_count(source, locales)
|
50
|
+
converter_options = options.merge(
|
51
|
+
translator: translator, listener: progress_updater(translation_count)
|
52
|
+
)
|
53
|
+
converter = Translatomatic::Converter.new(converter_options)
|
54
|
+
|
55
|
+
# convert source to locale(s)
|
56
|
+
locales.each { |i| converter.translate(source, i) }
|
57
|
+
|
58
|
+
log.info converter.stats
|
59
|
+
config.logger.finish
|
2
60
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
61
|
+
share_translations(converter) if options[:share]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "display file [key...]", "Display values from a resource bundle"
|
66
|
+
method_option :locales, type: :string, desc: "Locales to display"
|
67
|
+
method_option :sentences, type: :boolean, desc: "Display sentences"
|
68
|
+
def display(file, *keys)
|
69
|
+
run do
|
70
|
+
source = Translatomatic::ResourceFile.load(file)
|
71
|
+
keys = source.properties.keys if keys.empty?
|
72
|
+
display_keys(source, keys)
|
8
73
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
log.info converter.stats
|
44
|
-
true
|
45
|
-
rescue Interrupt
|
46
|
-
puts "\nAborted"
|
47
|
-
false
|
48
|
-
rescue Exception => e
|
49
|
-
log.error("Error translating #{file}")
|
50
|
-
log.error(e.message)
|
51
|
-
log.debug(e.backtrace.join("\n"))
|
52
|
-
false
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
desc "translators", "list available translation backends"
|
57
|
-
def translators
|
58
|
-
puts Translatomatic::Translator.list
|
59
|
-
end
|
74
|
+
# TODO: if locales not specified, determine the list of locales from
|
75
|
+
# all the files in the resource bundle.
|
76
|
+
locales = (options[:locales] || "").split(',').flatten.compact
|
77
|
+
locales << Translatomatic::Locale.default.to_s if locales.empty?
|
78
|
+
locales.each do |locale|
|
79
|
+
display_properties(source, locale)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
desc "strings file [file...]", "Extract strings from non-resource files"
|
85
|
+
def strings(*files)
|
86
|
+
run do
|
87
|
+
strings = []
|
88
|
+
files.each do |file|
|
89
|
+
extractor = Translatomatic::Extractor::Base.new(file)
|
90
|
+
strings << extractor.extract
|
91
|
+
end
|
92
|
+
puts strings.join("\n")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
desc "list", "List available translation backends"
|
97
|
+
def list
|
98
|
+
run { puts Translatomatic::Translator.list }
|
99
|
+
end
|
100
|
+
|
101
|
+
desc 'version', 'Display version'
|
102
|
+
def version
|
103
|
+
puts "Translatomatic version #{Translatomatic::VERSION}"
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
60
107
|
|
61
|
-
|
62
|
-
|
63
|
-
puts "Translatomatic version #{Translatomatic::VERSION}"
|
108
|
+
def calculate_translation_count(source, locales)
|
109
|
+
source.sentences.length * locales.length
|
64
110
|
end
|
65
111
|
|
66
|
-
|
67
|
-
|
68
|
-
def select_translator
|
69
|
-
# use options translator if specified
|
70
|
-
if options[:translator]
|
71
|
-
klass = Translatomatic::Translator.find(options[:translator])
|
72
|
-
return klass.new(options)
|
73
|
-
end
|
112
|
+
def share_translations(converter)
|
113
|
+
return if converter.db_translations.empty?
|
74
114
|
|
75
|
-
|
115
|
+
tmx = Translatomatic::TMX::Document.from_texts(converter.db_translations)
|
76
116
|
available = Translatomatic::Translator.available(options)
|
77
|
-
|
78
|
-
|
117
|
+
available.each do |translator|
|
118
|
+
if translator.respond_to?(:upload)
|
119
|
+
log.debug("Uploading tmx to #{translator.name}")
|
120
|
+
translator.upload(tmx)
|
121
|
+
end
|
79
122
|
end
|
80
123
|
|
81
|
-
|
124
|
+
ActiveRecord::Base.transaction do
|
125
|
+
converter.db_translations.each do |text|
|
126
|
+
text.update(shared: true) if text.is_translated?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# create a progress bar and progress updater
|
132
|
+
def progress_updater(translation_count)
|
133
|
+
return nil unless options[:wank]
|
134
|
+
# set up progress bar
|
135
|
+
progressbar = ProgressBar.create(
|
136
|
+
title: "Translating",
|
137
|
+
format: "%t: |%B| %E ",
|
138
|
+
autofinish: false,
|
139
|
+
total: translation_count
|
140
|
+
)
|
141
|
+
config.logger.progressbar = progressbar
|
142
|
+
Translatomatic::ProgressUpdater.new(progressbar)
|
143
|
+
end
|
144
|
+
|
145
|
+
# run the give code block, display exceptions.
|
146
|
+
# return true if the code ran without exceptions
|
147
|
+
def run
|
148
|
+
begin
|
149
|
+
yield
|
150
|
+
true
|
151
|
+
rescue Interrupt
|
152
|
+
puts "\nAborted"
|
153
|
+
false
|
154
|
+
rescue Exception => e
|
155
|
+
log.error(e.message)
|
156
|
+
log.debug(e.backtrace.join("\n"))
|
157
|
+
false
|
158
|
+
end
|
159
|
+
end
|
82
160
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
idx = idx.to_i
|
89
|
-
return available[idx - 1] if (1..available.length).include?(idx)
|
161
|
+
def display_properties(source, locale)
|
162
|
+
path = source.locale_path(locale)
|
163
|
+
if path.exist?
|
164
|
+
resource = Translatomatic::ResourceFile.load(path)
|
165
|
+
display_keys(resource, keys)
|
90
166
|
end
|
91
167
|
end
|
92
|
-
|
168
|
+
|
169
|
+
def display_keys(source, keys)
|
170
|
+
puts "File: #{source}"
|
171
|
+
table = []
|
172
|
+
keys.each do |key|
|
173
|
+
value = source.get(key)
|
174
|
+
table << [key + ":", value]
|
175
|
+
end
|
176
|
+
print_table(table, indent: 2)
|
177
|
+
|
178
|
+
if options[:sentences]
|
179
|
+
puts "Sentences:"
|
180
|
+
source.sentences.each do |sentence|
|
181
|
+
puts "- " + sentence.to_s
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
puts
|
186
|
+
end
|
187
|
+
|
188
|
+
def config
|
189
|
+
Translatomatic::Config.instance
|
190
|
+
end
|
191
|
+
|
192
|
+
def select_translator(options)
|
193
|
+
# use options translator if specified
|
194
|
+
if options[:translator]
|
195
|
+
klass = Translatomatic::Translator.find(options[:translator])
|
196
|
+
return klass.new(options)
|
197
|
+
end
|
198
|
+
|
199
|
+
# find all available translators that work with the given options
|
200
|
+
available = Translatomatic::Translator.available(options)
|
201
|
+
if available.empty?
|
202
|
+
raise "No translators configured. Use the translators command to see options"
|
203
|
+
end
|
204
|
+
|
205
|
+
return available[0] if available.length == 1
|
206
|
+
|
207
|
+
# prompt user for which translator to use
|
208
|
+
say("Multiple translators available:")
|
209
|
+
available.each_with_index { |mod, i| say(" #{i + 1}) #{mod.name}") }
|
210
|
+
loop do
|
211
|
+
idx = ask("Select translator (1-#{available.length}): ")
|
212
|
+
idx = idx.to_i
|
213
|
+
return available[idx - 1] if (1..available.length).include?(idx)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -1,26 +1,12 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
class Translatomatic::Config
|
3
|
-
include Singleton
|
4
|
-
|
5
|
-
attr_accessor :logger
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@logger
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
@logger = Logger.new(STDOUT)
|
17
|
-
@logger.formatter = proc do |severity, datetime, progname, msg|
|
18
|
-
"#{msg}\n"
|
19
|
-
end
|
20
|
-
self.debug = ENV['DEBUG'] ? true : false
|
21
|
-
end
|
22
|
-
|
23
|
-
def debug?
|
24
|
-
@debug
|
25
|
-
end
|
26
|
-
end
|
1
|
+
require 'singleton'
|
2
|
+
class Translatomatic::Config
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
attr_accessor :logger
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@logger = Translatomatic::Logger.new
|
11
|
+
end
|
12
|
+
end
|