gengo 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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