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,47 +1,83 @@
1
- require 'bing_translator'
2
-
3
- module Translatomatic
4
- module Translator
5
- @abstract
6
- class Base
7
-
8
- class << self
9
- attr_reader :options
10
- private
11
- include Translatomatic::DefineOptions
12
- end
13
-
14
- # @return [String] The name of this translator.
15
- def name
16
- self.class.name.demodulize
17
- end
18
-
19
- # @return [Array<String>] A list of languages supported by this translator.
20
- def languages
21
- []
22
- end
23
-
24
- # Translate strings from one locale to another
25
- # @param [Array<String>] strings A list of strings to translate.
26
- # @param [String, Locale] from The locale of the given strings.
27
- # @param [String, Locale] to The locale to translate to.
28
- # @return [Array<String>] Translated strings
29
- def translate(strings, from, to)
30
- strings = [strings] unless strings.kind_of?(Array)
31
- from = parse_locale(from) if from.kind_of?(String)
32
- to = parse_locale(to) if to.kind_of?(String)
33
- return strings if from.language == to.language
34
- perform_translate(strings, from, to)
35
- end
36
-
37
- private
38
-
39
- include Translatomatic::Util
40
-
41
- def perform_translate(strings, from, to)
42
- raise "subclasses must implement perform_translate"
43
- end
44
-
45
- end
46
- end
47
- end
1
+ require 'bing_translator'
2
+
3
+ module Translatomatic
4
+ module Translator
5
+ # @abstract
6
+ class Base
7
+
8
+ class << self
9
+ attr_reader :options
10
+ private
11
+ include Translatomatic::DefineOptions
12
+ end
13
+
14
+ # @private
15
+ attr_accessor :listener
16
+
17
+ def initialize(options = {})
18
+ @listener = options[:listener]
19
+ end
20
+
21
+ # @return [String] The name of this translator.
22
+ def name
23
+ self.class.name.demodulize
24
+ end
25
+
26
+ # @return [Array<String>] A list of languages supported by this translator.
27
+ def languages
28
+ []
29
+ end
30
+
31
+ # Translate strings from one locale to another
32
+ # @param [Array<String>] strings A list of strings to translate.
33
+ # @param [String, Translatomatic::Locale] from The locale of the given strings.
34
+ # @param [String, Translatomatic::Locale] to The locale to translate to.
35
+ # @return [Array<String>] Translated strings
36
+ def translate(strings, from, to)
37
+ strings = [strings] unless strings.kind_of?(Array)
38
+ from = locale(from)
39
+ to = locale(to)
40
+ return strings if from.language == to.language
41
+ translated = perform_translate(strings, from, to)
42
+ update_translated(translated) unless @updated_listener
43
+ translated
44
+ end
45
+
46
+ private
47
+
48
+ include Translatomatic::Util
49
+
50
+ # fetch translations for the given strings, one at a time, by
51
+ # opening a http connection to the given url and calling
52
+ # fetch_translation() on each string.
53
+ # (subclass must implement fetch_translation if this method is used)
54
+ def perform_fetch_translations(url, strings, from, to)
55
+ translated = []
56
+ request = Translatomatic::HTTPRequest.new(url)
57
+ request.start do |http|
58
+ strings.each do |string|
59
+ result = fetch_translation(request, string, from, to)
60
+ translated << result
61
+ update_translated(result)
62
+ end
63
+ end
64
+ translated
65
+ end
66
+
67
+ def fetch_translation(request, strings, from, to)
68
+ raise "subclass must implement fetch_translation"
69
+ end
70
+
71
+ def update_translated(texts)
72
+ texts = [texts] unless texts.kind_of?(Array)
73
+ @updated_listener = true
74
+ @listener.translated_texts(texts) if @listener
75
+ end
76
+
77
+ def perform_translate(strings, from, to)
78
+ raise "subclass must implement perform_translate"
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -1,64 +1,57 @@
1
- require 'net/http'
2
-
3
- module Translatomatic
4
- module Translator
5
-
6
- class Frengly < Base
7
-
8
- define_options({
9
- name: :frengly_api_key, desc: "Frengly API key", use_env: true
10
- },
11
- { name: :frengly_email, desc: "Email address", use_env: true
12
- },
13
- { name: :frengly_password, desc: "Password", use_env: true
14
- })
15
-
16
- # Create a new Frengly translator instance
17
- def initialize(options = {})
18
- @key = options[:frengly_api_key] || ENV["FRENGLY_API_KEY"] # optional
19
- @email = options[:frengly_email]
20
- @password = options[:frengly_password]
21
- raise "email address required" unless @email
22
- raise "password required" unless @password
23
- end
24
-
25
- # (see Translatomatic::Translator::Base#languages)
26
- def languages
27
- ['en','fr','de','es','pt','it','nl','tl','fi','el','iw','pl','ru','sv']
28
- end
29
-
30
- private
31
-
32
- URL = 'http://frengly.com/frengly/data/translateREST'
33
-
34
- def perform_translate(strings, from, to)
35
- translated = []
36
- uri = URI.parse(URL)
37
-
38
- Net::HTTP.start(uri.host, uri.port) do |http|
39
- strings.each do |string|
40
- body = {
41
- src: from.language,
42
- dest: to.language,
43
- text: string,
44
- email: @email,
45
- password: @password,
46
- premiumkey: @key
47
- }.to_json
48
-
49
- # TODO: work out what the response looks like
50
- req = Net::HTTP::Post.new(uri)
51
- req.body = body
52
- req.content_type = 'application/json'
53
- response = http.request(req)
54
- raise response.body unless response.kind_of? Net::HTTPSuccess
55
- data = JSON.parse(response.body)
56
- translated << data['text']
57
- end
58
- translated
59
- end
60
- end
61
-
62
- end # class
63
- end # module
64
- end
1
+ require 'net/http'
2
+
3
+ module Translatomatic
4
+ module Translator
5
+
6
+ class Frengly < Base
7
+
8
+ define_options({
9
+ name: :frengly_api_key, desc: "Frengly API key", use_env: true
10
+ },
11
+ { name: :frengly_email, desc: "Email address", use_env: true
12
+ },
13
+ { name: :frengly_password, desc: "Password", use_env: true
14
+ })
15
+
16
+ # Create a new Frengly translator instance
17
+ def initialize(options = {})
18
+ super(options)
19
+ @key = options[:frengly_api_key] || ENV["FRENGLY_API_KEY"] # optional
20
+ @email = options[:frengly_email]
21
+ @password = options[:frengly_password]
22
+ raise "email address required" unless @email
23
+ raise "password required" unless @password
24
+ end
25
+
26
+ # (see Translatomatic::Translator::Base#languages)
27
+ def languages
28
+ ['en','fr','de','es','pt','it','nl','tl','fi','el','iw','pl','ru','sv']
29
+ end
30
+
31
+ private
32
+
33
+ URL = 'http://frengly.com/frengly/data/translateREST'
34
+
35
+ def perform_translate(strings, from, to)
36
+ perform_fetch_translations(URL, strings, from, to)
37
+ end
38
+
39
+ def fetch_translation(request, string, from, to)
40
+ body = {
41
+ src: from.language,
42
+ dest: to.language,
43
+ text: string,
44
+ email: @email,
45
+ password: @password,
46
+ premiumkey: @key
47
+ }.to_json
48
+
49
+ # TODO: work out what the response looks like
50
+ response = request.post(body, content_type: 'application/json')
51
+ data = JSON.parse(response.body)
52
+ data['text']
53
+ end
54
+
55
+ end # class
56
+ end # module
57
+ end
@@ -1,30 +1,31 @@
1
- module Translatomatic
2
- module Translator
3
-
4
- class Google < Base
5
-
6
- define_options({ name: :google_api_key, desc: "Google API key",
7
- use_env: true
8
- })
9
-
10
- # Create a new Google translator instance
11
- def initialize(options = {})
12
- key = options[:google_api_key] || ENV["GOOGLE_API_KEY"]
13
- raise "google api key required" if key.nil?
14
- EasyTranslate.api_key = key
15
- end
16
-
17
- # (see Translatomatic::Translator::Base#languages)
18
- def languages
19
- EasyTranslate::LANGUAGES.keys
20
- end
21
-
22
- private
23
-
24
- def perform_translate(strings, from, to)
25
- EasyTranslate.translate(strings, from: from.language, to: to.language)
26
- end
27
-
28
- end # class
29
- end # module
30
- end
1
+ module Translatomatic
2
+ module Translator
3
+
4
+ class Google < Base
5
+
6
+ define_options({ name: :google_api_key, desc: "Google API key",
7
+ use_env: true
8
+ })
9
+
10
+ # Create a new Google translator instance
11
+ def initialize(options = {})
12
+ super(options)
13
+ key = options[:google_api_key] || ENV["GOOGLE_API_KEY"]
14
+ raise "google api key required" if key.nil?
15
+ EasyTranslate.api_key = key
16
+ end
17
+
18
+ # (see Translatomatic::Translator::Base#languages)
19
+ def languages
20
+ EasyTranslate::LANGUAGES.keys
21
+ end
22
+
23
+ private
24
+
25
+ def perform_translate(strings, from, to)
26
+ EasyTranslate.translate(strings, from: from.language, to: to.language)
27
+ end
28
+
29
+ end # class
30
+ end # module
31
+ end
@@ -1,32 +1,33 @@
1
- require 'bing_translator'
2
-
3
- module Translatomatic
4
- module Translator
5
-
6
- class Microsoft < Base
7
-
8
- define_options({
9
- name: :microsoft_api_key, desc: "Microsoft API key", use_env: true
10
- })
11
-
12
- # Create a new Microsoft translator instance
13
- def initialize(options = {})
14
- key = options[:microsoft_api_key] || ENV["MICROSOFT_API_KEY"]
15
- raise "microsoft api key required" if key.nil?
16
- @impl = BingTranslator.new(key)
17
- end
18
-
19
- # TODO: implement language list
20
- # (see Translatomatic::Translator::Base#languages)
21
- #def languages
22
- #end
23
-
24
- private
25
-
26
- def perform_translate(strings, from, to)
27
- @impl.translate_array(strings, from: from.language, to: to.language)
28
- end
29
-
30
- end
31
- end
32
- end
1
+ require 'bing_translator'
2
+
3
+ module Translatomatic
4
+ module Translator
5
+
6
+ class Microsoft < Base
7
+
8
+ define_options({
9
+ name: :microsoft_api_key, desc: "Microsoft API key", use_env: true
10
+ })
11
+
12
+ # Create a new Microsoft translator instance
13
+ def initialize(options = {})
14
+ super(options)
15
+ key = options[:microsoft_api_key] || ENV["MICROSOFT_API_KEY"]
16
+ raise "microsoft api key required" if key.nil?
17
+ @impl = BingTranslator.new(key)
18
+ end
19
+
20
+ # TODO: implement language list
21
+ # (see Translatomatic::Translator::Base#languages)
22
+ #def languages
23
+ #end
24
+
25
+ private
26
+
27
+ def perform_translate(strings, from, to)
28
+ @impl.translate_array(strings, from: from.language, to: to.language)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -1,55 +1,64 @@
1
- require 'bing_translator'
2
-
3
- module Translatomatic
4
- module Translator
5
-
6
- class MyMemory < Base
7
-
8
- define_options(
9
- { name: :mymemory_api_key, desc: "MyMemory API key", use_env: true },
10
- { name: :mymemory_email, desc: "Email address", use_env: true }
11
- )
12
-
13
- # Create a new MyMemory translator instance
14
- def initialize(options = {})
15
- @key = options[:mymemory_api_key] || ENV["MYMEMORY_API_KEY"]
16
- @email = options[:mymemory_email] || ENV["MYMEMORY_EMAIL"]
17
- end
18
-
19
- # TODO: implement language list
20
- # (see Translatomatic::Translator::Base#languages)
21
- #def languages
22
- #end
23
-
24
- private
25
-
26
- URL = 'https://api.mymemory.translated.net/get'
27
-
28
- def perform_translate(strings, from, to)
29
- translated = []
30
- uri = URI.parse(URL)
31
-
32
- http_options = { use_ssl: uri.scheme == "https" }
33
- Net::HTTP.start(uri.host, uri.port, http_options) do |http|
34
- strings.each do |string|
35
- query = {
36
- langpair: from.to_s + "|" + to.to_s,
37
- q: string
38
- }
39
- query.merge!(de: @email) if @email
40
- query.merge!(key: @key) if @key
41
- uri.query = URI.encode_www_form(query)
42
-
43
- req = Net::HTTP::Get.new(uri)
44
- response = http.request(req)
45
- raise response.body unless response.kind_of? Net::HTTPSuccess
46
- data = JSON.parse(response.body)
47
- translated << data['responseData']['translatedText']
48
- end
49
- translated
50
- end
51
- end
52
-
53
- end
54
- end
55
- end
1
+ require 'bing_translator'
2
+
3
+ module Translatomatic
4
+ module Translator
5
+
6
+ class MyMemory < Base
7
+
8
+ define_options(
9
+ { name: :mymemory_api_key, desc: "MyMemory API key", use_env: true },
10
+ { name: :mymemory_email, desc: "Email address", use_env: true }
11
+ )
12
+
13
+ # Create a new MyMemory translator instance
14
+ def initialize(options = {})
15
+ super(options)
16
+ @key = options[:mymemory_api_key] || ENV["MYMEMORY_API_KEY"]
17
+ @email = options[:mymemory_email] || ENV["MYMEMORY_EMAIL"]
18
+ @query_options = {}
19
+ @query_options.merge!(de: @email) if @email
20
+ @query_options.merge!(key: @key) if @key
21
+ end
22
+
23
+ # TODO: implement language list
24
+ # (see Translatomatic::Translator::Base#languages)
25
+ #def languages
26
+ #end
27
+
28
+ # Upload a set of translations to MyMemory
29
+ # @param [Translatomatic::TMX::Document] TMX document
30
+ def upload(tmx)
31
+ request = Translatomatic::HTTPRequest.new(UPLOAD_URL)
32
+ request.start do |http|
33
+ body = [
34
+ request.file(key: :tmx, filename: "import.tmx",
35
+ content: tmx.to_xml, mime_type: "application/xml"
36
+ ),
37
+ request.param(key: :private, value: 0)
38
+ ]
39
+ response = request.post(body, multipart: true)
40
+ log.debug("share response: #{response.body}")
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ GET_URL = 'https://api.mymemory.translated.net/get'
47
+ UPLOAD_URL = 'https://api.mymemory.translated.net/tmx/import'
48
+
49
+ def perform_translate(strings, from, to)
50
+ perform_fetch_translations(GET_URL, strings, from, to)
51
+ end
52
+
53
+ def fetch_translation(request, string, from, to)
54
+ response = request.get({
55
+ langpair: from.to_s + "|" + to.to_s,
56
+ q: string
57
+ }.merge(@query_options)
58
+ )
59
+ data = JSON.parse(response.body)
60
+ data['responseData']['translatedText']
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,37 +1,39 @@
1
- require 'yandex-translator'
2
-
3
- module Translatomatic
4
- module Translator
5
-
6
- class Yandex < Base
7
-
8
- define_options({
9
- name: :yandex_api_key, desc: "Yandex API key", use_env: true
10
- })
11
-
12
- # Create a new Yandex translator instance
13
- def initialize(options = {})
14
- key = options[:yandex_api_key] || ENV["YANDEX_API_KEY"]
15
- raise "yandex api key required" if key.nil?
16
- @impl = ::Yandex::Translator.new(key)
17
- end
18
-
19
- # (see Translatomatic::Translator::Base#languages)
20
- def languages
21
- @languages ||= @impl.langs.collect { |i| i[0, 2] }.uniq
22
- end
23
-
24
- private
25
-
26
- def perform_translate(strings, from, to)
27
- translated = []
28
- strings.each do |string|
29
- result = @impl.translate(string, from: from.language, to: to.language) || ""
30
- translated.push(result)
31
- end
32
- translated
33
- end
34
-
35
- end # class
36
- end # module
37
- end
1
+ require 'yandex-translator'
2
+
3
+ module Translatomatic
4
+ module Translator
5
+
6
+ class Yandex < Base
7
+
8
+ define_options({
9
+ name: :yandex_api_key, desc: "Yandex API key", use_env: true
10
+ })
11
+
12
+ # Create a new Yandex translator instance
13
+ def initialize(options = {})
14
+ super(options)
15
+ key = options[:yandex_api_key] || ENV["YANDEX_API_KEY"]
16
+ raise "yandex api key required" if key.nil?
17
+ @impl = ::Yandex::Translator.new(key)
18
+ end
19
+
20
+ # (see Translatomatic::Translator::Base#languages)
21
+ def languages
22
+ @languages ||= @impl.langs.collect { |i| i[0, 2] }.uniq
23
+ end
24
+
25
+ private
26
+
27
+ def perform_translate(strings, from, to)
28
+ translated = []
29
+ strings.each do |string|
30
+ result = @impl.translate(string, from: from.language, to: to.language) || ""
31
+ translated.push(result)
32
+ update_translated(result)
33
+ end
34
+ translated
35
+ end
36
+
37
+ end # class
38
+ end # module
39
+ end