gengo 0.0.2 → 0.0.3

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/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gengo (0.0.0)
4
+ gengo (0.0.2)
5
5
  json
6
6
  mime-types
7
7
  multipart-post
data/README.md CHANGED
@@ -1,41 +1,44 @@
1
1
  [![Build Status](https://secure.travis-ci.org/gengo/gengo-ruby.png)](http://travis-ci.org/gengo/gengo-ruby)
2
+
2
3
  Gengo Ruby Library (for the [Gengo API](http://gengo.com/api/))
3
- ========================================================================================================
4
- Translating your tools and products helps people all over the world access them; this is, of course, a
5
- somewhat tricky problem to solve. **[Gengo](http://gengo.com/)** is a service that offers human-translation
6
- (which is often a higher quality than machine translation), and an API to manage sending in work and watching
7
- jobs. This is a ruby interface to make using the API simpler (some would say incredibly easy).
4
+ ======================================================================================================================================================
5
+ Translating your tools and products helps people all over the world access them; this is, of course, a somewhat tricky problem to solve.
6
+ **[Gengo](http://gengo.com/)** is a service that offers human-translation (which is often a higher quality than machine translation), and an API to
7
+ manage sending in work and watching jobs. This is a Ruby interface to make using the API simpler (some would say incredibly easy).
8
8
 
9
9
 
10
10
  Installation & Requirements
11
- -------------------------------------------------------------------------------------------------------
11
+ ------------------------------------------------------------------------------------------------------------------------------------------------------
12
12
  Installing Gengo is fairly simple:
13
13
 
14
- gem install gengo
14
+ ```sh
15
+ $ gem install gengo
16
+ ```
15
17
 
16
18
 
17
19
  Tests - Running Them, etc
18
- ------------------------------------------------------------------------------------------------------
19
- Gengo has a full suite of tests, however they're not currently automated. Each script in the _examples_
20
- directory tests a different Gengo API endpoint; run against those if you wish to test for now.
20
+ ------------------------------------------------------------------------------------------------------------------------------------------------------
21
+ Gengo has a full suite of tests, however they're not currently automated. Each script in the `examples` directory tests a different Gengo API
22
+ endpoint; run against those if you wish to test for now.
23
+
21
24
 
22
25
  Question, Comments, Complaints, Praise?
23
- ------------------------------------------------------------------------------------------------------
24
- If you have questions or comments and would like to reach us directly, please feel free to do
25
- so at the following outlets. We love hearing from developers!
26
+ ------------------------------------------------------------------------------------------------------------------------------------------------------
27
+ If you have questions or comments and would like to reach us directly, please feel free to do so at the following outlets. We love hearing from
28
+ developers!
26
29
 
27
- Email: api [at] gengo dot com
28
- Twitter: **[@gengo_dev](http://twitter.com/gengo_dev)**
30
+ * Email: api [at] gengo dot com
31
+ * Twitter: [@gengoit](https://twitter.com/gengoit)
32
+ * IRC: [#gengo](irc://irc.freenode.net/gengo)
29
33
 
30
- If you come across any issues, please file them on the **[Github project issue tracker](https://github.com/gengo/gengo-ruby/issues)**. Thanks!
34
+ If you come across any issues, please file them on the [Github project issue tracker](https://github.com/gengo/gengo-ruby/issues). Thanks!
31
35
 
32
36
 
33
37
  Documentation
34
- ------------------------------------------------------------------------------------------------------
35
- The usage of the API is very simple - the most important part is getting authenticated. To do this is just
36
- a few lines of code:
38
+ ------------------------------------------------------------------------------------------------------------------------------------------------------
39
+ The usage of the API is very simple - the most important part is getting authenticated. To do this is just a few lines of code:
37
40
 
38
- ``` ruby
41
+ ```ruby
39
42
  require 'gengo'
40
43
 
41
44
  gengo = Gengo::API.new({
@@ -48,6 +51,6 @@ gengo = Gengo::API.new({
48
51
  puts gengo.getAccountBalance()
49
52
  ```
50
53
 
51
- With that, you can call any number of methods supported by this library. The entire library is rdoc supported,
52
- so you can look at more method information there - there's also a full suite of test code/examples, located in the 'examples'
53
- directory. Enjoy!
54
+ With that, you can call any number of methods supported by this library. The entire library is rdoc supported, so you can look at more method
55
+ information there. There's also a full suite of test code/examples, located in the `examples` directory. Be sure to checkout the [Gengo API
56
+ documentation](http://developers.gengo.com). Enjoy!
@@ -12,422 +12,425 @@ require 'mime/types'
12
12
 
13
13
  module Gengo
14
14
 
15
- # The only real class that ever needs to be instantiated.
16
- class API
17
- attr_accessor :api_host
18
- attr_accessor :debug
19
- attr_accessor :client_info
20
-
21
- # Creates a new API handler to shuttle calls/jobs/etc over to the Gengo translation API.
22
- #
23
- # Options:
24
- # <tt>opts</tt> - A hash containing the api key, the api secret key, the API version (defaults to 1), whether to use
25
- # the sandbox API, and an optional custom user agent to send.
26
- def initialize(opts)
27
- # Consider this an example of the object you need to pass.
28
- @opts = {
29
- :public_key => '',
30
- :private_key => '',
31
- :api_version => '1.1',
32
- :sandbox => false,
33
- :user_agent => "Gengo Ruby Library; Version #{Gengo::Config::VERSION}; http://gengo.com/;",
34
- :debug => false,
35
- }.merge(opts)
36
-
37
- # Let's go ahead and separate these out, for clarity...
38
- @debug = @opts[:debug]
39
- @api_host = (@opts[:sandbox] == true ? Gengo::Config::SANDBOX_API_HOST : Gengo::Config::API_HOST)
40
-
41
- # More of a public "check this" kind of object.
42
- @client_info = {"VERSION" => Gengo::Config::VERSION}
43
- end
44
-
45
- # Use CGI escape to escape a string
46
- def urlencode(string)
47
- CGI::escape(string)
48
- end
49
-
50
- # Creates an HMAC::SHA1 signature, signing the timestamp with the private key.
51
- def signature_of(ts)
52
- OpenSSL::HMAC.hexdigest 'sha1', @opts[:private_key], ts
53
- end
54
-
55
- # The "GET" method; handles requesting basic data sets from Gengo and converting
56
- # the response to a Ruby hash/object.
57
- #
58
- # Options:
59
- # <tt>endpoint</tt> - String/URL to request data from.
60
- # <tt>params</tt> - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.
61
- def get_from_gengo(endpoint, params = {})
62
- # Do this small check here...
63
- is_delete = params.delete(:is_delete)
64
- is_download_file = params.delete(:is_download)
65
-
66
- # The first part of the object we're going to encode and use in our request to Gengo. The signing process
67
- # is a little annoying at the moment, so bear with us...
68
- query = params.reduce({}) {|hash_thus_far, (param_key, param_value)|
69
- hash_thus_far.merge(
70
- param_key.to_sym => param_value.to_s
71
- )
72
- }
73
-
74
- query[:api_key] = @opts[:public_key]
75
- query[:ts] = Time.now.gmtime.to_i.to_s
76
-
77
- endpoint << "?api_sig=" + signature_of(query[:ts])
78
- endpoint << '&' + query.map { |k, v| "#{k}=#{urlencode(v)}" }.join('&')
79
-
80
- uri = "/v#{@opts[:api_version]}/" + endpoint
81
- headers = {
82
- 'Accept' => 'application/json',
83
- 'User-Agent' => @opts[:user_agent]
84
- }
85
-
86
- if is_delete
87
- req = Net::HTTP::Delete.new(uri, headers)
88
- else
89
- req = Net::HTTP::Get.new(uri, headers)
90
- end
91
-
92
- http = Net::HTTP.start(@api_host, 80)
93
- if @debug
94
- http.set_debug_output($stdout)
95
- end
96
- http.read_timeout = 5*60
97
- resp = http.request(req)
98
-
99
- if is_download_file.nil?
100
- json = JSON.parse(resp.body)
101
- if json['opstat'] != 'ok'
102
- raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
103
- end
104
-
105
- # Return it if there are no problems, nice...
106
- return json
107
- else
108
- return resp.body
109
- end
110
-
111
- end
112
-
113
- # The "POST" method; handles shuttling up encoded job data to Gengo
114
- # for translation and such. Somewhat similar to the above methods, but depending on the scenario
115
- # can get some strange exceptions, so we're gonna keep them fairly separate for the time being. Consider
116
- # for a merger down the road...
117
- #
118
- # Options:
119
- # <tt>endpoint</tt> - String/URL to post data to.
120
- # <tt>params</tt> - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.
121
- def send_to_gengo(endpoint, params = {})
122
-
123
- # Check if this is a put
124
- is_put = params.delete(:is_put)
15
+ # The only real class that ever needs to be instantiated.
16
+ class API
17
+ attr_accessor :api_host
18
+ attr_accessor :debug
19
+ attr_accessor :client_info
20
+
21
+ # Creates a new API handler to shuttle calls/jobs/etc over to the Gengo translation API.
22
+ #
23
+ # Options:
24
+ # <tt>opts</tt> - A hash containing the api key, the api secret key, the API version (defaults to 1), whether to use
25
+ # the sandbox API, and an optional custom user agent to send.
26
+ def initialize(opts)
27
+ # Consider this an example of the object you need to pass.
28
+ @opts = {
29
+ :public_key => '',
30
+ :private_key => '',
31
+ :api_version => '2',
32
+ :sandbox => false,
33
+ :user_agent => "Gengo Ruby Library; Version #{Gengo::Config::VERSION}; http://gengo.com/;",
34
+ :debug => false,
35
+ }.merge(opts)
36
+
37
+ # Let's go ahead and separate these out, for clarity...
38
+ @debug = @opts[:debug]
39
+ @api_host = (@opts[:sandbox] == true ? Gengo::Config::SANDBOX_API_HOST : Gengo::Config::API_HOST)
40
+
41
+ # More of a public "check this" kind of object.
42
+ @client_info = {"VERSION" => Gengo::Config::VERSION}
43
+ end
44
+
45
+ # Use CGI escape to escape a string
46
+ def urlencode(string)
47
+ CGI::escape(string)
48
+ end
49
+
50
+ # Creates an HMAC::SHA1 signature, signing the timestamp with the private key.
51
+ def signature_of(ts)
52
+ OpenSSL::HMAC.hexdigest 'sha1', @opts[:private_key], ts
53
+ end
54
+
55
+ # The "GET" method; handles requesting basic data sets from Gengo and converting
56
+ # the response to a Ruby hash/object.
57
+ #
58
+ # Options:
59
+ # <tt>endpoint</tt> - String/URL to request data from.
60
+ # <tt>params</tt> - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.
61
+ def get_from_gengo(endpoint, params = {})
62
+ # Do this small check here...
63
+ is_delete = params.delete(:is_delete)
64
+ is_download_file = params.delete(:is_download)
65
+
66
+ # The first part of the object we're going to encode and use in our request to Gengo. The signing process
67
+ # is a little annoying at the moment, so bear with us...
68
+ query = params.reduce({}) do |hash_thus_far, (param_key, param_value)|
69
+ hash_thus_far.merge(param_key.to_sym => param_value.to_s)
70
+ end
125
71
 
126
- query = {
127
- :api_key => @opts[:public_key],
128
- :data => params.to_json.gsub('"', '\"'),
129
- :ts => Time.now.gmtime.to_i.to_s
130
- }
131
-
132
- url = URI.parse("http://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")
133
- http = Net::HTTP.new(url.host, url.port)
134
- http.read_timeout = 5*60
135
- if is_put
136
- request = Net::HTTP::Put.new(url.path)
137
- else
138
- request = Net::HTTP::Post.new(url.path)
139
- end
140
-
141
- request.add_field('Accept', 'application/json')
142
- request.add_field('User-Agent', @opts[:user_agent])
143
-
144
- request.content_type = 'application/x-www-form-urlencoded'
145
- request.body = {
146
- "api_sig" => signature_of(query[:ts]),
147
- "api_key" => urlencode(@opts[:public_key]),
148
- "data" => urlencode(params.to_json.gsub('\\', '\\\\')),
149
- "ts" => query[:ts].to_i.to_s
150
- }.map { |k, v| "#{k}=#{v}" }.flatten.join('&')
151
-
152
- if @debug
153
- http.set_debug_output($stdout)
154
- end
155
-
156
- resp = http.request(request)
157
-
158
- case resp
159
- when Net::HTTPSuccess, Net::HTTPRedirection
160
- json = JSON.parse(resp.body)
161
-
162
- if json['opstat'] != 'ok'
163
- raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
164
- end
165
-
166
- # Return it if there are no problems, nice...
167
- json
168
- else
169
- resp.error!
170
- end
171
- end
172
-
173
- # The "UPLOAD" method; handles sending a file to the quote method
174
- #
175
- # Options:
176
- # <tt>endpoint</tt> - String/URL to post data to.
177
- # <tt>params</tt> - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.
178
- def upload_to_gengo(endpoint, params = {})
179
-
180
- # prepare the file_hash and append file_key to each job payload
181
- files_hash = params[:jobs].each_value.reduce({}) do |hash_thus_far, job_values|
182
- if job_values[:file_path]
183
- job_mime_type = MIME::Types.type_for(job_values[:file_path]).first.content_type
184
- file_hash_key = "file_#{hash_thus_far.length.to_s}".to_sym
185
- job_values[:file_key] = file_hash_key
186
- hash_thus_far[file_hash_key] = UploadIO.new(File.open(job_values[:file_path]), job_mime_type, File.basename(job_values[:file_path]))
187
- end
188
- hash_thus_far
189
- end
190
-
191
- url = URI.parse("http://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")
192
-
193
- http = Net::HTTP.new(url.host, url.port)
194
- http.read_timeout = 5*60
195
-
196
- call_timestamp = Time.now.gmtime.to_i.to_s
197
-
198
- the_hash = files_hash.merge({
199
- "api_sig" => signature_of(call_timestamp),
200
- "api_key" => @opts[:public_key],
201
- "data" =>params.to_json.gsub('\\', '\\\\'),
202
- "ts" => call_timestamp
203
- })
204
-
205
- request = Net::HTTP::Post::Multipart.new(url.path, the_hash, {'Accept' => 'application/json', 'User-Agent' => @opts[:user_agent] })
206
-
207
- if @debug
208
- http.set_debug_output($stdout)
209
- end
210
-
211
- resp = http.request(request)
212
-
213
- case resp
214
- when Net::HTTPSuccess, Net::HTTPRedirection
215
- json = JSON.parse(resp.body)
216
-
217
- if json['opstat'] != 'ok'
218
- raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
219
- end
220
-
221
- # Return it if there are no problems, nice...
222
- json
223
- else
224
- resp.error!
225
- end
226
- end
227
-
228
- # Returns a Ruby-hash of the stats for the current account. No arguments required!
229
- #
230
- # Options:
231
- # <tt>None</tt> - N/A
232
- def getAccountStats(params = {})
233
- self.get_from_gengo('account/stats', params)
234
- end
72
+ query[:api_key] = @opts[:public_key]
73
+ query[:ts] = Time.now.gmtime.to_i.to_s
235
74
 
236
- # Returns a Ruby-hash of the balance for the authenticated account. No args required!
237
- #
238
- # Options:
239
- # <tt>None</tt> - N/A
240
- def getAccountBalance(params = {})
241
- self.get_from_gengo('account/balance', params)
242
- end
75
+ endpoint << "?api_sig=" + signature_of(query[:ts])
76
+ endpoint << '&' + query.map { |k, v| "#{k}=#{urlencode(v)}" }.join('&')
243
77
 
244
- # Posts a translation job over to Gengo, returns a response indicating whether the submission was
245
- # successful or not. Param list is quite expansive here, pay attention...
246
- #
247
- # Options:
248
- # <tt>job</tt> - A job is a hash of data describing what you want translated. See the examples included for
249
- # more information on what this should be. (type/slug/body_src/lc_src/lc_tgt/tier/auto_approve/comment/callback_url/custom_data)
250
- def postTranslationJob(params = {})
251
- self.send_to_gengo('translate/job', params)
252
- end
78
+ uri = "/v#{@opts[:api_version]}/" + endpoint
79
+ headers = {
80
+ 'Accept' => 'application/json',
81
+ 'User-Agent' => @opts[:user_agent]
82
+ }
253
83
 
254
- # Much like the above, but takes a hash titled "jobs" that is multiple jobs, each with their own unique key.
255
- #
256
- # Options:
257
- # <tt>jobs</tt> - "Jobs" is a hash containing further hashes; each further hash is a job. This is best seen in the example code.
258
- def postTranslationJobs(params = {})
259
- self.send_to_gengo('translate/jobs', params)
260
- end
84
+ if is_delete
85
+ req = Net::HTTP::Delete.new(uri, headers)
86
+ else
87
+ req = Net::HTTP::Get.new(uri, headers)
88
+ end
261
89
 
262
- # Updates an already submitted job.
263
- #
264
- # Options:
265
- # <tt>id</tt> - The ID of a job to update.
266
- # <tt>action</tt> - A hash describing the update to this job. See the examples for further documentation.
267
- def updateTranslationJob(params = {})
268
- params[:is_put] = true
269
- self.send_to_gengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
270
- end
90
+ http = Net::HTTP.start(@api_host, 80)
91
+ if @debug
92
+ http.set_debug_output($stdout)
93
+ end
94
+ http.read_timeout = 5*60
95
+ resp = http.request(req)
271
96
 
272
- # Updates a group of already submitted jobs.
273
- #
274
- # Options:
275
- # <tt>jobs</tt> - An Array of job objects to update (job objects or ids)
276
- # <tt>action</tt> - A String describing the update to this job. "approved", "rejected", etc - see Gengo docs.
277
- def updateTranslationJobs(params = {})
278
- params[:is_put] = true
279
- self.send_to_gengo('translate/jobs', {:jobs => params[:jobs], :action => params[:action]})
97
+ if is_download_file.nil?
98
+ json = JSON.parse(resp.body)
99
+ if json['opstat'] != 'ok'
100
+ raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
280
101
  end
281
102
 
282
- # Given an ID, pulls down information concerning that job from Gengo.
283
- #
284
- # <tt>id</tt> - The ID of a job to check.
285
- # <tt>pre_mt</tt> - Optional, get a machine translation if the human translation is not done.
286
- def getTranslationJob(params = {})
287
- self.get_from_gengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
288
- end
103
+ # Return it if there are no problems, nice...
104
+ return json
105
+ else
106
+ return resp.body
107
+ end
289
108
 
290
- # Pulls down a list of recently submitted jobs, allows some filters.
291
- #
292
- # <tt>status</tt> - Optional. "unpaid", "available", "pending", "reviewable", "approved", "rejected", or "canceled".
293
- # <tt>timestamp_after</tt> - Optional. Epoch timestamp from which to filter submitted jobs.
294
- # <tt>count</tt> - Optional. Defaults to 10.
295
- def getTranslationJobs(params = {})
296
- if params[:ids] and params[:ids].kind_of?(Array)
297
- params[:ids] = params[:ids].map { |i| i.to_s() }.join(',')
298
- self.get_from_gengo('translate/jobs/:ids'.gsub(':ids', params.delete(:ids)))
299
- else
300
- self.get_from_gengo('translate/jobs', params)
301
- end
302
- end
109
+ end
303
110
 
304
- # Pulls a group of jobs that were previously submitted together.
305
- #
306
- # <tt>id</tt> - Required, the ID of a job that you want the batch/group of.
307
- def getTranslationJobBatch(params = {})
308
- self.get_from_gengo('translate/jobs/group/:group_id'.gsub(':group_id', params.delete(:group_id).to_s), params)
309
- end
111
+ # The "POST" method; handles shuttling up encoded job data to Gengo
112
+ # for translation and such. Somewhat similar to the above methods, but depending on the scenario
113
+ # can get some strange exceptions, so we're gonna keep them fairly separate for the time being. Consider
114
+ # for a merger down the road...
115
+ #
116
+ # Options:
117
+ # <tt>endpoint</tt> - String/URL to post data to.
118
+ # <tt>params</tt> - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.
119
+ def send_to_gengo(endpoint, params = {})
310
120
 
311
- # Pulls a group of jobs that were previously submitted together.
312
- #
313
- # <tt>id</tt> - Required, the ID of a job that you want the batch/group of.
314
- def getTranslationOrderJobs(params = {})
315
- self.get_from_gengo('translate/order/:order_id'.gsub(':order_id', params.delete(:order_id).to_s), params)
316
- end
121
+ # Check if this is a put
122
+ is_put = params.delete(:is_put)
317
123
 
318
- # Mirrors the bulk Translation call, but just returns an estimated cost.
319
- def determineTranslationCost(params = {})
320
- is_upload = params.delete(:is_upload)
124
+ query = {
125
+ :api_key => @opts[:public_key],
126
+ :data => params.to_json.gsub('"', '\"'),
127
+ :ts => Time.now.gmtime.to_i.to_s
128
+ }
129
+
130
+ url = URI.parse("http://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")
131
+ http = Net::HTTP.new(url.host, url.port)
132
+ http.read_timeout = 5*60
133
+ if is_put
134
+ request = Net::HTTP::Put.new(url.path)
135
+ else
136
+ request = Net::HTTP::Post.new(url.path)
137
+ end
321
138
 
322
- if is_upload
323
- self.upload_to_gengo('translate/service/quote/file', params)
324
- else
325
- self.send_to_gengo('translate/service/quote', params)
326
- end
327
- end
139
+ request.add_field('Accept', 'application/json')
140
+ request.add_field('User-Agent', @opts[:user_agent])
328
141
 
329
- # Post a comment for a translator or Gengo on a job.
330
- #
331
- # Options:
332
- # <tt>id</tt> - The ID of the job you're commenting on.
333
- # <tt>comment</tt> - The comment to put on the job.
334
- def postTranslationJobComment(params = {})
335
- self.send_to_gengo('translate/job/:id/comment'.gsub(':id', params.delete(:id).to_s), params)
336
- end
142
+ request.content_type = 'application/x-www-form-urlencoded'
143
+ request.body = {
144
+ "api_sig" => signature_of(query[:ts]),
145
+ "api_key" => urlencode(@opts[:public_key]),
146
+ "data" => urlencode(params.to_json.gsub('\\', '\\\\')),
147
+ "ts" => query[:ts].to_i.to_s
148
+ }.map { |k, v| "#{k}=#{v}" }.flatten.join('&')
337
149
 
338
- # Get all comments (the history) from a given job.
339
- #
340
- # Options:
341
- # <tt>id</tt> - The ID of the job to get comments for.
342
- def getTranslationJobComments(params = {})
343
- self.get_from_gengo('translate/job/:id/comments'.gsub(':id', params.delete(:id).to_s), params)
344
- end
150
+ if @debug
151
+ http.set_debug_output($stdout)
152
+ end
345
153
 
346
- # Returns the feedback you've submitted for a given job.
347
- #
348
- # Options:
349
- # <tt>id</tt> - The ID of the translation job you're retrieving comments from.
350
- def getTranslationJobFeedback(params = {})
351
- self.get_from_gengo('translate/job/:id/feedback'.gsub(':id', params.delete(:id).to_s), params)
352
- end
154
+ resp = http.request(request)
353
155
 
354
- # Gets a list of the revision resources for a job. Revisions are created each time a translator updates the text.
355
- #
356
- # Options:
357
- # <tt>id</tt> - The ID of the translation job you're getting revisions from.
358
- def getTranslationJobRevisions(params = {})
359
- self.get_from_gengo('translate/job/:id/revisions'.gsub(':id', params.delete(:id).to_s), params)
360
- end
156
+ case resp
157
+ when Net::HTTPSuccess, Net::HTTPRedirection
158
+ json = JSON.parse(resp.body)
361
159
 
362
- # Get a specific revision to a job.
363
- #
364
- # Options:
365
- # <tt>id</tt> - The ID of the translation job you're getting revisions from.
366
- # <tt>rev_id</tt> - The ID of the revision you're looking up.
367
- def getTranslationJobRevision(params = {})
368
- self.get_from_gengo('translate/job/:id/revisions/:revision_id'.gsub(':id', params.delete(:id).to_s).gsub(':revision_id', params.delete(:rev_id).to_s), params)
160
+ if json['opstat'] != 'ok'
161
+ raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
369
162
  end
370
163
 
371
- # Returns a preview image for a job.
372
- #
373
- # Options:
374
- # <tt>id</tt> - The ID of the job you want a preview image of.
375
- def getTranslationJobPreviewImage(params = {})
376
- params[:is_download] = true
377
- self.get_from_gengo('translate/job/:id/preview'.gsub(':id', params.delete(:id).to_s), params)
378
- end
164
+ # Return it if there are no problems, nice...
165
+ json
166
+ else
167
+ resp.error!
168
+ end
169
+ end
170
+
171
+ # The "UPLOAD" method; handles sending a file to the quote method
172
+ #
173
+ # Options:
174
+ # <tt>endpoint</tt> - String/URL to post data to.
175
+ # <tt>params</tt> - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.
176
+ def upload_to_gengo(endpoint, params = {})
177
+
178
+ # prepare the file_hash and append file_key to each job payload
179
+ files_hash = params[:jobs].each_value.reduce({}) do |hash_thus_far, job_values|
180
+ if job_values[:file_path]
181
+ job_mime_type = MIME::Types.type_for(job_values[:file_path]).first.content_type
182
+ file_hash_key = "file_#{hash_thus_far.length.to_s}".to_sym
183
+ job_values[:file_key] = file_hash_key
184
+ hash_thus_far[file_hash_key] = UploadIO.new(File.open(job_values[:file_path]), job_mime_type, File.basename(job_values[:file_path]))
185
+ end
186
+ hash_thus_far
187
+ end
379
188
 
380
- # Deletes a job.
381
- #
382
- # Options:
383
- # <tt>id</tt> - The ID of the job you want to delete.
384
- def deleteTranslationJob(params = {})
385
- params[:is_delete] = true
386
- self.get_from_gengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
387
- end
189
+ url = URI.parse("http://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")
388
190
 
389
- # Deletes multiple jobs.
390
- #
391
- # Options:
392
- # <tt>ids</tt> - An Array of job IDs you want to delete.
393
- def deleteTranslationJobs(params = {})
394
- if params[:ids] and params[:ids].kind_of?(Array)
395
- params[:job_ids] = params[:ids].map { |i| i.to_s() }.join(',')
396
- params.delete(:ids)
397
- end
398
-
399
- params[:is_delete] = true
400
- self.get_from_gengo('translate/jobs', params)
401
- end
191
+ http = Net::HTTP.new(url.host, url.port)
192
+ http.read_timeout = 5*60
402
193
 
403
- # Gets information about currently supported language pairs.
404
- #
405
- # Options:
406
- # <tt>lc_src</tt> - Optional language code to filter on.
407
- def getServiceLanguagePairs(params = {})
408
- self.get_from_gengo('translate/service/language_pairs', params)
409
- end
194
+ call_timestamp = Time.now.gmtime.to_i.to_s
410
195
 
411
- # Pulls down currently supported languages.
412
- def getServiceLanguages(params = {})
413
- self.get_from_gengo('translate/service/languages', params)
414
- end
196
+ the_hash = files_hash.merge({
197
+ "api_sig" => signature_of(call_timestamp),
198
+ "api_key" => @opts[:public_key],
199
+ "data" =>params.to_json.gsub('\\', '\\\\'),
200
+ "ts" => call_timestamp
201
+ })
415
202
 
416
- # Gets list of glossaries that belongs to the authenticated user
417
- def getGlossaryList(params = {})
418
- self.get_from_gengo('translate/glossary', params)
419
- end
203
+ request = Net::HTTP::Post::Multipart.new(url.path, the_hash, {'Accept' => 'application/json', 'User-Agent' => @opts[:user_agent] })
420
204
 
421
- # Gets one glossary that belongs to the authenticated user
422
- def getGlossary(params = {})
423
- self.get_from_gengo('translate/glossary/:id'.gsub(':id', params.delete(:id).to_s), params)
424
- end
205
+ if @debug
206
+ http.set_debug_output($stdout)
207
+ end
208
+
209
+ resp = http.request(request)
210
+
211
+ case resp
212
+ when Net::HTTPSuccess, Net::HTTPRedirection
213
+ json = JSON.parse(resp.body)
425
214
 
426
- # Downloads one glossary that belongs to the authenticated user
427
- def getGlossaryFile(params = {})
428
- params[:is_download] = true
429
- self.get_from_gengo('translate/glossary/download/:id'.gsub(':id', params.delete(:id).to_s), params)
215
+ if json['opstat'] != 'ok'
216
+ raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
430
217
  end
218
+
219
+ # Return it if there are no problems, nice...
220
+ json
221
+ else
222
+ resp.error!
223
+ end
224
+ end
225
+
226
+ # Returns a Ruby-hash of the stats for the current account. No arguments required!
227
+ #
228
+ # Options:
229
+ # <tt>None</tt> - N/A
230
+ def getAccountStats(params = {})
231
+ self.get_from_gengo('account/stats', params)
232
+ end
233
+
234
+ # Returns a Ruby-hash of the balance for the authenticated account. No args required!
235
+ #
236
+ # Options:
237
+ # <tt>None</tt> - N/A
238
+ def getAccountBalance(params = {})
239
+ self.get_from_gengo('account/balance', params)
240
+ end
241
+
242
+ # Much like the above, but takes a hash titled "jobs" that is multiple jobs, each with their own unique key.
243
+ #
244
+ # Options:
245
+ # <tt>jobs</tt> - "Jobs" is a hash containing further hashes; each further hash is a job. This is best seen in the example code.
246
+ def postTranslationJobs(params = {})
247
+ self.send_to_gengo('translate/jobs', params)
248
+ end
249
+
250
+ # Updates an already submitted job.
251
+ #
252
+ # Options:
253
+ # <tt>id</tt> - The ID of a job to update.
254
+ # <tt>action</tt> - A hash describing the update to this job. See the examples for further documentation.
255
+ def updateTranslationJob(params = {})
256
+ params[:is_put] = true
257
+ self.send_to_gengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
258
+ end
259
+
260
+ # Updates a group of already submitted jobs.
261
+ #
262
+ # Options:
263
+ # <tt>jobs</tt> - An Array of job objects to update (job objects or ids)
264
+ # <tt>action</tt> - A String describing the update to this job. "approved", "rejected", etc - see Gengo docs.
265
+ def updateTranslationJobs(params = {})
266
+ params[:is_put] = true
267
+ self.send_to_gengo('translate/jobs', {:jobs => params[:jobs], :action => params[:action]})
268
+ end
269
+
270
+ # Given an ID, pulls down information concerning that job from Gengo.
271
+ #
272
+ # <tt>id</tt> - The ID of a job to check.
273
+ # <tt>pre_mt</tt> - Optional, get a machine translation if the human translation is not done.
274
+ def getTranslationJob(params = {})
275
+ self.get_from_gengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
276
+ end
277
+
278
+ # Pulls down a list of recently submitted jobs, allows some filters.
279
+ #
280
+ # <tt>status</tt> - Optional. "unpaid", "available", "pending", "reviewable", "approved", "rejected", or "canceled".
281
+ # <tt>timestamp_after</tt> - Optional. Epoch timestamp from which to filter submitted jobs.
282
+ # <tt>count</tt> - Optional. Defaults to 10.
283
+ def getTranslationJobs(params = {})
284
+ if params[:ids] and params[:ids].kind_of?(Array)
285
+ params[:ids] = params[:ids].map { |i| i.to_s() }.join(',')
286
+ self.get_from_gengo('translate/jobs/:ids'.gsub(':ids', params.delete(:ids)))
287
+ else
288
+ self.get_from_gengo('translate/jobs', params)
289
+ end
290
+ end
291
+
292
+ # Pulls a group of jobs that were previously submitted together.
293
+ #
294
+ # <tt>id</tt> - Required, the ID of a job that you want the batch/group of.
295
+ def getTranslationJobBatch(params = {})
296
+ self.get_from_gengo('translate/jobs/group/:group_id'.gsub(':group_id', params.delete(:group_id).to_s), params)
297
+ end
298
+
299
+ # Pulls a group of jobs that were previously submitted together.
300
+ #
301
+ # <tt>id</tt> - Required, the ID of a job that you want the batch/group of.
302
+ def getTranslationOrderJobs(params = {})
303
+ self.get_from_gengo('translate/order/:order_id'.gsub(':order_id', params.delete(:order_id).to_s), params)
304
+ end
305
+
306
+ # Mirrors the bulk Translation call, but just returns an estimated cost.
307
+ def determineTranslationCost(params = {})
308
+ is_upload = params.delete(:is_upload)
309
+ if is_upload
310
+ self.upload_to_gengo('translate/service/quote/file', params)
311
+ else
312
+ self.send_to_gengo('translate/service/quote', params)
431
313
  end
314
+ end
315
+
316
+ # Mirrors the bulk Translation call, but just returns an estimated cost.
317
+ def getTranslationQuote(params = {})
318
+ determineTranslationCost(params)
319
+ end
320
+
321
+ # Post a comment for a translator or Gengo on a job.
322
+ #
323
+ # Options:
324
+ # <tt>id</tt> - The ID of the job you're commenting on.
325
+ # <tt>comment</tt> - The comment to put on the job.
326
+ def postTranslationJobComment(params = {})
327
+ self.send_to_gengo('translate/job/:id/comment'.gsub(':id', params.delete(:id).to_s), params)
328
+ end
329
+
330
+ # Get all comments (the history) from a given job.
331
+ #
332
+ # Options:
333
+ # <tt>id</tt> - The ID of the job to get comments for.
334
+ def getTranslationJobComments(params = {})
335
+ self.get_from_gengo('translate/job/:id/comments'.gsub(':id', params.delete(:id).to_s), params)
336
+ end
337
+
338
+ # Returns the feedback you've submitted for a given job.
339
+ #
340
+ # Options:
341
+ # <tt>id</tt> - The ID of the translation job you're retrieving comments from.
342
+ def getTranslationJobFeedback(params = {})
343
+ self.get_from_gengo('translate/job/:id/feedback'.gsub(':id', params.delete(:id).to_s), params)
344
+ end
345
+
346
+ # Gets a list of the revision resources for a job. Revisions are created each time a translator updates the text.
347
+ #
348
+ # Options:
349
+ # <tt>id</tt> - The ID of the translation job you're getting revisions from.
350
+ def getTranslationJobRevisions(params = {})
351
+ self.get_from_gengo('translate/job/:id/revisions'.gsub(':id', params.delete(:id).to_s), params)
352
+ end
353
+
354
+ # Get a specific revision to a job.
355
+ #
356
+ # Options:
357
+ # <tt>id</tt> - The ID of the translation job you're getting revisions from.
358
+ # <tt>rev_id</tt> - The ID of the revision you're looking up.
359
+ def getTranslationJobRevision(params = {})
360
+ self.get_from_gengo('translate/job/:id/revisions/:revision_id'.gsub(':id', params.delete(:id).to_s).gsub(':revision_id', params.delete(:rev_id).to_s), params)
361
+ end
362
+
363
+ # Returns a preview image for a job.
364
+ #
365
+ # Options:
366
+ # <tt>id</tt> - The ID of the job you want a preview image of.
367
+ def getTranslationJobPreviewImage(params = {})
368
+ params[:is_download] = true
369
+ self.get_from_gengo('translate/job/:id/preview'.gsub(':id', params.delete(:id).to_s), params)
370
+ end
371
+
372
+ # Deletes an order, cancelling all available jobs.
373
+ #
374
+ # This method is EXPERIMENTAL
375
+ #
376
+ # Options:
377
+ # <tt>id</tt> - The ID of the order you want to delete.
378
+ def deleteTranslationOrder(params = {})
379
+ params[:is_delete] = true
380
+ self.get_from_gengo('translate/order/:id'.gsub(':id', params.delete(:id).to_s), params)
381
+ end
382
+
383
+ # Deletes a job.
384
+ #
385
+ # Options:
386
+ # <tt>id</tt> - The ID of the job you want to delete.
387
+ def deleteTranslationJob(params = {})
388
+ params[:is_delete] = true
389
+ self.get_from_gengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
390
+ end
391
+
392
+ # Deletes multiple jobs.
393
+ #
394
+ # Options:
395
+ # <tt>ids</tt> - An Array of job IDs you want to delete.
396
+ def deleteTranslationJobs(params = {})
397
+ if params[:ids] and params[:ids].kind_of?(Array)
398
+ params[:job_ids] = params[:ids].map { |i| i.to_s() }.join(',')
399
+ params.delete(:ids)
400
+ end
401
+
402
+ params[:is_delete] = true
403
+ self.get_from_gengo('translate/jobs', params)
404
+ end
405
+
406
+ # Gets information about currently supported language pairs.
407
+ #
408
+ # Options:
409
+ # <tt>lc_src</tt> - Optional language code to filter on.
410
+ def getServiceLanguagePairs(params = {})
411
+ self.get_from_gengo('translate/service/language_pairs', params)
412
+ end
413
+
414
+ # Pulls down currently supported languages.
415
+ def getServiceLanguages(params = {})
416
+ self.get_from_gengo('translate/service/languages', params)
417
+ end
418
+
419
+ # Gets list of glossaries that belongs to the authenticated user
420
+ def getGlossaryList(params = {})
421
+ self.get_from_gengo('translate/glossary', params)
422
+ end
423
+
424
+ # Gets one glossary that belongs to the authenticated user
425
+ def getGlossary(params = {})
426
+ self.get_from_gengo('translate/glossary/:id'.gsub(':id', params.delete(:id).to_s), params)
427
+ end
428
+
429
+ # Downloads one glossary that belongs to the authenticated user
430
+ def getGlossaryFile(params = {})
431
+ params[:is_download] = true
432
+ self.get_from_gengo('translate/glossary/download/:id'.gsub(':id', params.delete(:id).to_s), params)
433
+ end
434
+ end
432
435
 
433
436
  end
@@ -1,15 +1,15 @@
1
1
  module Gengo
2
- # Base Exception class and such.
3
- class Gengo::Exception < ::StandardError
4
- attr_accessor :opstat, :code, :msg
2
+ # Base Exception class and such.
3
+ class Gengo::Exception < ::StandardError
4
+ attr_accessor :opstat, :code, :msg
5
5
 
6
- # Pretty self explanatory stuff here...
7
- def initialize(opstat, code, msg)
8
- @opstat = opstat
9
- @code = code
10
- @msg = msg
6
+ # Pretty self explanatory stuff here...
7
+ def initialize(opstat, code, msg)
8
+ @opstat = opstat
9
+ @code = code
10
+ @msg = msg
11
11
 
12
- puts msg
13
- end
14
- end
12
+ puts msg
13
+ end
14
+ end
15
15
  end
data/lib/gengo.rb CHANGED
@@ -3,13 +3,13 @@ require 'gengo-ruby/api_handler'
3
3
  require 'gengo-ruby/gengo_exception'
4
4
 
5
5
  module Gengo
6
- # Store global config objects here - e.g, urls, etc.
7
- module Config
8
- # API url endpoints; replace the version at function call time to
9
- # allow for function-by-function differences in versioning.
10
- API_HOST = 'api.gengo.com'
11
- SANDBOX_API_HOST = 'api.sandbox.gengo.com'
6
+ # Store global config objects here - e.g, urls, etc.
7
+ module Config
8
+ # API url endpoints; replace the version at function call time to
9
+ # allow for function-by-function differences in versioning.
10
+ API_HOST = 'api.gengo.com'
11
+ SANDBOX_API_HOST = 'api.sandbox.gengo.com'
12
12
 
13
- VERSION = '0.0.0'
14
- end
13
+ VERSION = '0.0.0'
14
+ end
15
15
  end
metadata CHANGED
@@ -1,22 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gengo
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matthew Romaine
14
14
  - Shawn Smith
15
+ - Issam Zeibak
15
16
  autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2012-11-19 00:00:00 Z
20
+ date: 2013-04-17 00:00:00 Z
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
22
23
  name: json
@@ -135,8 +136,8 @@ files:
135
136
  - Rakefile
136
137
  - README.md
137
138
  homepage: http://developers.gengo.com
138
- licenses: []
139
-
139
+ licenses:
140
+ - New BSD
140
141
  post_install_message:
141
142
  rdoc_options: []
142
143