translatomatic 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/.gitattributes +1 -0
  3. data/.gitignore +15 -12
  4. data/.rspec +3 -3
  5. data/.travis.yml +32 -50
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/Gemfile +29 -5
  8. data/Guardfile +48 -0
  9. data/LICENSE.txt +21 -21
  10. data/README.de.md +92 -0
  11. data/README.es.md +92 -0
  12. data/README.fr.md +92 -0
  13. data/README.it.md +92 -0
  14. data/README.ja.md +92 -0
  15. data/README.md +96 -74
  16. data/Rakefile +6 -6
  17. data/bin/setup +8 -8
  18. data/bin/translatomatic +6 -6
  19. data/bin/travis +26 -0
  20. data/db/database.yml +9 -9
  21. data/db/migrate/201712170000_initial.rb +24 -23
  22. data/lib/translatomatic/cli.rb +204 -80
  23. data/lib/translatomatic/config.rb +12 -26
  24. data/lib/translatomatic/converter.rb +206 -142
  25. data/lib/translatomatic/converter_stats.rb +27 -27
  26. data/lib/translatomatic/database.rb +139 -99
  27. data/lib/translatomatic/escaped_unicode.rb +90 -90
  28. data/lib/translatomatic/extractor/base.rb +14 -0
  29. data/lib/translatomatic/extractor/ruby.rb +5 -0
  30. data/lib/translatomatic/extractor.rb +4 -0
  31. data/lib/translatomatic/http_request.rb +133 -0
  32. data/lib/translatomatic/locale.rb +52 -0
  33. data/lib/translatomatic/logger.rb +28 -0
  34. data/lib/translatomatic/model/locale.rb +21 -22
  35. data/lib/translatomatic/model/text.rb +17 -13
  36. data/lib/translatomatic/model.rb +4 -4
  37. data/lib/translatomatic/option.rb +24 -24
  38. data/lib/translatomatic/progress_updater.rb +15 -0
  39. data/lib/translatomatic/resource_file/base.rb +169 -137
  40. data/lib/translatomatic/resource_file/html.rb +46 -28
  41. data/lib/translatomatic/resource_file/markdown.rb +54 -0
  42. data/lib/translatomatic/resource_file/plist.rb +30 -29
  43. data/lib/translatomatic/resource_file/properties.rb +72 -60
  44. data/lib/translatomatic/resource_file/resw.rb +30 -0
  45. data/lib/translatomatic/resource_file/text.rb +29 -28
  46. data/lib/translatomatic/resource_file/xcode_strings.rb +71 -65
  47. data/lib/translatomatic/resource_file/xml.rb +79 -59
  48. data/lib/translatomatic/resource_file/yaml.rb +82 -80
  49. data/lib/translatomatic/resource_file.rb +76 -74
  50. data/lib/translatomatic/string.rb +160 -0
  51. data/lib/translatomatic/tmx/document.rb +100 -0
  52. data/lib/translatomatic/tmx/translation_unit.rb +19 -0
  53. data/lib/translatomatic/tmx.rb +4 -0
  54. data/lib/translatomatic/translation_result.rb +75 -57
  55. data/lib/translatomatic/translator/base.rb +83 -47
  56. data/lib/translatomatic/translator/frengly.rb +57 -64
  57. data/lib/translatomatic/translator/google.rb +31 -30
  58. data/lib/translatomatic/translator/microsoft.rb +33 -32
  59. data/lib/translatomatic/translator/my_memory.rb +64 -55
  60. data/lib/translatomatic/translator/yandex.rb +39 -37
  61. data/lib/translatomatic/translator.rb +63 -63
  62. data/lib/translatomatic/util.rb +15 -24
  63. data/lib/translatomatic/version.rb +4 -3
  64. data/lib/translatomatic.rb +32 -27
  65. data/translatomatic.gemspec +43 -45
  66. metadata +52 -18
  67. data/Gemfile.lock +0 -137
@@ -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
- class Translatomatic::CLI < Thor
4
- include Translatomatic::Util
5
- package_name "Translatomatic"
6
- map %W[-v --version] => :version
7
- map %W[-L --list] => :translators
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
- desc "translate file locale...", "translate files to target locale(s)"
10
- method_option :translator, enum: Translatomatic::Translator.names
11
- method_option :source_locale, desc: "The locale of the source file, default is autodetermined"
12
- method_option :debug, type: :boolean, desc: "Turn on debugging output"
13
- Translatomatic::Converter.options.each do |option|
14
- method_option option.name, option.to_hash
15
- end
16
- Translatomatic::Database.options.each do |option|
17
- method_option option.name, option.to_hash
18
- end
19
- Translatomatic::Translator.modules.each do |mod|
20
- mod.options.each do |option|
21
- method_option option.name, option.to_hash
22
- end
23
- end
24
- def translate(file, locale, *locales)
25
- begin
26
- log.info("dry run: files will not be translated or written") if options[:dry_run]
27
-
28
- Translatomatic::Config.instance.debug = options[:debug] if options[:debug]
29
- Translatomatic::Database.new(options)
30
-
31
- translator = select_translator
32
- log.info("Using translator #{translator.name}")
33
-
34
- converter_options = options.merge(translator: translator)
35
- converter = Translatomatic::Converter.new(converter_options)
36
- source = Translatomatic::ResourceFile.load(file, options[:source_locale])
37
-
38
- raise "Unsupported file type #{file}" unless source
39
- target_locales = [locale]
40
- target_locales += locales
41
- target_locales.each { |i| converter.translate(source, i) }
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
- desc 'version', 'Display version'
62
- def version
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
- private
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
- # find all available translators that work with the given options
115
+ tmx = Translatomatic::TMX::Document.from_texts(converter.db_translations)
76
116
  available = Translatomatic::Translator.available(options)
77
- if available.empty?
78
- raise "No translators configured. Use the translators command to see options"
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
- return available[0] if available.length == 1
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
- # prompt user for which translator to use
84
- say("Multiple translators available:")
85
- available.each_with_index { |mod, i| say(" #{i + 1}) #{mod.name}") }
86
- loop do
87
- idx = ask("Select translator (1-#{available.length}): ")
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
- end
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
- attr_accessor :debug
7
-
8
- def debug=(value)
9
- @debug = value ? true : false
10
- @logger.level = @debug ? Logger::DEBUG : Logger::INFO
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