bing_translator_fix 4.5.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.
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: []