easy_translate 0.2.1 → 0.3.0
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.
- data/lib/easy_translate.rb +15 -69
- data/lib/easy_translate/detection.rb +83 -0
- data/lib/easy_translate/easy_translate_exception.rb +6 -0
- data/lib/easy_translate/languages.rb +58 -0
- data/lib/easy_translate/request.rb +63 -0
- data/lib/easy_translate/translation.rb +109 -0
- data/lib/easy_translate/version.rb +2 -2
- data/spec/spec_helper.rb +11 -0
- metadata +49 -70
- data/lib/easy_translate/param_builder.rb +0 -23
- data/lib/easy_translate/translator.rb +0 -159
data/lib/easy_translate.rb
CHANGED
@@ -1,73 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/easy_translate/detection'
|
2
|
+
require File.dirname(__FILE__) + '/easy_translate/translation'
|
3
|
+
|
1
4
|
module EasyTranslate
|
2
5
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
API_VERSION = '2.0'
|
6
|
+
autoload :EasyTranslateException, File.dirname(__FILE__) + '/easy_translate/easy_translate_exception'
|
7
|
+
autoload :Request, File.dirname(__FILE__) + '/easy_translate/request'
|
8
|
+
|
9
|
+
autoload :LANGUAGES, File.dirname(__FILE__) + '/easy_translate/languages'
|
10
|
+
autoload :VERSION, File.dirname(__FILE__) + '/easy_translate/version'
|
11
|
+
|
12
|
+
extend Detection # Language Detection
|
13
|
+
extend Translation # Language Translation
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_accessor :api_key
|
17
|
+
end
|
16
18
|
|
17
|
-
LANGUAGES = {
|
18
|
-
'af' => 'afrikaans',
|
19
|
-
'sq' => 'albanian',
|
20
|
-
'ar' => 'arabic',
|
21
|
-
'be' => 'belarusian',
|
22
|
-
'bg' => 'bulgarian',
|
23
|
-
'ca' => 'catalan',
|
24
|
-
'zh-CN' => 'chinese_simplified',
|
25
|
-
'zh-TW' => 'chinese_traditional',
|
26
|
-
'hr' => 'croatian',
|
27
|
-
'cs' => 'czech',
|
28
|
-
'da' => 'danish',
|
29
|
-
'nl' => 'dutch',
|
30
|
-
'en' => 'english',
|
31
|
-
'et' => 'estonian',
|
32
|
-
'tl' => 'filipino',
|
33
|
-
'fi' => 'finnish',
|
34
|
-
'fr' => 'french',
|
35
|
-
'gl' => 'galician',
|
36
|
-
'de' => 'german',
|
37
|
-
'el' => 'greek',
|
38
|
-
'ht' => 'haitian_creole',
|
39
|
-
'iw' => 'hebrew',
|
40
|
-
'hi' => 'hindi',
|
41
|
-
'hu' => 'hungarian',
|
42
|
-
'is' => 'icelandic',
|
43
|
-
'id' => 'indonesian',
|
44
|
-
'ga' => 'irish',
|
45
|
-
'it' => 'italian',
|
46
|
-
'ja' => 'japanese',
|
47
|
-
'ko' => 'korean',
|
48
|
-
'lv' => 'latvian',
|
49
|
-
'lt' => 'lithuanian',
|
50
|
-
'mk' => 'macedonian',
|
51
|
-
'ms' => 'malay',
|
52
|
-
'mt' => 'maltese',
|
53
|
-
'no' => 'norwegian',
|
54
|
-
'fa' => 'persian',
|
55
|
-
'pl' => 'polish',
|
56
|
-
'pt' => 'portuguese',
|
57
|
-
'ro' => 'romanian',
|
58
|
-
'ru' => 'russian',
|
59
|
-
'sr' => 'serbian',
|
60
|
-
'sk' => 'slovak',
|
61
|
-
'sl' => 'slovenian',
|
62
|
-
'es' => 'spanish',
|
63
|
-
'sw' => 'swahili',
|
64
|
-
'sv' => 'swedish',
|
65
|
-
'th' => 'thai',
|
66
|
-
'tr' => 'turkish',
|
67
|
-
'uk' => 'ukrainian',
|
68
|
-
'vi' => 'vietnamese',
|
69
|
-
'cy' => 'welsh',
|
70
|
-
'yi' => 'yiddish'
|
71
|
-
}
|
72
|
-
|
73
19
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'json'
|
2
|
+
require File.dirname(__FILE__) + '/request'
|
3
|
+
|
4
|
+
module EasyTranslate
|
5
|
+
|
6
|
+
module Detection
|
7
|
+
|
8
|
+
# Detect language
|
9
|
+
# @param [String, Array] texts - A single string or set of strings to detect for
|
10
|
+
# @param [Hash] options - Extra options to pass along with the request
|
11
|
+
# @return [String, Array] The resultant language or languages
|
12
|
+
def detect(texts, options = nil)
|
13
|
+
request = DetectionRequest.new(texts, options)
|
14
|
+
# Turn the response into an array of detections
|
15
|
+
raw = request.perform_raw
|
16
|
+
detections = JSON.parse(raw)['data']['detections'].map do |res|
|
17
|
+
res.empty? ? nil : res.first['language']
|
18
|
+
end
|
19
|
+
# And then return, if they only asked for one, only give one back
|
20
|
+
request.multi? ? detections : detections.first
|
21
|
+
end
|
22
|
+
|
23
|
+
# A convenience class for wrapping a detection request
|
24
|
+
class DetectionRequest < EasyTranslate::Request
|
25
|
+
|
26
|
+
# Set the texts and options
|
27
|
+
# @param [String, Array] texts - The text (or texts) to translate
|
28
|
+
# @param [Hash] options - Options to override or pass along with the request
|
29
|
+
def initialize(texts, options = nil)
|
30
|
+
self.texts = texts
|
31
|
+
if options
|
32
|
+
@options = options
|
33
|
+
if replacement_api_key = @options.delete(:api_key)
|
34
|
+
@options[:key] = replacement_api_key
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# The params for this request
|
40
|
+
# @return [Hash] the params for the request
|
41
|
+
def params
|
42
|
+
params = super || {}
|
43
|
+
params.merge! @options if @options
|
44
|
+
params
|
45
|
+
end
|
46
|
+
|
47
|
+
# The path for the request
|
48
|
+
# @return [String] The path for the request
|
49
|
+
def path
|
50
|
+
'/language/translate/v2/detect'
|
51
|
+
end
|
52
|
+
|
53
|
+
# The body for the request
|
54
|
+
# @return [String] the body for the request, URL escaped
|
55
|
+
def body
|
56
|
+
@texts.map { |t| "q=#{URI.escape(t)}" }.join '&'
|
57
|
+
end
|
58
|
+
|
59
|
+
# Whether or not this was a request for multiple texts
|
60
|
+
# @return [Boolean]
|
61
|
+
def multi?
|
62
|
+
@multi
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Set the texts for this request
|
68
|
+
# @param [String, Array] texts - The text or texts for this request
|
69
|
+
def texts=(texts)
|
70
|
+
if texts.is_a?(String)
|
71
|
+
@multi = false
|
72
|
+
@texts = [texts]
|
73
|
+
else
|
74
|
+
@multi = true
|
75
|
+
@texts = texts
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module EasyTranslate
|
2
|
+
|
3
|
+
LANGUAGES = {
|
4
|
+
'af' => 'afrikaans',
|
5
|
+
'sq' => 'albanian',
|
6
|
+
'ar' => 'arabic',
|
7
|
+
'be' => 'belarusian',
|
8
|
+
'bg' => 'bulgarian',
|
9
|
+
'ca' => 'catalan',
|
10
|
+
'zh-CN' => 'chinese_simplified',
|
11
|
+
'zh-TW' => 'chinese_traditional',
|
12
|
+
'hr' => 'croatian',
|
13
|
+
'cs' => 'czech',
|
14
|
+
'da' => 'danish',
|
15
|
+
'nl' => 'dutch',
|
16
|
+
'en' => 'english',
|
17
|
+
'et' => 'estonian',
|
18
|
+
'tl' => 'filipino',
|
19
|
+
'fi' => 'finnish',
|
20
|
+
'fr' => 'french',
|
21
|
+
'gl' => 'galician',
|
22
|
+
'de' => 'german',
|
23
|
+
'el' => 'greek',
|
24
|
+
'iw' => 'hebrew',
|
25
|
+
'hi' => 'hindi',
|
26
|
+
'hu' => 'hungarian',
|
27
|
+
'is' => 'icelandic',
|
28
|
+
'id' => 'indonesian',
|
29
|
+
'ga' => 'irish',
|
30
|
+
'it' => 'italian',
|
31
|
+
'ja' => 'japanese',
|
32
|
+
'ko' => 'korean',
|
33
|
+
'lv' => 'latvian',
|
34
|
+
'lt' => 'lithuanian',
|
35
|
+
'mk' => 'macedonian',
|
36
|
+
'ms' => 'malay',
|
37
|
+
'mt' => 'maltese',
|
38
|
+
'no' => 'norwegian',
|
39
|
+
'fa' => 'persian',
|
40
|
+
'pl' => 'polish',
|
41
|
+
'pt' => 'portuguese',
|
42
|
+
'ro' => 'romanian',
|
43
|
+
'ru' => 'russian',
|
44
|
+
'sr' => 'serbian',
|
45
|
+
'sk' => 'slovak',
|
46
|
+
'sl' => 'slovenian',
|
47
|
+
'es' => 'spanish',
|
48
|
+
'sw' => 'swahili',
|
49
|
+
'sv' => 'swedish',
|
50
|
+
'th' => 'thai',
|
51
|
+
'tr' => 'turkish',
|
52
|
+
'uk' => 'ukrainian',
|
53
|
+
'vi' => 'vietnamese',
|
54
|
+
'cy' => 'welsh',
|
55
|
+
'yi' => 'yiddish'
|
56
|
+
}
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module EasyTranslate
|
6
|
+
|
7
|
+
class Request
|
8
|
+
|
9
|
+
# Body, blank by default
|
10
|
+
# @return [String] The body for this request
|
11
|
+
def body
|
12
|
+
''
|
13
|
+
end
|
14
|
+
|
15
|
+
# The path for the request
|
16
|
+
# @return [String] The path for this request
|
17
|
+
def path
|
18
|
+
raise NotImplementedError.new('path is not implemented')
|
19
|
+
end
|
20
|
+
|
21
|
+
# The base params for a request
|
22
|
+
# @return [Hash] a hash of the base parameters for any request
|
23
|
+
def params
|
24
|
+
params = {}
|
25
|
+
params[:key] = EasyTranslate.api_key if EasyTranslate.api_key
|
26
|
+
params[:prettyPrint] = 'false' # eliminate unnecessary overhead
|
27
|
+
params
|
28
|
+
end
|
29
|
+
|
30
|
+
# Perform the given request
|
31
|
+
# @return [String] The response String
|
32
|
+
def perform_raw
|
33
|
+
# Get the URI
|
34
|
+
uri = URI.parse("https://www.googleapis.com#{path}?#{param_s}")
|
35
|
+
# Open the HTTP object
|
36
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
37
|
+
http.use_ssl = true
|
38
|
+
# Construct the request
|
39
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
40
|
+
request.add_field('X-HTTP-Method-Override', 'GET')
|
41
|
+
request.body = body
|
42
|
+
# Fire and return
|
43
|
+
response = http.request(request)
|
44
|
+
unless response.code == '200'
|
45
|
+
err = JSON.parse(response.body)['error']['errors'].first['message']
|
46
|
+
raise EasyTranslateException.new(err)
|
47
|
+
end
|
48
|
+
response.body
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Stringify the params
|
54
|
+
# @return [String] The params as a string
|
55
|
+
def param_s
|
56
|
+
params.map do |k, v|
|
57
|
+
"#{k}=#{v}" unless v.nil?
|
58
|
+
end.compact.join('&')
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'json'
|
2
|
+
require File.dirname(__FILE__) + '/request'
|
3
|
+
|
4
|
+
module EasyTranslate
|
5
|
+
|
6
|
+
module Translation
|
7
|
+
|
8
|
+
# Translate text
|
9
|
+
# @param [String, Array] texts - A single string or set of strings to translate
|
10
|
+
# @option options [String, Symbol] :source - The source language (optional)
|
11
|
+
# @option options [String, Symbol] :target - The target language (required)
|
12
|
+
# @option options [Boolean] :html - Whether or not the supplied string is HTML (optional)
|
13
|
+
# @return [String, Array] Translated text or texts
|
14
|
+
def translate(texts, options = {})
|
15
|
+
request = TranslationRequest.new(texts, options)
|
16
|
+
# Turn the response into an array of translations
|
17
|
+
raw = request.perform_raw
|
18
|
+
translations = JSON.parse(raw)['data']['translations'].map do |res|
|
19
|
+
res['translatedText']
|
20
|
+
end
|
21
|
+
# And then return, if they only asked for one, only give one back
|
22
|
+
request.multi? ? translations : translations.first
|
23
|
+
end
|
24
|
+
|
25
|
+
# A convenience class for wrapping a translation request
|
26
|
+
class TranslationRequest < EasyTranslate::Request
|
27
|
+
|
28
|
+
# Set the texts and options
|
29
|
+
# @param [String, Array] texts - the text (or texts) to translate
|
30
|
+
# @param [Hash] options - Options to override or pass along with the request
|
31
|
+
def initialize(texts, options)
|
32
|
+
self.texts = texts
|
33
|
+
self.html = options.delete(:html)
|
34
|
+
@source = options.delete(:from)
|
35
|
+
@target = options.delete(:to)
|
36
|
+
raise ArgumentError.new('No target language provded') unless @target
|
37
|
+
raise ArgumentError.new('Support for multiple targets dropped in V2') if @target.is_a?(Array)
|
38
|
+
if options
|
39
|
+
@options = options
|
40
|
+
if replacement_api_key = @options.delete(:api_key)
|
41
|
+
@options[:key] = replacement_api_key
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# The params for this request
|
47
|
+
# @return [Hash] the params for the request
|
48
|
+
def params
|
49
|
+
params = super || {}
|
50
|
+
params[:source] = lang(@source) unless @source.nil?
|
51
|
+
params[:target] = lang(@target) unless @target.nil?
|
52
|
+
params[:format] = @format unless @format.nil?
|
53
|
+
params.merge! @options if @options
|
54
|
+
params
|
55
|
+
end
|
56
|
+
|
57
|
+
# The path for the request
|
58
|
+
# @return [String] The path for the request
|
59
|
+
def path
|
60
|
+
'/language/translate/v2'
|
61
|
+
end
|
62
|
+
|
63
|
+
# The body for the request
|
64
|
+
# @return [String] the body for the request, URL escaped
|
65
|
+
def body
|
66
|
+
@texts.map { |t| "q=#{URI.escape(t)}" }.join '&'
|
67
|
+
end
|
68
|
+
|
69
|
+
# Whether or not this was a request for multiple texts
|
70
|
+
# @return [Boolean]
|
71
|
+
def multi?
|
72
|
+
@multi
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Look up a language in the table (if needed)
|
78
|
+
def lang(orig)
|
79
|
+
look = orig.is_a?(String) ? orig : orig.to_s
|
80
|
+
return look if LANGUAGES[look] # shortcut iteration
|
81
|
+
if val = LANGUAGES.detect { |k, v| v == look }
|
82
|
+
return val.first
|
83
|
+
end
|
84
|
+
look
|
85
|
+
end
|
86
|
+
|
87
|
+
# Set the HTML attribute, if true add a format
|
88
|
+
# @param [Boolean] b - Whether or not the text supplied iS HTML
|
89
|
+
def html=(b)
|
90
|
+
@format = b ? 'html' : nil
|
91
|
+
end
|
92
|
+
|
93
|
+
# Set the texts for this request
|
94
|
+
# @param [String, Array] texts - The text or texts for this request
|
95
|
+
def texts=(texts)
|
96
|
+
if texts.is_a?(String)
|
97
|
+
@multi = false
|
98
|
+
@texts = [texts]
|
99
|
+
else
|
100
|
+
@multi = true
|
101
|
+
@texts = texts
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,97 +1,76 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_translate
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 1
|
10
|
-
version: 0.2.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- John Crepezzi
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-01-03 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: rspec
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70158452480400 !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
33
22
|
type: :development
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: json
|
37
23
|
prerelease: false
|
38
|
-
|
24
|
+
version_requirements: *70158452480400
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
requirement: &70158452479660 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
segments:
|
45
|
-
- 0
|
46
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
47
33
|
type: :runtime
|
48
|
-
|
49
|
-
|
50
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70158452479660
|
36
|
+
description: easy_translate is a wrapper for the google translate API that makes sense
|
37
|
+
programatically, and implements API keys
|
38
|
+
email: john.crepezzi@gmail.com
|
51
39
|
executables: []
|
52
|
-
|
53
40
|
extensions: []
|
54
|
-
|
55
41
|
extra_rdoc_files: []
|
56
|
-
|
57
|
-
|
58
|
-
- lib/easy_translate/
|
59
|
-
- lib/easy_translate/
|
42
|
+
files:
|
43
|
+
- lib/easy_translate/detection.rb
|
44
|
+
- lib/easy_translate/easy_translate_exception.rb
|
45
|
+
- lib/easy_translate/languages.rb
|
46
|
+
- lib/easy_translate/request.rb
|
47
|
+
- lib/easy_translate/translation.rb
|
60
48
|
- lib/easy_translate/version.rb
|
61
49
|
- lib/easy_translate.rb
|
62
|
-
|
63
|
-
homepage:
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
homepage: https://github.com/seejohnrun/easy_translate
|
64
52
|
licenses: []
|
65
|
-
|
66
53
|
post_install_message:
|
67
54
|
rdoc_options: []
|
68
|
-
|
69
|
-
require_paths:
|
55
|
+
require_paths:
|
70
56
|
- lib
|
71
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
58
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
|
78
|
-
- 0
|
79
|
-
version: "0"
|
80
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
64
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
|
86
|
-
segments:
|
87
|
-
- 0
|
88
|
-
version: "0"
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
89
69
|
requirements: []
|
90
|
-
|
91
|
-
|
92
|
-
rubygems_version: 1.3.7
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.8.10
|
93
72
|
signing_key:
|
94
73
|
specification_version: 3
|
95
74
|
summary: Google Translate API Wrapper for Ruby
|
96
|
-
test_files:
|
97
|
-
|
75
|
+
test_files:
|
76
|
+
- spec/spec_helper.rb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module EasyTranslate
|
2
|
-
|
3
|
-
class ParamBuilder
|
4
|
-
|
5
|
-
def initialize
|
6
|
-
@str = ''
|
7
|
-
end
|
8
|
-
|
9
|
-
def add(param, value)
|
10
|
-
if @str.empty?
|
11
|
-
@str << "#{param.to_s}=#{value}"
|
12
|
-
else
|
13
|
-
@str << "&#{param.to_s}=#{value}"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
@str
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,159 +0,0 @@
|
|
1
|
-
module EasyTranslate
|
2
|
-
|
3
|
-
class <<self
|
4
|
-
attr_accessor :api_key
|
5
|
-
end
|
6
|
-
|
7
|
-
# Detect the language of a given string of text.
|
8
|
-
# Optional parameters:
|
9
|
-
# :key - API key for google language (defaults to nil)
|
10
|
-
# :host_language - language (defaults to 'en')
|
11
|
-
# :user_ip - the ip of the end user - will help not be mistaken for abuse
|
12
|
-
# Required Parameters:
|
13
|
-
# the text to detect the language for
|
14
|
-
# Returns:
|
15
|
-
# the string language code (ie: 'en') of the language
|
16
|
-
# Note:
|
17
|
-
# This API (since it focuses more on tranlations/ease, does not return
|
18
|
-
# confidence ratings)
|
19
|
-
def self.detect(text, options = {})
|
20
|
-
params = base_params(text, options)
|
21
|
-
params.add :q, URI.escape(text)
|
22
|
-
json = api_call EasyTranslate::API_DETECT_PATH, params, :type => :get
|
23
|
-
json['responseData']['language']
|
24
|
-
end
|
25
|
-
|
26
|
-
# Translate batches of string using Google Translate
|
27
|
-
# Optional parameters:
|
28
|
-
# :key - API key for google language (defaults to nil)
|
29
|
-
# :host_language - language (defaults to 'en') (symbol/string)
|
30
|
-
# :user_ip - the ip of the end user - will help not be mistaken for abuse
|
31
|
-
# :from - the language to translate from (symbol/string)
|
32
|
-
# :html - boolean indicating whether the text you're translating is HTML or plaintext
|
33
|
-
# Required Parameters:
|
34
|
-
# the text(s) to translate (string/array)
|
35
|
-
# :to - the language(s) to translate to (symbol/string/array)
|
36
|
-
# Returns:
|
37
|
-
# string / an array of the translated strings
|
38
|
-
def self.translate(text, options)
|
39
|
-
# what type of call is this?
|
40
|
-
multi_call = options[:to].class == Array || text.class == Array
|
41
|
-
all_multi_call = options[:to].class == Array && text.class == Array
|
42
|
-
# translate params if necessary
|
43
|
-
to_lang = (options[:to].class == Array) ? options[:to].map { |to| get_language(to) } : get_language(options[:to])
|
44
|
-
from_lang = get_language(options[:from])
|
45
|
-
# make the call
|
46
|
-
params = base_params(text, options)
|
47
|
-
params.add :format, (options[:html] ? 'html' : 'text')
|
48
|
-
# for each to language, put all of the q's
|
49
|
-
to_lang = [to_lang] if to_lang.is_a?(String)
|
50
|
-
to_lang.each do |tol|
|
51
|
-
escaped_lang_pair = URI.escape "#{from_lang}|#{tol}"
|
52
|
-
# because ruby let's us call .each on a string with newlines
|
53
|
-
text = [text] if text.is_a?(String) # sorry, TODO separate
|
54
|
-
text.each do |t|
|
55
|
-
params.add :q, URI.escape(t)
|
56
|
-
params.add :langpair, escaped_lang_pair
|
57
|
-
end
|
58
|
-
end
|
59
|
-
# TODO cleanup
|
60
|
-
# get the proper response and return
|
61
|
-
json = api_call EasyTranslate::API_TRANSLATE_PATH, params, :type => :post
|
62
|
-
# single argument is returned
|
63
|
-
if !multi_call
|
64
|
-
single_single(json)
|
65
|
-
# array should be returned
|
66
|
-
elsif multi_call && !all_multi_call
|
67
|
-
single_multiple(json)
|
68
|
-
# the big badass case
|
69
|
-
else
|
70
|
-
multiple_multiple(json, options[:to].size)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# an exception indicating something went wrong in EasyTranslate
|
75
|
-
class EasyTranslateException < Exception
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
def self.multiple_multiple(json, translation_count)
|
81
|
-
if json['responseData'].class == Hash
|
82
|
-
[[json['responseData']['translatedText']]]
|
83
|
-
else
|
84
|
-
translations = []
|
85
|
-
responseData = json['responseData'].map { |r| r['responseData']['translatedText'] }
|
86
|
-
per_bucket = responseData.size / translation_count # should always be integer
|
87
|
-
0.upto(translation_count - 1) { |i| translations[i] = responseData.slice(i * per_bucket, per_bucket) }
|
88
|
-
end
|
89
|
-
translations
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.single_multiple(json)
|
93
|
-
if json['responseData'].class == Hash
|
94
|
-
[json['responseData']['translatedText']]
|
95
|
-
else
|
96
|
-
json['responseData'].map { |j| j['responseData']['translatedText'] }
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def self.single_single(json)
|
101
|
-
json['responseData']['translatedText']
|
102
|
-
end
|
103
|
-
|
104
|
-
# take in the base parameters for the google translate api
|
105
|
-
def self.base_params(text, options)
|
106
|
-
raise ArgumentError.new('multiple :from not allowed') if options[:from] && options[:from].class == Array
|
107
|
-
raise ArgumentError.new('no string given') if text.empty?
|
108
|
-
key = options[:key] || EasyTranslate.api_key || nil
|
109
|
-
params = ParamBuilder.new
|
110
|
-
params.add :v, API_VERSION
|
111
|
-
params.add :user_ip, URI.escape(options[:user_ip]) if options.has_key?(:user_ip)
|
112
|
-
params.add :hl, URI.escape(get_language(options[:host_language])) if options.has_key?(:host_language)
|
113
|
-
params.add :key, URI.escape(key) if key
|
114
|
-
# key is standard - but left to individual methods
|
115
|
-
params
|
116
|
-
end
|
117
|
-
|
118
|
-
# make a call to the api and throw an error on non-200 response
|
119
|
-
# TODO expand error handling
|
120
|
-
def self.api_call(path, params, options = {:type => :get})
|
121
|
-
response = case options[:type]
|
122
|
-
when :get ; api_get_call(path, params)
|
123
|
-
when :post ; api_post_call(path, params)
|
124
|
-
else ; ArgumentError.new('Bad HTTP type')
|
125
|
-
end
|
126
|
-
# if we got a response, use it - otherwise, fail town
|
127
|
-
json = JSON.parse(response) if response
|
128
|
-
raise EasyTranslateException.new(json['responseDetails']) unless json && json['responseStatus'] == 200
|
129
|
-
json
|
130
|
-
end
|
131
|
-
|
132
|
-
def self.api_post_call(path, params)
|
133
|
-
http = Net::HTTP.new(EasyTranslate::API_URL)
|
134
|
-
response = http.post(path, params.to_s)
|
135
|
-
response.body if response
|
136
|
-
end
|
137
|
-
|
138
|
-
def self.api_get_call(path, params)
|
139
|
-
http = Net::HTTP.new(EasyTranslate::API_URL)
|
140
|
-
response = http.get("#{path}?#{params.to_s}")
|
141
|
-
response.body if response
|
142
|
-
end
|
143
|
-
|
144
|
-
def self.index_func
|
145
|
-
return @index_func if @index_func
|
146
|
-
Hash.instance_methods.include?(:key) ? :key : :index
|
147
|
-
end
|
148
|
-
|
149
|
-
# a function used to get the lang code of any input.
|
150
|
-
# can take -- :english, 'english', :en, 'en'
|
151
|
-
def self.get_language(lang)
|
152
|
-
return unless lang
|
153
|
-
lang = lang.to_s
|
154
|
-
lang = EasyTranslate::LANGUAGES.include?(lang) ? lang : EasyTranslate::LANGUAGES.send(index_func, lang)
|
155
|
-
raise ArgumentError.new('please supply a valid language') unless lang
|
156
|
-
lang
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|