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.
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