bing_translator_fix 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/bing_translator.rb +213 -0
  3. metadata +87 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f0ee46cc98df19d4b842d8fea57cf904a160daa1
4
+ data.tar.gz: 259c5eba544b0b5e6991ce671aa4f1cda0a9c24b
5
+ SHA512:
6
+ metadata.gz: 4dcd2029d7385d3f93a8c7b9c96d29859b1606bbd1b027229bbb6d0b27ee147f72d7fe25de7fb41e5686eb0dbbd6bb4cd955b9dc6232515f75fe7423fc933159
7
+ data.tar.gz: b676f8085d6d1e2bb49718466816a9ca2a152818cdaf187e8550d1edb24e1b3d02527a38d55f35220b06961ccbc501ab70447540d9685d0dfd1debc802f8c8f8
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
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 'nokogiri'
11
+ require 'json'
12
+ require 'savon'
13
+
14
+ class BingTranslator
15
+ WSDL_URI = 'http://api.microsofttranslator.com/V2/soap.svc?wsdl'
16
+ NAMESPACE_URI = 'http://api.microsofttranslator.com/V2'
17
+ ACCESS_TOKEN_URI = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13'
18
+ DATASETS_URI = "https://api.datamarket.azure.com/Services/My/Datasets?$format=json"
19
+
20
+ class Exception < StandardError; end
21
+ class AuthenticationException < StandardError; end
22
+
23
+ def initialize(client_id, client_secret, skip_ssl_verify = false, account_key = nil)
24
+ @client_id = client_id
25
+ @client_secret = client_secret
26
+ @account_key = account_key
27
+ @skip_ssl_verify = skip_ssl_verify
28
+
29
+ @access_token_uri = URI.parse ACCESS_TOKEN_URI
30
+ @datasets_uri = URI.parse DATASETS_URI
31
+ end
32
+
33
+ def translate(text, params = {})
34
+ raise "Must provide :to." if params[:to].nil?
35
+
36
+ # Important notice: param order makes sense in SOAP. Do not reorder or delete!
37
+ params = {
38
+ 'text' => text.to_s,
39
+ 'from' => params[:from].to_s,
40
+ 'to' => params[:to].to_s,
41
+ 'category' => 'general',
42
+ 'contentType' => params[:content_type] || 'text/plain'
43
+ }
44
+
45
+ result(:translate, params)
46
+ end
47
+
48
+ def translate_array(texts, params = {})
49
+ raise "Must provide :to." if params[:to].nil?
50
+
51
+ # Important notice: param order makes sense in SOAP. Do not reorder or delete!
52
+ params = {
53
+ 'texts' => { 'arr:string' => texts },
54
+ 'from' => params[:from].to_s,
55
+ 'to' => params[:to].to_s,
56
+ 'category' => 'general',
57
+ 'contentType' => params[:content_type] || 'text/plain'
58
+ }
59
+
60
+ array_wrap(result(:translate_array, params)[:translate_array_response]).map{|r| r[:translated_text]}
61
+ end
62
+
63
+ def detect(text)
64
+ params = {
65
+ 'text' => text.to_s,
66
+ 'language' => '',
67
+ }
68
+
69
+ result(:detect, params).to_sym
70
+ end
71
+
72
+ # format: 'audio/wav' [default] or 'audio/mp3'
73
+ # language: valid translator language code
74
+ # options: 'MinSize' [default] or 'MaxQuality'
75
+ def speak(text, params = {})
76
+ raise "Must provide :language" if params[:language].nil?
77
+
78
+ params = {
79
+ 'text' => text.to_s,
80
+ 'language' => params[:language].to_s,
81
+ 'format' => params[:format] || 'audio/wav',
82
+ 'options' => params[:options] || 'MinSize',
83
+ }
84
+
85
+ uri = URI.parse(result(:speak, params))
86
+
87
+ http = Net::HTTP.new(uri.host, uri.port)
88
+ if uri.scheme == "https"
89
+ http.use_ssl = true
90
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @skip_ssl_verify
91
+ end
92
+ results = http.get(uri.to_s, {'Authorization' => "Bearer #{get_access_token['access_token']}"})
93
+
94
+ if results.response.code.to_i == 200
95
+ results.body
96
+ else
97
+ html = Nokogiri::HTML(results.body)
98
+ raise Exception, html.xpath("//text()").remove.map(&:to_s).join(' ')
99
+ end
100
+ end
101
+
102
+ def supported_language_codes
103
+ result(:get_languages_for_translate)[:string]
104
+ end
105
+
106
+ def language_names(codes, locale = 'en')
107
+ response = result(:get_language_names, locale: locale, languageCodes: {'a:string' => codes}) do
108
+ attributes 'xmlns:a' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
109
+ end
110
+
111
+ response[:string]
112
+ end
113
+
114
+ def balance
115
+ datasets["d"]["results"].each do |result|
116
+ return result["ResourceBalance"] if result["ProviderName"] == "Microsoft Translator"
117
+ end
118
+ end
119
+
120
+ # Get a new access token and set it internally as @access_token
121
+ #
122
+ # Microsoft changed up how you get access to the Translate API.
123
+ # This gets a new token if it's required. We call this internally
124
+ # before any request we make to the Translate API.
125
+ #
126
+ # @return {hash}
127
+ # Returns existing @access_token if we don't need a new token yet,
128
+ # or returns the one just obtained.
129
+ def get_access_token
130
+ return @access_token if @access_token and
131
+ Time.now < @access_token['expires_at']
132
+
133
+ params = {
134
+ 'client_id' => CGI.escape(@client_id),
135
+ 'client_secret' => CGI.escape(@client_secret),
136
+ 'scope' => CGI.escape('http://api.microsofttranslator.com'),
137
+ 'grant_type' => 'client_credentials'
138
+ }
139
+
140
+ http = Net::HTTP.new(@access_token_uri.host, @access_token_uri.port)
141
+ http.use_ssl = true
142
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @skip_ssl_verify
143
+
144
+ response = http.post(@access_token_uri.path, prepare_param_string(params))
145
+ @access_token = JSON.parse(response.body)
146
+ raise AuthenticationException, @access_token['error'] if @access_token["error"]
147
+ @access_token['expires_at'] = Time.now + @access_token['expires_in'].to_i
148
+ @access_token
149
+ end
150
+
151
+ private
152
+ def datasets
153
+ raise AuthenticationException, "Must provide account key" if @account_key.nil?
154
+
155
+ http = Net::HTTP.new(@datasets_uri.host, @datasets_uri.port)
156
+ http.use_ssl = true
157
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
158
+ request = Net::HTTP::Get.new(@datasets_uri.request_uri)
159
+ request.basic_auth("", @account_key)
160
+ response = http.request(request)
161
+
162
+ JSON.parse response.body
163
+ end
164
+
165
+ def prepare_param_string(params)
166
+ params.map { |key, value| "#{key}=#{value}" }.join '&'
167
+ end
168
+
169
+ # Public: performs actual request to Bing Translator SOAP API
170
+ def result(action, params = {}, &block)
171
+ # Specify SOAP namespace in tag names (see https://github.com/savonrb/savon/issues/340 )
172
+ params = Hash[params.map{|k,v| ["v2:#{k}", v]}]
173
+ begin
174
+ soap_client.call(action, message: params, &block).body[:"#{action}_response"][:"#{action}_result"]
175
+ rescue AuthenticationException
176
+ raise
177
+ rescue StandardError => e
178
+ # Keep old behaviour: raise only internal Exception class
179
+ raise Exception, e.message
180
+ end
181
+ end
182
+
183
+ # Private: Constructs SOAP client
184
+ #
185
+ # Construct and store new client when called first time.
186
+ # Return stored client while access token is fresh.
187
+ # Construct and store new client when token have been expired.
188
+ def soap_client
189
+ return @client if @client and @access_token and
190
+ Time.now < @access_token['expires_at']
191
+
192
+ @client = Savon.client(
193
+ wsdl: WSDL_URI,
194
+ namespace: NAMESPACE_URI,
195
+ namespace_identifier: :v2,
196
+ namespaces: {
197
+ 'xmlns:arr' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
198
+ },
199
+ headers: {'Authorization' => "Bearer #{get_access_token['access_token']}"},
200
+ )
201
+ end
202
+
203
+ # Private: Array#wrap based on ActiveSupport extension
204
+ def array_wrap(object)
205
+ if object.nil?
206
+ []
207
+ elsif object.respond_to?(:to_ary)
208
+ object.to_ary || [object]
209
+ else
210
+ [object]
211
+ end
212
+ end
213
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bing_translator_fix
3
+ version: !ruby/object:Gem::Version
4
+ version: 4.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Ricky Elrod
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.6.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.6.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: savon
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.10.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.10.0
55
+ description: Translate strings using the Bing HTTP API. Requires that you have a Client
56
+ ID and Secret. See README.md for information.
57
+ email: ricky@elrod.me
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/bing_translator.rb
63
+ homepage: https://www.github.com/relrod/bing_translator-gem
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.4.8
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Translate using the Bing HTTP API
87
+ test_files: []