Class: MyGengo::API

Inherits:
Object
  • Object
show all
Defined in:
lib/mygengo-ruby/api_handler.rb

Overview

The only real class that ever needs to be instantiated.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ API

Creates a new API handler to shuttle calls/jobs/etc over to the Gengo translation API.

Options: opts - A hash containing the api key, the api secret key, the API version (defaults to 1), whether to use the sandbox API, and an optional custom user agent to send.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/mygengo-ruby/api_handler.rb', line 26

def initialize(opts)
	# Consider this an example of the object you need to pass.
	@opts = {
		:public_key => '',
		:private_key => '',
		:api_version => '1.1',
		:sandbox => false,
		:user_agent => "Gengo Ruby Library; Version #{MyGengo::Config::VERSION}; http://gengo.com/;",
		:debug => false,
	}.merge(opts)

	# Let's go ahead and separate these out, for clarity...
	@debug = @opts[:debug]
	@api_host = (@opts[:sandbox] == true ? MyGengo::Config::SANDBOX_API_HOST : MyGengo::Config::API_HOST)

	# More of a public "check this" kind of object.
	@client_info = {"VERSION" => MyGengo::Config::VERSION}
end

Instance Attribute Details

#api_hostObject

Returns the value of attribute api_host.



17
18
19
# File 'lib/mygengo-ruby/api_handler.rb', line 17

def api_host
  @api_host
end

#client_infoObject

Returns the value of attribute client_info.



19
20
21
# File 'lib/mygengo-ruby/api_handler.rb', line 19

def client_info
  @client_info
end

#debugObject

Returns the value of attribute debug.



18
19
20
# File 'lib/mygengo-ruby/api_handler.rb', line 18

def debug
  @debug
end

Instance Method Details

#deleteTranslationJob(params = {}) ⇒ Object

Deletes a job.

Options: id - The ID of the job you want to delete.



388
389
390
391
# File 'lib/mygengo-ruby/api_handler.rb', line 388

def deleteTranslationJob(params = {})
        params[:is_delete] = true
  self.get_from_mygengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
end

#deleteTranslationJobs(params = {}) ⇒ Object

Deletes multiple jobs.

Options: ids - An Array of job IDs you want to delete.



397
398
399
400
401
402
403
404
405
# File 'lib/mygengo-ruby/api_handler.rb', line 397

def deleteTranslationJobs(params = {})
  if params[:ids] and params[:ids].kind_of?(Array)
    params[:job_ids] = params[:ids].map { |i| i.to_s() }.join(',')
    params.delete(:ids)
  end

        params[:is_delete] = true
  self.get_from_mygengo('translate/jobs', params)
end

#determineTranslationCost(params = {}) ⇒ Object

Mirrors the bulk Translation call, but just returns an estimated cost.



323
324
325
326
327
328
329
330
331
# File 'lib/mygengo-ruby/api_handler.rb', line 323

def determineTranslationCost(params = {})
  is_upload = params.delete(:is_upload)

  if is_upload
    self.upload_to_mygengo('translate/service/quote/file', params)
  else
    self.send_to_mygengo('translate/service/quote', params)
  end
end

#get_from_mygengo(endpoint, params = {}) ⇒ Object

The “GET” method; handles requesting basic data sets from Gengo and converting the response to a Ruby hash/object.

Options: endpoint - String/URL to request data from. params - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/mygengo-ruby/api_handler.rb', line 65

def get_from_mygengo(endpoint, params = {})
	# Do this small check here...
          is_delete = params.delete(:is_delete)
          is_download_file = params.delete(:is_download)

          # The first part of the object we're going to encode and use in our request to Gengo. The signing process
	# is a little annoying at the moment, so bear with us...
	query = params.reduce({}) {|hash_thus_far, (param_key, param_value)|
            hash_thus_far.merge(
                param_key.to_sym => param_value.to_s
            )
          }

          query[:api_key] = @opts[:public_key]
          query[:ts] = Time.now.gmtime.to_i.to_s

	endpoint << "?api_sig=" + signature_of(query[:ts])
	endpoint << '&' + query.map { |k, v| "#{k}=#{urlencode(v)}" }.join('&')

          uri = "/v#{@opts[:api_version]}/" + endpoint
          headers = {
              'Accept' => 'application/json',
              'User-Agent' => @opts[:user_agent]
          }

          if is_delete
              req = Net::HTTP::Delete.new(uri, headers)
          else
              req = Net::HTTP::Get.new(uri, headers)
          end

	http = Net::HTTP.start(@api_host, 80)
          if @debug
            http.set_debug_output($stdout)
          end
          http.read_timeout = 5*60
          resp = http.request(req)

	if is_download_file.nil?
            json = JSON.parse(resp.body)
            if json['opstat'] != 'ok'
                raise MyGengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
            end

            # Return it if there are no problems, nice...
            return json
          else
            return resp.body
          end

end

#getAccountBalance(params = {}) ⇒ Object

Returns a Ruby-hash of the balance for the authenticated account. No args required!

Options: None - N/A



244
245
246
# File 'lib/mygengo-ruby/api_handler.rb', line 244

def getAccountBalance(params = {})
  self.get_from_mygengo('account/balance', params)
end

#getAccountStats(params = {}) ⇒ Object

Returns a Ruby-hash of the stats for the current account. No arguments required!

Options: None - N/A



236
237
238
# File 'lib/mygengo-ruby/api_handler.rb', line 236

def getAccountStats(params = {})
  self.get_from_mygengo('account/stats', params)
end

#getGlossary(params = {}) ⇒ Object

Gets one glossary that belongs to the authenticated user



426
427
428
# File 'lib/mygengo-ruby/api_handler.rb', line 426

def getGlossary(params = {})
    self.get_from_mygengo('translate/glossary/:id'.gsub(':id', params.delete(:id).to_s), params)
end

#getGlossaryFile(params = {}) ⇒ Object

Downloads one glossary that belongs to the authenticated user



431
432
433
434
# File 'lib/mygengo-ruby/api_handler.rb', line 431

def getGlossaryFile(params = {})
    params[:is_download] = true
    self.get_from_mygengo('translate/glossary/download/:id'.gsub(':id', params.delete(:id).to_s), params)
end

#getGlossaryList(params = {}) ⇒ Object

Gets list of glossaries that belongs to the authenticated user



421
422
423
# File 'lib/mygengo-ruby/api_handler.rb', line 421

def getGlossaryList(params = {})
    self.get_from_mygengo('translate/glossary', params)
end

#getServiceLanguagePairs(params = {}) ⇒ Object

Gets information about currently supported language pairs.

Options: lc_src - Optional language code to filter on.



411
412
413
# File 'lib/mygengo-ruby/api_handler.rb', line 411

def getServiceLanguagePairs(params = {})
        self.get_from_mygengo('translate/service/language_pairs', params)
end

#getServiceLanguages(params = {}) ⇒ Object

Pulls down currently supported languages.



416
417
418
# File 'lib/mygengo-ruby/api_handler.rb', line 416

def getServiceLanguages(params = {})
  self.get_from_mygengo('translate/service/languages', params)
end

#getTranslationJob(params = {}) ⇒ Object

Given an ID, pulls down information concerning that job from Gengo.

id - The ID of a job to check. pre_mt - Optional, get a machine translation if the human translation is not done.



290
291
292
# File 'lib/mygengo-ruby/api_handler.rb', line 290

def getTranslationJob(params = {})
  self.get_from_mygengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
end

#getTranslationJobBatch(params = {}) ⇒ Object

Pulls a group of jobs that were previously submitted together.

id - Required, the ID of a job that you want the batch/group of.



311
312
313
# File 'lib/mygengo-ruby/api_handler.rb', line 311

def getTranslationJobBatch(params = {})
  self.get_from_mygengo('translate/jobs/group/:group_id'.gsub(':group_id', params.delete(:group_id).to_s), params)
end

#getTranslationJobComments(params = {}) ⇒ Object

Get all comments (the history) from a given job.

Options: id - The ID of the job to get comments for.



346
347
348
# File 'lib/mygengo-ruby/api_handler.rb', line 346

def getTranslationJobComments(params = {})
  self.get_from_mygengo('translate/job/:id/comments'.gsub(':id', params.delete(:id).to_s), params)
end

#getTranslationJobFeedback(params = {}) ⇒ Object

Returns the feedback you’ve submitted for a given job.

Options: id - The ID of the translation job you’re retrieving comments from.



354
355
356
# File 'lib/mygengo-ruby/api_handler.rb', line 354

def getTranslationJobFeedback(params = {})
  self.get_from_mygengo('translate/job/:id/feedback'.gsub(':id', params.delete(:id).to_s), params)
end

#getTranslationJobPreviewImage(params = {}) ⇒ Object

Returns a preview image for a job.

Options: id - The ID of the job you want a preview image of.



379
380
381
382
# File 'lib/mygengo-ruby/api_handler.rb', line 379

def getTranslationJobPreviewImage(params = {})
  params[:is_download] = true
  self.get_from_mygengo('translate/job/:id/preview'.gsub(':id', params.delete(:id).to_s), params)
end

#getTranslationJobRevision(params = {}) ⇒ Object

Get a specific revision to a job.

Options: id - The ID of the translation job you’re getting revisions from. rev_id - The ID of the revision you’re looking up.



371
372
373
# File 'lib/mygengo-ruby/api_handler.rb', line 371

def getTranslationJobRevision(params = {})
  self.get_from_mygengo('translate/job/:id/revisions/:revision_id'.gsub(':id', params.delete(:id).to_s).gsub(':revision_id', params.delete(:rev_id).to_s), params)
end

#getTranslationJobRevisions(params = {}) ⇒ Object

Gets a list of the revision resources for a job. Revisions are created each time a translator updates the text.

Options: id - The ID of the translation job you’re getting revisions from.



362
363
364
# File 'lib/mygengo-ruby/api_handler.rb', line 362

def getTranslationJobRevisions(params = {})
  self.get_from_mygengo('translate/job/:id/revisions'.gsub(':id', params.delete(:id).to_s), params)
end

#getTranslationJobs(params = {}) ⇒ Object

Pulls down a list of recently submitted jobs, allows some filters.

status - Optional. “unpaid”, “available”, “pending”, “reviewable”, “approved”, “rejected”, or “canceled”. timestamp_after - Optional. Epoch timestamp from which to filter submitted jobs. count - Optional. Defaults to 10.



299
300
301
302
303
304
305
306
# File 'lib/mygengo-ruby/api_handler.rb', line 299

def getTranslationJobs(params = {})
  if params[:ids] and params[:ids].kind_of?(Array)
    params[:ids] = params[:ids].map { |i| i.to_s() }.join(',')
    self.get_from_mygengo('translate/jobs/:ids'.gsub(':ids', params.delete(:ids)))
  else
    self.get_from_mygengo('translate/jobs', params)
  end
end

#getTranslationOrderJobs(params = {}) ⇒ Object

Pulls a group of jobs that were previously submitted together.

id - Required, the ID of a job that you want the batch/group of.



318
319
320
# File 'lib/mygengo-ruby/api_handler.rb', line 318

def getTranslationOrderJobs(params = {})
  self.get_from_mygengo('translate/order/:order_id'.gsub(':order_id', params.delete(:order_id).to_s), params)
end

#postTranslationJob(params = {}) ⇒ Object

Posts a translation job over to Gengo, returns a response indicating whether the submission was successful or not. Param list is quite expansive here, pay attention…

Options: job - A job is a hash of data describing what you want translated. See the examples included for more information on what this should be. (type/slug/body_src/lc_src/lc_tgt/tier/auto_approve/comment/callback_url/custom_data)



254
255
256
# File 'lib/mygengo-ruby/api_handler.rb', line 254

def postTranslationJob(params = {})
  self.send_to_mygengo('translate/job', params)
end

#postTranslationJobComment(params = {}) ⇒ Object

Post a comment for a translator or Gengo on a job.

Options: id - The ID of the job you’re commenting on. comment - The comment to put on the job.



338
339
340
# File 'lib/mygengo-ruby/api_handler.rb', line 338

def postTranslationJobComment(params = {})
  self.send_to_mygengo('translate/job/:id/comment'.gsub(':id', params.delete(:id).to_s), params)
end

#postTranslationJobs(params = {}) ⇒ Object

Much like the above, but takes a hash titled “jobs” that is multiple jobs, each with their own unique key.

Options: jobs - “Jobs” is a hash containing further hashes; each further hash is a job. This is best seen in the example code.



262
263
264
# File 'lib/mygengo-ruby/api_handler.rb', line 262

def postTranslationJobs(params = {})
  self.send_to_mygengo('translate/jobs', params)
end

#send_to_mygengo(endpoint, params = {}) ⇒ Object

The “POST” method; handles shuttling up encoded job data to Gengo for translation and such. Somewhat similar to the above methods, but depending on the scenario can get some strange exceptions, so we’re gonna keep them fairly separate for the time being. Consider for a merger down the road…

Options: endpoint - String/URL to post data to. params - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/mygengo-ruby/api_handler.rb', line 125

def send_to_mygengo(endpoint, params = {})

  # Check if this is a put
    is_put = params.delete(:is_put)

	query = {
		:api_key => @opts[:public_key],
		:data => params.to_json.gsub('"', '\"'),
		:ts => Time.now.gmtime.to_i.to_s
	}

	url = URI.parse("http://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")
	http = Net::HTTP.new(url.host, url.port)
          http.read_timeout = 5*60
	if is_put
	  request = Net::HTTP::Put.new(url.path)
  else
	  request = Net::HTTP::Post.new(url.path)
  end

	request.add_field('Accept', 'application/json')
	request.add_field('User-Agent', @opts[:user_agent])

	request.content_type = 'application/x-www-form-urlencoded'
	request.body = {
		"api_sig" => signature_of(query[:ts]),
		"api_key" => urlencode(@opts[:public_key]),
		"data" => urlencode(params.to_json.gsub('\\', '\\\\')),
		"ts" => Time.now.gmtime.to_i.to_s
	}.map { |k, v| "#{k}=#{v}" }.flatten.join('&')

	if @debug
		http.set_debug_output($stdout)
	end

	resp = http.request(request)

	case resp
		when Net::HTTPSuccess, Net::HTTPRedirection
			json = JSON.parse(resp.body)

			if json['opstat'] != 'ok'
				raise MyGengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
			end

			# Return it if there are no problems, nice...
			json
		else
			resp.error!
	end
end

#signature_of(ts) ⇒ Object

Creates an HMAC::SHA1 signature, signing the timestamp with the private key.



55
56
57
# File 'lib/mygengo-ruby/api_handler.rb', line 55

def signature_of(ts)
	OpenSSL::HMAC.hexdigest 'sha1', @opts[:private_key], ts
end

#updateTranslationJob(params = {}) ⇒ Object

Updates an already submitted job.

Options: id - The ID of a job to update. action - A hash describing the update to this job. See the examples for further documentation.



271
272
273
274
# File 'lib/mygengo-ruby/api_handler.rb', line 271

def updateTranslationJob(params = {})
  params[:is_put] = true
  self.send_to_mygengo('translate/job/:id'.gsub(':id', params.delete(:id).to_s), params)
end

#updateTranslationJobs(params = {}) ⇒ Object

Updates a group of already submitted jobs.

Options: jobs - An Array of job objects to update (job objects or ids) action - A String describing the update to this job. “approved”, “rejected”, etc - see Gengo docs.



281
282
283
284
# File 'lib/mygengo-ruby/api_handler.rb', line 281

def updateTranslationJobs(params = {})
  params[:is_put] = true
  self.send_to_mygengo('translate/jobs', {:jobs => params[:jobs], :action => params[:action]})
end

#upload_to_mygengo(endpoint, params = {}) ⇒ Object

The “UPLOAD” method; handles sending a file to the quote method

Options: endpoint - String/URL to post data to. params - Data necessary for request (keys, etc). Generally taken care of by the requesting instance.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/mygengo-ruby/api_handler.rb', line 182

def upload_to_mygengo(endpoint, params = {})

  # prepare the file_hash and append file_key to each job payload
        files_hash = params[:jobs].each_value.reduce({}) do |hash_thus_far, job_values|
          if job_values[:file_path].present?
              job_mime_type = MIME::Types.type_for(job_values[:file_path]).first.content_type
              file_hash_key = "file_#{hash_thus_far.length.to_s}".to_sym
              job_values[:file_key] = file_hash_key
              hash_thus_far[file_hash_key] = UploadIO.new(File.open(job_values[:file_path]), job_mime_type, File.basename(job_values[:file_path]))
          end
          hash_thus_far
        end

        url = URI.parse("http://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")

        http = Net::HTTP.new(url.host, url.port)
        http.read_timeout = 5*60

        call_timestamp = Time.now.gmtime.to_i.to_s

	the_hash = files_hash.merge({
		"api_sig" => signature_of(call_timestamp),
		"api_key" => @opts[:public_key],
		"data" =>params.to_json.gsub('\\', '\\\\'),
		"ts" => call_timestamp
	})

	request = Net::HTTP::Post::Multipart.new(url.path, the_hash, {'Accept' => 'application/json', 'User-Agent' => @opts[:user_agent] })

	if @debug
		http.set_debug_output($stdout)
	end

	resp = http.request(request)

	case resp
		when Net::HTTPSuccess, Net::HTTPRedirection
			json = JSON.parse(resp.body)

			if json['opstat'] != 'ok'
				raise MyGengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
			end

			# Return it if there are no problems, nice...
			json
		else
			resp.error!
	end
end

#urlencode(string) ⇒ Object

This is… hilariously awkward, but Ruby escapes things very differently from PHP/etc. This causes issues with de-escaping things on the backend over at Gengo; in the future this will become obsolete, but for now we’ll just leave this here…



48
49
50
51
52
# File 'lib/mygengo-ruby/api_handler.rb', line 48

def urlencode(string)
	string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
		'%' + $1.unpack('H2' * $1.size).join('%').upcase
	end.tr(' ', '+')
end