Skip to content

Commit

Permalink
Implement project create with files
Browse files Browse the repository at this point in the history
  • Loading branch information
İsmail Akbudak committed Mar 12, 2018
1 parent 4651bac commit c5a3f88
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 39 deletions.
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ PATH
remote: .
specs:
smartcat_sdk (0.1.0)
mime-types (~> 3.0)
multi_json (~> 1.13, >= 1.13.1)
multipart-post (~> 2.0)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -40,6 +42,9 @@ GEM
httparty (0.15.6)
multi_xml (>= 0.5.2)
ice_nine (0.11.2)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
Expand Down
14 changes: 13 additions & 1 deletion config.reek
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
"lib/smartcat_sdk/rest":
InstanceVariableAssumption:
enabled: false
TooManyInstanceVariables:
max_instance_variables: 6

IrresponsibleModule:
enabled: false

DuplicateMethodCall:
enabled: false

Expand All @@ -6,4 +15,7 @@ FeatureEnvy:

TooManyStatements:
enabled: true
max_statements: 6
max_statements: 6

LongParameterList:
max_params: 4
18 changes: 17 additions & 1 deletion examples/example.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,20 @@
# -------------------------------------------------------------
project = SmartcatSDK::REST::Project.new(ACCOUNT_ID, API_KEY)
# Get project details
puts project.get('EXAMPLE_PROJECT_ID')
PROJECT_ID = 'EXAMPLE_PROJECT_ID'.freeze
puts project.get(PROJECT_ID)

# Create project without file
model = {
'name' => 'Test',
'description' => 'Test',
'sourceLanguage' => 'tr',
'targetLanguages' => %w[en],
'workflowStages' => [
'translation'
],
'assignToVendor' => false
}
puts project.create(model)
# Create project with files
puts project.create(model, files: %w[files/Test.txt files/Test-2.txt])
1 change: 1 addition & 0 deletions examples/files/Test-2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test test test test test test
1 change: 1 addition & 0 deletions examples/files/Test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test
8 changes: 8 additions & 0 deletions lib/smartcat_sdk.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
require 'net/http'
require 'net/https'
require 'json'

# Our multipart post lib
require 'net/http/post/multipart'

# JSON parser
require 'multi_json'

# File format decider
require 'mime/types'

# Smartcat files
require 'smartcat_sdk/version' unless defined?(SmartcatSDK::VERSION)
require 'smartcat_sdk/util/client_config'
require 'smartcat_sdk/util/project'
require 'smartcat_sdk/util/request'
require 'smartcat_sdk/rest/errors'
require 'smartcat_sdk/rest/project'

Expand Down
72 changes: 41 additions & 31 deletions lib/smartcat_sdk/rest/base_request.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
module SmartcatSDK
module REST
class BaseRequest
RUBY_INFO = "(#{RUBY_ENGINE}/#{RUBY_PLATFORM} #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})".freeze
HTTP_HEADERS = {
'Accept' => 'application/json',
'Accept-Charset' => 'utf-8',
'User-Agent' => "smartcat_sdk/#{SmartcatSDK::VERSION} #{RUBY_INFO}"
}.freeze

def initialize(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
@config = SmartcatSDK::Util::ClientConfig.new options
@user = args[0] || nil
@password = args[1] || nil
raise ArgumentError, 'Account ID is required' if @user.nil?
raise ArgumentError, 'API key is required' if @password.nil?
raise ArgumentError, 'Account ID is required' unless @user
raise ArgumentError, 'API key is required' unless @password
set_up_connection
end

protected

##
# Prepare http request
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def prepare_request(method, path, params: {})
# :reek:TooManyStatements { enabled: false }
def prepare_request(method, path, params: {}, headers: {})
request_path = @config.host
request_path += "/api/integration/v1/#{path}"
uri = URI.parse(request_path)
uri.query = URI.encode_www_form(params) if %w[get delete].include?(method)
method_class = Net::HTTP.const_get method.to_s.capitalize
request = method_class.new(uri.to_s, HTTP_HEADERS)
request.form_data = params if %w[post put].include?(method)
uri.query = URI.encode_www_form(params) if %w[get delete post_multipart].include?(method)
request = SmartcatSDK::Util::Request.prepare(headers, method, params, uri)
request.basic_auth(@user, @password)
connect_and_send(request)
end
Expand All @@ -40,6 +30,9 @@ def prepare_request(method, path, params: {})

##
# Set up and cache a Net::HTTP object to use when making requests.
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
# :reek:TooManyStatements { enabled: false }
def set_up_connection
uri = URI.parse(@config.host)
@http = Net::HTTP.new(
Expand All @@ -61,14 +54,16 @@ def set_up_connection
@http.open_timeout = @config.timeout
@http.read_timeout = @config.timeout
end
# rubocop:enable Metrics/AbcSize

##
# Send an HTTP request using the cached <tt>@http</tt> object and
# return the JSON response body parsed into a hash. Also save the raw
# Net::HTTP::Request and Net::HTTP::Response objects as
# <tt>@last_request</tt> and <tt>@last_response</tt> to allow for
# inspection later.
def connect_and_send(request, is_file = false)
# :reek:TooManyStatements { enabled: false }
def connect_and_send(request, type: :json)
@last_request = request
retries_left = @config.retry_limit
begin
Expand All @@ -81,23 +76,38 @@ def connect_and_send(request, is_file = false)
retries_left -= 1
retry
end
handle_response_errors(handle_response(is_file, response), response)
Builder.handle(type, response)
end
# rubocop:enable Metrics/MethodLength

def handle_response_errors(object, response)
return object unless response.is_a?(Net::HTTPClientError)
raise SmartcatSDK::REST::RequestError.new(object['error'], object['code'])
end
class Builder
# rubocop:disable Metrics/MethodLength
def self.handle(type, response)
if response.is_a?(Net::HTTPClientError)
raise SmartcatSDK::REST::RequestError.new(response, response['code'])
end
if response.body && !response.body.empty?
builder_class = Builder.const_get(type.to_s.capitalize)
builder_class.result(response.body)
elsif response.is_a?(Net::HTTPBadRequest)
{
message: 'Bad request',
code: 400
}
end
end
# rubocop:enable Metrics/MethodLength

class Body
def self.result(body)
body
end
end

def handle_response(is_file, response)
if response.body && !response.body.empty?
return response.body if is_file
MultiJson.load(response.body)
elsif response.is_a?(Net::HTTPBadRequest)
{
message: 'Bad request',
code: 400
}
class Json
def self.result(body)
MultiJson.load(body)
end
end
end
end
Expand Down
5 changes: 2 additions & 3 deletions lib/smartcat_sdk/rest/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class ServerError < StandardError; end
class RequestError < StandardError
attr_reader :code

def initialize(message, code=nil)
def initialize(message, code = nil)
super message
@code = code
end
Expand All @@ -14,11 +14,10 @@ def initialize(message, code=nil)
class SDKError < StandardError
attr_reader :code

def initialize(message, code=nil)
def initialize(message, code = nil)
super message
@code = code
end
end

end
end
12 changes: 11 additions & 1 deletion lib/smartcat_sdk/rest/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@
module SmartcatSDK
module REST
class Project < BaseRequest

def initialize(*args)
super(*args)
@resource = 'project'
end

# @param [Hash] project_model
# @param [Array] files file directory paths
def create(project_model, files: [])
prepare_request(
:post_multipart,
"#{@resource}/create",
params: SmartcatSDK::Util::Project.params(project_model, files),
headers: SmartcatSDK::Util::Project.model_headers
)
end

def get(project_id)
prepare_request(:get, "#{@resource}/#{project_id}")
end
Expand Down
4 changes: 2 additions & 2 deletions lib/smartcat_sdk/util/client_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class ClientConfig
attr_accessor attribute
end

def initialize(opts={})
def initialize(opts = {})
DEFAULTS.each do |attribute, value|
send("#{attribute}=".to_sym, opts.fetch(attribute, value))
send("#{attribute}=".to_sym, opts.fetch(attribute) { value })
end
end
end
Expand Down
41 changes: 41 additions & 0 deletions lib/smartcat_sdk/util/project.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module SmartcatSDK
module Util
module Project
MODEL_KEY = 'model'.freeze

class << self
def params(project_model, files)
params = {
SmartcatSDK::Util::Project::MODEL_KEY => JSON.generate(project_model)
}
prepare_files(files, params)
params
end

def model_headers
{
parts: {
MODEL_KEY => {
'Content-Type' => 'application/json'
}
}
}
end

private

# :reek:TooManyStatements { enabled: false }
def prepare_files(files, params)
index = 0
files.each do |path|
file_name = File.basename(path)
file = File.new(path)
content_type = MIME::Types.type_for(file.path).first.to_s
params["project_file#{index}"] = UploadIO.new(file, content_type, file_name)
index += 1
end
end
end
end
end
end
24 changes: 24 additions & 0 deletions lib/smartcat_sdk/util/request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module SmartcatSDK
module Util
module Request
RUBY_INFO = "(#{RUBY_ENGINE}/#{RUBY_PLATFORM} #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})".freeze
HTTP_HEADERS = {
'Accept' => 'application/json',
'Accept-Charset' => 'utf-8',
'User-Agent' => "smartcat_sdk/#{SmartcatSDK::VERSION} #{RUBY_INFO}"
}.freeze

class << self
def prepare(headers, method, params, uri)
if method == :post_multipart
return Net::HTTP::Post::Multipart.new(uri, params, HTTP_HEADERS.merge(headers))
end
method_class = Net::HTTP.const_get method.to_s.capitalize
request = method_class.new(uri.to_s, headers)
request.form_data = params if %w[post put].include?(method)
request
end
end
end
end
end
1 change: 1 addition & 0 deletions smartcat_sdk.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']
spec.add_runtime_dependency 'multi_json', '~> 1.13', '>= 1.13.1'
spec.add_runtime_dependency 'multipart-post', '~> 2.0'
spec.add_dependency 'mime-types', '~> 3.0'
spec.add_development_dependency 'bundler', '~> 1.16'
spec.add_development_dependency 'pronto', '~> 0.9.5'
spec.add_development_dependency 'pronto-fasterer', '~> 0.9.0'
Expand Down

0 comments on commit c5a3f88

Please sign in to comment.