class Gengo::API

The only real class that ever needs to be instantiated.

Attributes

api_host[RW]
client_info[RW]
debug[RW]

Public Class Methods

new(opts) click to toggle source

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.

# File lib/gengo-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 => '',
    :access_token => '',
    :api_version => '2',
    :sandbox => false,
    :user_agent => "Gengo Ruby Library; Version #{Gengo::Config::VERSION}; Ruby Version #{RUBY_DESCRIPTION}; http://gengo.com/;",
    :debug => false,
  }.merge(opts)

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

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

Public Instance Methods

access_token_bearer() click to toggle source
# File lib/gengo-ruby/api_handler.rb, line 60
def access_token_bearer
  "Bearer #{@opts[:access_token]}"
end
auth_by_access_token?() click to toggle source
# File lib/gengo-ruby/api_handler.rb, line 56
def auth_by_access_token?
  @opts[:access_token] != ''
end
deleteTranslationJob(params = {}) click to toggle source

Deletes a job.

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

# File lib/gengo-ruby/api_handler.rb, line 482
def deleteTranslationJob(params = {})
  params[:is_delete] = true
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/job/#{id}", params)
end
deleteTranslationJobs(params = {}) click to toggle source

Deletes multiple jobs.

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

# File lib/gengo-ruby/api_handler.rb, line 492
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_gengo('translate/jobs', params)
end
deleteTranslationOrder(params = {}) click to toggle source

Deletes an order, cancelling all available jobs.

This method is EXPERIMENTAL

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

# File lib/gengo-ruby/api_handler.rb, line 454
def deleteTranslationOrder(params = {})
  params[:is_delete] = true
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/order/#{id}", params)
end
determineTranslationCost(params = {}) click to toggle source

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

# File lib/gengo-ruby/api_handler.rb, line 386
def determineTranslationCost(params = {})
  is_upload = params.delete(:is_upload)
  if is_upload
    self.upload_to_gengo('translate/service/quote', params)
  else
    self.send_to_gengo('translate/service/quote', params)
  end
end
getAccountBalance(params = {}) click to toggle source

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

Options: None - N/A

# File lib/gengo-ruby/api_handler.rb, line 276
def getAccountBalance(params = {})
  self.get_from_gengo('account/balance', params)
end
getAccountMe(params = {}) click to toggle source

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

Options: None - N/A

# File lib/gengo-ruby/api_handler.rb, line 260
def getAccountMe(params = {})
  self.get_from_gengo('account/me', params)
end
getAccountPreferredTranslators(params = {}) click to toggle source

Returns an array of preferred translators for the current account by language pair. No args required!

Options: None - N/A

# File lib/gengo-ruby/api_handler.rb, line 284
def getAccountPreferredTranslators(params = {})
  self.get_from_gengo('account/preferred_translators', params)
end
getAccountStats(params = {}) click to toggle source

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

Options: None - N/A

# File lib/gengo-ruby/api_handler.rb, line 268
def getAccountStats(params = {})
  self.get_from_gengo('account/stats', params)
end
getGlossary(params = {}) click to toggle source

Gets one glossary that belongs to the authenticated user

# File lib/gengo-ruby/api_handler.rb, line 521
def getGlossary(params = {})
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/glossary/#{id}", params)
end
getGlossaryFile(params = {}) click to toggle source

Downloads one glossary that belongs to the authenticated user

# File lib/gengo-ruby/api_handler.rb, line 527
def getGlossaryFile(params = {})
  params[:is_download] = true
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/glossary/download/#{id}", params)
end
getGlossaryList(params = {}) click to toggle source

Gets list of glossaries that belongs to the authenticated user

# File lib/gengo-ruby/api_handler.rb, line 516
def getGlossaryList(params = {})
  self.get_from_gengo('translate/glossary', params)
end
getServiceLanguagePairs(params = {}) click to toggle source

Gets information about currently supported language pairs.

Options: lc_src - Optional language code to filter on.

# File lib/gengo-ruby/api_handler.rb, line 506
def getServiceLanguagePairs(params = {})
  self.get_from_gengo('translate/service/language_pairs', params)
end
getServiceLanguages(params = {}) click to toggle source

Pulls down currently supported languages.

# File lib/gengo-ruby/api_handler.rb, line 511
def getServiceLanguages(params = {})
  self.get_from_gengo('translate/service/languages', params)
end
getTranslationJob(params = {}) click to toggle source

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

id - The ID of a job to check.

# File lib/gengo-ruby/api_handler.rb, line 320
def getTranslationJob(params = {})
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/job/#{id}", params)
end
getTranslationJobComments(params = {}) click to toggle source

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

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

# File lib/gengo-ruby/api_handler.rb, line 414
def getTranslationJobComments(params = {})
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/job/#{id}/comments", params)
end
getTranslationJobFeedback(params = {}) click to toggle source

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

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

# File lib/gengo-ruby/api_handler.rb, line 423
def getTranslationJobFeedback(params = {})
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/job/#{id}/feedback", params)
end
getTranslationJobRevision(params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 442
def getTranslationJobRevision(params = {})
  id = params.delete(:id).to_s
  revision_id = params.delete(:rev_id).to_s
  self.get_from_gengo("translate/job/#{id}/revision/#{revision_id}", params)
end
getTranslationJobRevisions(params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 432
def getTranslationJobRevisions(params = {})
  id = params.delete(:id).to_s
  self.get_from_gengo("translate/job/#{id}/revisions", params)
end
getTranslationJobs(params = {}) click to toggle source

Fetches a list of recent jobs you made.

@deprecated Use {#jobs} or {#query_jobs} instead.

Keyword Parameters

ids

Optional. An array of job IDs to be fetched. Other parameters are ignored if you specify this parameter.

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.

# File lib/gengo-ruby/api_handler.rb, line 339
def getTranslationJobs(params = {})
  if params[:ids].respond_to?(:each)
    jobs(params.delete(:ids))
  else
    query_jobs(params)
  end
end
getTranslationOrderJobs(params = {}) click to toggle source

Fetches a set of jobs in the order you made.

@deprecated Use {#jobs_in_order} instead.

Required keyword parameters

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

# File lib/gengo-ruby/api_handler.rb, line 374
def getTranslationOrderJobs(params = {})
  order_id = params[:order_id]
  raise ArgumentError, 'order_id is a required parameter' unless order_id
  jobs_in_order(order_id)
end
getTranslationQuote(params = {}) click to toggle source

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

# File lib/gengo-ruby/api_handler.rb, line 396
def getTranslationQuote(params = {})
  determineTranslationCost(params)
end
get_from_gengo(endpoint, params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 70
def get_from_gengo(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({}) do |hash_thus_far, (param_key, param_value)|
    hash_thus_far.merge(param_key.to_sym => param_value.to_s)
  end

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

  headers = {
    'Accept' => 'application/json',
    'User-Agent' => @opts[:user_agent]
  }

  if auth_by_access_token?
    headers.merge!('Authorization' => access_token_bearer)
  end

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

  uri = "/v#{@opts[:api_version]}/" + endpoint

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

  url = URI.parse("https://#{@api_host}")
  http = Net::HTTP.start(url.host, url.port, use_ssl: true)
  if @debug
    http.set_debug_output($stdout)
  end
  http.read_timeout = 5*60
  resp = http.request(req)

  return resp.body if is_download_file

  begin
    json = JSON.parse(resp.body)
  rescue => e
    # TODO(yugui) Log the original error
    raise Gengo::Exception.new('error', resp.code.to_i, resp.body) unless resp.kind_of?(Net::HTTPSuccess)

    # It should be very unlikely, but resp.body can be invalid as a JSON in theory even though the status is successful.
    # In this case, raise an exception to report that unexpected status.
    raise Gengo::Exception.new('error', 500, 'unexpected format of server response. Report it to Gengo if this exception repeatedly happens')
  end

  raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg']) unless json['opstat'] == 'ok'

  # Return it if there are no problems, nice...
  return json
end
get_translation_order_comments(order_id) click to toggle source

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

Requirements: order_id - The ID of the order to get comments for.

# File lib/gengo-ruby/api_handler.rb, line 464
def get_translation_order_comments(order_id)
  get_from_gengo("translate/order/#{order_id}/comments")
end
jobs(ids) click to toggle source

Fetchs a set of recent jobs whose IDs are the given ones. @param ids [[Integer|String]] An array of job IDs to be fetched

# File lib/gengo-ruby/api_handler.rb, line 349
def jobs(ids)
  get_from_gengo('translate/jobs/%s' % ids.join(','))
end
jobs_in_order(id) click to toggle source

Fetches a set of jobs in the order you made.

# File lib/gengo-ruby/api_handler.rb, line 381
def jobs_in_order(id)
  self.get_from_gengo("translate/order/#{id}")
end
postTranslationJobComment(params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 405
def postTranslationJobComment(params = {})
  id = params.delete(:id).to_s
  self.send_to_gengo("translate/job/#{id}/comment", params)
end
postTranslationJobs(params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 292
def postTranslationJobs(params = {})
  self.send_to_gengo('translate/jobs', params)
end
post_translation_order_comment(params = {}) click to toggle source

Post a comment for a translator or Gengo on an order.

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

# File lib/gengo-ruby/api_handler.rb, line 473
def post_translation_order_comment(params = {})
  id = params.delete(:id).to_s
  send_to_gengo("translate/order/#{id}/comment", params)
end
query_jobs(params = {}) click to toggle source

Fetchs a set of recent jobs you made. You can apply filters with the following keyword parameters.

Keyword Parameters

status

Optional. Fetches only jobs in this status. Must be “unpaid”, “available”, “pending”, “reviewable”, “approved”, “rejected”, or “canceled”.

timestamp_after

Optional. Epoch timestamp from which to filter submitted jobs.

count

Optional. The maximum number of jobs to be returned. Defaults to 10.

# File lib/gengo-ruby/api_handler.rb, line 364
def query_jobs(params = {})
  get_from_gengo('translate/jobs', params)
end
send_to_gengo(endpoint, params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 139
def send_to_gengo(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("https://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")
  http = Net::HTTP.new(url.host, url.port)
  http.read_timeout = 5*60
  http.use_ssl = true
  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])

  if auth_by_access_token?
    request.add_field('Authorization', access_token_bearer)
  end

  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" => query[:ts].to_i.to_s
  }.map { |k, v| "#{k}=#{v}" }.flatten.join('&')

  if @debug
    http.set_debug_output($stdout)
  end

  resp = http.request(request)
  resp.error! unless resp.kind_of?(Net::HTTPSuccess)

  json = JSON.parse(resp.body)
  return json if json['opstat'] == 'ok'

  case
  when json['err']['code']
    raise Gengo::Exception.new(json['opstat'], json['err']['code'].to_i, json['err']['msg'])
  when json['err'].respond_to?(:each)
    # Ad-hock care of bulk operations. To be done in a higher-layer in future.  [#93504182]
    err = json['err'].map {|key, value| value.respond_to?(:first) ? value.first : value }
    raise Gengo::Exception.new(json['opstat'], err.first['code'], err.map{|e| e['msg']}.join(';'))
  end
end
signature_of(ts) click to toggle source

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

# File lib/gengo-ruby/api_handler.rb, line 52
def signature_of(ts)
  OpenSSL::HMAC.hexdigest 'sha1', @opts[:private_key], ts
end
updateTranslationJob(params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 301
def updateTranslationJob(params = {})
  params[:is_put] = true
  id = params.delete(:id).to_s
  self.send_to_gengo("translate/job/#{id}", params)
end
updateTranslationJobs(params = {}) click to toggle source

Updates a group of already submitted jobs.

Options: job_ids - 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.

# File lib/gengo-ruby/api_handler.rb, line 312
def updateTranslationJobs(params = {})
  params[:is_put] = true
  self.send_to_gengo('translate/jobs', params)
end
upload_to_gengo(endpoint, params = {}) click to toggle source

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.

# File lib/gengo-ruby/api_handler.rb, line 200
def upload_to_gengo(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]
    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("https://#{@api_host}/v#{@opts[:api_version]}/#{endpoint}")

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

  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
  })

  headers = {'Accept' => 'application/json', 'User-Agent' => @opts[:user_agent] }
  if auth_by_access_token?
    headers.merge!('Authorization' => access_token_bearer)
  end

  request = Net::HTTP::Post::Multipart.new(url.path, the_hash, headers)

  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 Gengo::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) click to toggle source

Use CGI escape to escape a string

# File lib/gengo-ruby/api_handler.rb, line 47
def urlencode(string)
  CGI::escape(string)
end