bing_translator 6.0.0 → 6.1.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.
- checksums.yaml +5 -5
- data/lib/bing_translator.rb +171 -165
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5f88718168ee707a700ed926c13ff7539155d5e94535145c912672520a166f72
|
4
|
+
data.tar.gz: 0d5afc1c573bb1c613a7ca77fc7cc8ae2373477677845b3b21f4e425b6ea2fa1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61a293de90f373bbe12a79989c32a416949b557761dcfb3a773b7fb5c2f9a3bb1657bc084661dee065aa603c0497ada6bf3e6fbc66ea17c99a4f2bfb200a7b6f
|
7
|
+
data.tar.gz: 0d9afa36690c92b84987392f5b5ca1d970e5b057144f355fe8733e304a4acc444522159fd0fc8bbc5510c6a2417872972b84aa77124dbfd2d45899e9e2a5a6d1
|
data/lib/bing_translator.rb
CHANGED
@@ -1,165 +1,171 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# (c) 2011-present. Ricky Elrod <ricky@elrod.me>
|
4
|
-
# Released under the MIT license.
|
5
|
-
require 'rubygems'
|
6
|
-
require 'cgi'
|
7
|
-
require 'uri'
|
8
|
-
require 'net/http'
|
9
|
-
require 'net/https'
|
10
|
-
require 'json'
|
11
|
-
|
12
|
-
class BingTranslator
|
13
|
-
class Exception < StandardError; end
|
14
|
-
|
15
|
-
class ApiClient
|
16
|
-
API_HOST = 'https://api.cognitive.microsofttranslator.com'.freeze
|
17
|
-
COGNITIVE_ACCESS_TOKEN_URI =
|
18
|
-
URI.parse('https://api.cognitive.microsoft.com/sts/v1.0/issueToken').freeze
|
19
|
-
|
20
|
-
def initialize(subscription_key, skip_ssl_verify)
|
21
|
-
@subscription_key = subscription_key
|
22
|
-
@skip_ssl_verify = skip_ssl_verify
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
headers
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
http
|
62
|
-
http
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
translations
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# (c) 2011-present. Ricky Elrod <ricky@elrod.me>
|
4
|
+
# Released under the MIT license.
|
5
|
+
require 'rubygems'
|
6
|
+
require 'cgi'
|
7
|
+
require 'uri'
|
8
|
+
require 'net/http'
|
9
|
+
require 'net/https'
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
class BingTranslator
|
13
|
+
class Exception < StandardError; end
|
14
|
+
|
15
|
+
class ApiClient
|
16
|
+
API_HOST = 'https://api.cognitive.microsofttranslator.com'.freeze
|
17
|
+
COGNITIVE_ACCESS_TOKEN_URI =
|
18
|
+
URI.parse('https://api.cognitive.microsoft.com/sts/v1.0/issueToken').freeze
|
19
|
+
|
20
|
+
def initialize(subscription_key, skip_ssl_verify, read_timeout = 60, open_timeout = 60)
|
21
|
+
@subscription_key = subscription_key
|
22
|
+
@skip_ssl_verify = skip_ssl_verify
|
23
|
+
@read_timeout = read_timeout
|
24
|
+
@open_timeout = open_timeout
|
25
|
+
end
|
26
|
+
|
27
|
+
def get(path, params: {}, headers: {}, authorization: false)
|
28
|
+
uri = request_uri(path, params)
|
29
|
+
request = Net::HTTP::Get.new(uri.request_uri, default_headers(authorization).merge(headers))
|
30
|
+
|
31
|
+
json_response(uri, request)
|
32
|
+
end
|
33
|
+
|
34
|
+
def post(path, params: {}, headers: {}, data: {}, authorization: true)
|
35
|
+
uri = request_uri(path, params)
|
36
|
+
|
37
|
+
request = Net::HTTP::Post.new(uri.request_uri, default_headers(authorization).merge(headers))
|
38
|
+
request.body = data
|
39
|
+
|
40
|
+
json_response(uri, request)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def default_headers(authorization = true)
|
46
|
+
headers = { 'Content-Type' => 'application/json' }
|
47
|
+
headers['Authorization'] = "Bearer #{access_token}" if authorization
|
48
|
+
headers
|
49
|
+
end
|
50
|
+
|
51
|
+
def json_response(uri, request)
|
52
|
+
http = http_client(uri)
|
53
|
+
|
54
|
+
response = http.request(request)
|
55
|
+
|
56
|
+
raise Exception.new("Unsuccessful API call: Code: #{response.code}") unless response.code == '200'
|
57
|
+
JSON.parse(response.body)
|
58
|
+
end
|
59
|
+
|
60
|
+
def http_client(uri)
|
61
|
+
http = Net::HTTP.new(uri.host, 443)
|
62
|
+
http.use_ssl = true
|
63
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @skip_ssl_verify
|
64
|
+
http.read_timeout = @read_timeout
|
65
|
+
http.open_timeout = @open_timeout
|
66
|
+
http
|
67
|
+
end
|
68
|
+
|
69
|
+
def request_uri(path, params)
|
70
|
+
encoded_params = URI.encode_www_form(params.merge('api-version' => '3.0'))
|
71
|
+
uri = URI.parse("#{API_HOST}#{path}")
|
72
|
+
uri.query = encoded_params
|
73
|
+
uri
|
74
|
+
end
|
75
|
+
|
76
|
+
def access_token
|
77
|
+
if @access_token.nil? || Time.now >= @access_token_expiration_time
|
78
|
+
@access_token = request_new_access_token
|
79
|
+
end
|
80
|
+
@access_token
|
81
|
+
end
|
82
|
+
|
83
|
+
def request_new_access_token
|
84
|
+
headers = {
|
85
|
+
'Ocp-Apim-Subscription-Key' => @subscription_key
|
86
|
+
}
|
87
|
+
|
88
|
+
http = Net::HTTP.new(COGNITIVE_ACCESS_TOKEN_URI.host, COGNITIVE_ACCESS_TOKEN_URI.port)
|
89
|
+
http.use_ssl = true
|
90
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @skip_ssl_verify
|
91
|
+
|
92
|
+
response = http.post(COGNITIVE_ACCESS_TOKEN_URI.path, '', headers)
|
93
|
+
if response.code != '200'
|
94
|
+
raise Exception.new('Invalid credentials')
|
95
|
+
else
|
96
|
+
@access_token_expiration_time = Time.now + 480
|
97
|
+
response.body
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def initialize(subscription_key, options = {})
|
103
|
+
skip_ssl_verify = options.fetch(:skip_ssl_verify, false)
|
104
|
+
read_timeout = options.fetch(:read_timeout, 60)
|
105
|
+
open_timeout = options.fetch(:open_timeout, 60)
|
106
|
+
@api_client = ApiClient.new(subscription_key, skip_ssl_verify, read_timeout, open_timeout)
|
107
|
+
end
|
108
|
+
|
109
|
+
def translate(text, params)
|
110
|
+
translate_array([text], params).first
|
111
|
+
end
|
112
|
+
|
113
|
+
def translate_array(texts, params = {})
|
114
|
+
translations = translation_request(texts, params)
|
115
|
+
translations.map do |translation|
|
116
|
+
translation['text'] if translation.is_a?(Hash)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def translate_array2(texts, params = {})
|
121
|
+
translations = translation_request(texts, params.merge('includeAlignment' => true))
|
122
|
+
translations.map do |translation|
|
123
|
+
[translation['text'], translation['alignment']['proj']] if translation.is_a?(Hash)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def detect(text)
|
128
|
+
data = [{ 'Text' => text }].to_json
|
129
|
+
|
130
|
+
response_json = api_client.post('/detect', data: data)
|
131
|
+
best_detection = response_json.sort_by { |detection| -detection['score'] }.first
|
132
|
+
best_detection['language'].to_sym
|
133
|
+
end
|
134
|
+
|
135
|
+
def speak(text, params = {})
|
136
|
+
raise Exception.new('Not supported since 3.0.0')
|
137
|
+
end
|
138
|
+
|
139
|
+
def supported_language_codes
|
140
|
+
response_json = api_client.get('/languages',
|
141
|
+
params: { scope: 'translation' },
|
142
|
+
authorization: false)
|
143
|
+
response_json['translation'].keys
|
144
|
+
end
|
145
|
+
|
146
|
+
def language_names(codes, locale = 'en')
|
147
|
+
response_json = api_client.get('/languages',
|
148
|
+
params: { scope: 'translation' },
|
149
|
+
headers: { 'Accept-Language' => locale },
|
150
|
+
authorization: false)
|
151
|
+
codes.map do |code|
|
152
|
+
response = response_json['translation'][code.to_s]
|
153
|
+
response['name'] unless response.nil?
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
attr_reader :api_client
|
160
|
+
|
161
|
+
def translation_request(texts, params)
|
162
|
+
raise Exception.new('Must provide :to.') if params[:to].nil?
|
163
|
+
|
164
|
+
data = texts.map { |text| { 'Text' => text } }.to_json
|
165
|
+
response_json = api_client.post('/translate', params: params, data: data)
|
166
|
+
response_json.map do |translation|
|
167
|
+
# There should be just one translation, but who knows...
|
168
|
+
translation['translations'].find { |result| result['to'] == params[:to].to_s }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bing_translator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ricky Elrod
|
@@ -52,9 +52,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
52
|
version: '0'
|
53
53
|
requirements: []
|
54
54
|
rubyforge_project:
|
55
|
-
rubygems_version: 2.
|
55
|
+
rubygems_version: 2.7.6.2
|
56
56
|
signing_key:
|
57
57
|
specification_version: 4
|
58
58
|
summary: Translate using the Bing HTTP API
|
59
59
|
test_files: []
|
60
|
-
has_rdoc:
|