rev-api 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +22 -22
- data/.ruby-gemset +1 -1
- data/.ruby-version +1 -1
- data/.travis.yml +8 -8
- data/Gemfile +3 -3
- data/LICENSE +191 -191
- data/README.md +131 -131
- data/Rakefile +13 -13
- data/examples/cli.rb +270 -270
- data/lib/rev-api.rb +26 -26
- data/lib/rev-api/api.rb +326 -326
- data/lib/rev-api/api_serializable.rb +30 -30
- data/lib/rev-api/exceptions.rb +97 -97
- data/lib/rev-api/http_client.rb +97 -97
- data/lib/rev-api/models/order.rb +129 -129
- data/lib/rev-api/models/order_request.rb +292 -273
- data/lib/rev-api/version.rb +3 -3
- data/rev-api.gemspec +33 -33
- data/spec/fixtures/api_cassettes/cancel_order.yml +38 -38
- data/spec/fixtures/api_cassettes/cancel_order_not_allowed.yml +40 -40
- data/spec/fixtures/api_cassettes/get_attachment_content.yml +399 -399
- data/spec/fixtures/api_cassettes/get_attachment_content_as_pdf.yml +399 -399
- data/spec/fixtures/api_cassettes/get_attachment_content_as_text.yml +65 -65
- data/spec/fixtures/api_cassettes/get_attachment_content_as_youtube_transcript.yml +66 -66
- data/spec/fixtures/api_cassettes/get_attachment_content_unacceptable_representation.yml +42 -42
- data/spec/fixtures/api_cassettes/get_attachment_content_with_invalid_id.yml +42 -42
- data/spec/fixtures/api_cassettes/get_attachment_metadata.yml +42 -42
- data/spec/fixtures/api_cassettes/get_attachment_with_invalid_id.yml +40 -40
- data/spec/fixtures/api_cassettes/get_orders.yml +122 -122
- data/spec/fixtures/api_cassettes/get_orders_with_clientRef.yml +41 -41
- data/spec/fixtures/api_cassettes/get_tc_order.yml +44 -44
- data/spec/fixtures/api_cassettes/get_third_page_of_orders.yml +52 -52
- data/spec/fixtures/api_cassettes/link_input.yml +44 -44
- data/spec/fixtures/api_cassettes/link_input_with_all_attributes.yml +44 -44
- data/spec/fixtures/api_cassettes/link_input_with_spaces_in_filename.yml +45 -45
- data/spec/fixtures/api_cassettes/not_found_order.yml +42 -42
- data/spec/fixtures/api_cassettes/submit_cp_order.yml +44 -44
- data/spec/fixtures/api_cassettes/submit_su_order.yml +44 -44
- data/spec/fixtures/api_cassettes/submit_tc_order_with_account_balance.yml +44 -44
- data/spec/fixtures/api_cassettes/submit_tc_order_with_invalid_request.yml +45 -45
- data/spec/fixtures/api_cassettes/submit_tc_order_without_specifying_payment.yml +44 -44
- data/spec/fixtures/api_cassettes/unauthorized.yml +42 -42
- data/spec/fixtures/api_cassettes/upload_input.yml +90 -90
- data/spec/fixtures/api_cassettes/upload_input_with_invalid_content_type.yml +91 -91
- data/spec/lib/rev/api_spec.rb +30 -30
- data/spec/lib/rev/cancel_order_spec.rb +24 -24
- data/spec/lib/rev/exceptions_spec.rb +8 -8
- data/spec/lib/rev/get_attachment_content_spec.rb +79 -79
- data/spec/lib/rev/get_attachment_metadata_spec.rb +33 -33
- data/spec/lib/rev/get_order_spec.rb +52 -52
- data/spec/lib/rev/get_orders_spec.rb +62 -62
- data/spec/lib/rev/http_client_spec.rb +32 -32
- data/spec/lib/rev/models/order_request_spec.rb +41 -6
- data/spec/lib/rev/models/order_spec.rb +58 -58
- data/spec/lib/rev/post_inputs_spec.rb +94 -94
- data/spec/lib/rev/post_order_spec.rb +163 -163
- data/spec/spec_helper.rb +47 -47
- data/spec/test_helpers.rb +5 -5
- metadata +19 -19
@@ -1,30 +1,30 @@
|
|
1
|
-
module Rev
|
2
|
-
# Utility class with instance methods for hash/JSON conversion
|
3
|
-
class ApiSerializable
|
4
|
-
|
5
|
-
# Map given hash to instance properties
|
6
|
-
#
|
7
|
-
# @param fields [Hash] of fields to initialize instance. See instance attributes for available fields.
|
8
|
-
def initialize(fields = {})
|
9
|
-
fields.each { |k,v| self.instance_variable_set("@#{k.to_sym}", v) if self.methods.include? k.to_sym }
|
10
|
-
end
|
11
|
-
|
12
|
-
# Recursively convert object to hash
|
13
|
-
# @note http://stackoverflow.com/questions/1684588/how-to-do-ruby-object-serialization-using-json
|
14
|
-
#
|
15
|
-
# @return [Hash] hash map of the object including all nested children
|
16
|
-
def to_hash
|
17
|
-
h = {}
|
18
|
-
instance_variables.each do |e|
|
19
|
-
o = instance_variable_get e.to_sym
|
20
|
-
h[e[1..-1]] = (o.respond_to? :to_hash) ? o.to_hash : o;
|
21
|
-
end
|
22
|
-
h
|
23
|
-
end
|
24
|
-
|
25
|
-
# Recursively convert object to JSON (internally utilizing hash)
|
26
|
-
def to_json *args
|
27
|
-
to_hash.to_json *args
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
1
|
+
module Rev
|
2
|
+
# Utility class with instance methods for hash/JSON conversion
|
3
|
+
class ApiSerializable
|
4
|
+
|
5
|
+
# Map given hash to instance properties
|
6
|
+
#
|
7
|
+
# @param fields [Hash] of fields to initialize instance. See instance attributes for available fields.
|
8
|
+
def initialize(fields = {})
|
9
|
+
fields.each { |k,v| self.instance_variable_set("@#{k.to_sym}", v) if self.methods.include? k.to_sym }
|
10
|
+
end
|
11
|
+
|
12
|
+
# Recursively convert object to hash
|
13
|
+
# @note http://stackoverflow.com/questions/1684588/how-to-do-ruby-object-serialization-using-json
|
14
|
+
#
|
15
|
+
# @return [Hash] hash map of the object including all nested children
|
16
|
+
def to_hash
|
17
|
+
h = {}
|
18
|
+
instance_variables.each do |e|
|
19
|
+
o = instance_variable_get e.to_sym
|
20
|
+
h[e[1..-1]] = (o.respond_to? :to_hash) ? o.to_hash : o;
|
21
|
+
end
|
22
|
+
h
|
23
|
+
end
|
24
|
+
|
25
|
+
# Recursively convert object to JSON (internally utilizing hash)
|
26
|
+
def to_json *args
|
27
|
+
to_hash.to_json *args
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/rev-api/exceptions.rb
CHANGED
@@ -1,97 +1,97 @@
|
|
1
|
-
module Rev
|
2
|
-
class ApiError < StandardError; end
|
3
|
-
|
4
|
-
# 400 BadRequest. Response body contains API error code and optional details
|
5
|
-
class BadRequestError < ApiError
|
6
|
-
|
7
|
-
# Code of the validation error
|
8
|
-
attr_reader :code
|
9
|
-
|
10
|
-
# @param message [String] custom message, usually includes API validation error code and it's meaning
|
11
|
-
# @param code [Integer] API validation code is passed separately to be evaluated in consumer's app
|
12
|
-
def initialize(message, code)
|
13
|
-
super message
|
14
|
-
@code = code
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# 401 Unauthorized
|
19
|
-
class NotAuthorizedError < ApiError; end
|
20
|
-
|
21
|
-
# 403 Forbidden (not allowed)
|
22
|
-
class ForbiddenError < ApiError; end
|
23
|
-
|
24
|
-
# 404 Not Found
|
25
|
-
class NotFoundError < ApiError; end
|
26
|
-
|
27
|
-
# 406 NotAcceptable (used when requested representation is not supported by attachment)
|
28
|
-
class NotAcceptableError < ApiError; end
|
29
|
-
|
30
|
-
# 500 ServerError (internal error on API server)
|
31
|
-
class ServerError < ApiError; end
|
32
|
-
|
33
|
-
# have no idea what's going on - used in 'pokemon' rescue
|
34
|
-
class UnknownError < ApiError; end
|
35
|
-
|
36
|
-
# Constants for validation error codes in OrderRequest response
|
37
|
-
module OrderRequestErrorCodes
|
38
|
-
# 10001 Missing Inputs - if the order request did not contain any input media
|
39
|
-
MISSING_INPUTS = 10001
|
40
|
-
|
41
|
-
# 10002 Invalid Input - if one of the input media URIs is invalid, eg does not identify a valid media uploaded via a POST to /inputs
|
42
|
-
INVALID_INPUTS = 10002
|
43
|
-
|
44
|
-
# 10003 Multiple options specified - only options for one service can be included per each order placement request
|
45
|
-
MULTIPLE_OPTIONS_SPECIFIED = 10003
|
46
|
-
|
47
|
-
# 10001 Missing Inputs - if the order request did not contain any input media
|
48
|
-
OPTIONS_NOT_SPECIFIED = 10004
|
49
|
-
|
50
|
-
# 10005 External Link and URI specified - only External Link or URI should be set for input media
|
51
|
-
EXTERNAL_LINK_AND_URI_SPECIFIED = 10005
|
52
|
-
|
53
|
-
# 10006 Input Location is not specified - neither of External Link and URI set for input media
|
54
|
-
EXTERNAL_LINK_OR_URI_NOT_SPECIFIED = 10006
|
55
|
-
|
56
|
-
# 20001 Invalid Media Length - If one of the input medias has a specified length that is not a positive integer
|
57
|
-
INVALID_MEDIA_LENGTH = 20001
|
58
|
-
|
59
|
-
# @deprecated Use {#OrderRequestErrorCodes.INVALID_MEDIA_LENGTH} instead
|
60
|
-
INVALID_AUDIO_LENGTH = INVALID_MEDIA_LENGTH
|
61
|
-
|
62
|
-
# 20003 Invalid Language Code - the language codes provided for subtitles are invalid
|
63
|
-
INVALID_LANGUAGE_CODE = 20003
|
64
|
-
|
65
|
-
# 20010 Reference Number Too Long Code - the reference number provided longer than 40 characters
|
66
|
-
REFERENCE_NUMBER_TOO_LONG = 20010
|
67
|
-
|
68
|
-
# 30001 Missing Payment Info - if the order request did not contain a payment information element
|
69
|
-
MISSING_PAYMENT_INFO = 30001
|
70
|
-
|
71
|
-
# 30002 Missing Payment Type - if the order request did not contain a payment kind element
|
72
|
-
MISSING_PAYMENT_TYPE = 30002
|
73
|
-
|
74
|
-
# 30010 Ineligible For Balance Payments - if the user on whose behalf the order request was made is not eligible for paying using account balance
|
75
|
-
INELIGIBLE_FOR_BALANCE_PAYMENT = 30010
|
76
|
-
|
77
|
-
# 30011 Account Balance Limit Exceeded - if the order request specified payment using account balance, but doing so would exceed the user's balance limit
|
78
|
-
ACCOUNT_BALANCE_LIMIT_EXCEEDED = 30011
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
module InputRequestErrorCodes
|
83
|
-
# 10001 Unsupported Content Type – if the content type of the media is not currently supported by our system.
|
84
|
-
# Supported media types for inputs are listed in https://www.rev.com/api/inputspost
|
85
|
-
UNSUPPORTED_CONTENT_TYPE = 10001
|
86
|
-
|
87
|
-
# 10002 Could not retrieve file – if we could not retrieve the file from the specified location.
|
88
|
-
COULD_NOT_RETRIEVE_MEDIA = 10002
|
89
|
-
|
90
|
-
# 10003 Invalid multipart request – If the multipart request did not contain exactly one file part, or was otherwise malformed.
|
91
|
-
INVALID_MULTIPART_REQUEST = 10003
|
92
|
-
|
93
|
-
# 10004 Unspecified filename - If the filename for the media was not specified explicitly and could not be determined automatically.
|
94
|
-
UNSPECIFIED_FILENAME = 10004
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
1
|
+
module Rev
|
2
|
+
class ApiError < StandardError; end
|
3
|
+
|
4
|
+
# 400 BadRequest. Response body contains API error code and optional details
|
5
|
+
class BadRequestError < ApiError
|
6
|
+
|
7
|
+
# Code of the validation error
|
8
|
+
attr_reader :code
|
9
|
+
|
10
|
+
# @param message [String] custom message, usually includes API validation error code and it's meaning
|
11
|
+
# @param code [Integer] API validation code is passed separately to be evaluated in consumer's app
|
12
|
+
def initialize(message, code)
|
13
|
+
super message
|
14
|
+
@code = code
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# 401 Unauthorized
|
19
|
+
class NotAuthorizedError < ApiError; end
|
20
|
+
|
21
|
+
# 403 Forbidden (not allowed)
|
22
|
+
class ForbiddenError < ApiError; end
|
23
|
+
|
24
|
+
# 404 Not Found
|
25
|
+
class NotFoundError < ApiError; end
|
26
|
+
|
27
|
+
# 406 NotAcceptable (used when requested representation is not supported by attachment)
|
28
|
+
class NotAcceptableError < ApiError; end
|
29
|
+
|
30
|
+
# 500 ServerError (internal error on API server)
|
31
|
+
class ServerError < ApiError; end
|
32
|
+
|
33
|
+
# have no idea what's going on - used in 'pokemon' rescue
|
34
|
+
class UnknownError < ApiError; end
|
35
|
+
|
36
|
+
# Constants for validation error codes in OrderRequest response
|
37
|
+
module OrderRequestErrorCodes
|
38
|
+
# 10001 Missing Inputs - if the order request did not contain any input media
|
39
|
+
MISSING_INPUTS = 10001
|
40
|
+
|
41
|
+
# 10002 Invalid Input - if one of the input media URIs is invalid, eg does not identify a valid media uploaded via a POST to /inputs
|
42
|
+
INVALID_INPUTS = 10002
|
43
|
+
|
44
|
+
# 10003 Multiple options specified - only options for one service can be included per each order placement request
|
45
|
+
MULTIPLE_OPTIONS_SPECIFIED = 10003
|
46
|
+
|
47
|
+
# 10001 Missing Inputs - if the order request did not contain any input media
|
48
|
+
OPTIONS_NOT_SPECIFIED = 10004
|
49
|
+
|
50
|
+
# 10005 External Link and URI specified - only External Link or URI should be set for input media
|
51
|
+
EXTERNAL_LINK_AND_URI_SPECIFIED = 10005
|
52
|
+
|
53
|
+
# 10006 Input Location is not specified - neither of External Link and URI set for input media
|
54
|
+
EXTERNAL_LINK_OR_URI_NOT_SPECIFIED = 10006
|
55
|
+
|
56
|
+
# 20001 Invalid Media Length - If one of the input medias has a specified length that is not a positive integer
|
57
|
+
INVALID_MEDIA_LENGTH = 20001
|
58
|
+
|
59
|
+
# @deprecated Use {#OrderRequestErrorCodes.INVALID_MEDIA_LENGTH} instead
|
60
|
+
INVALID_AUDIO_LENGTH = INVALID_MEDIA_LENGTH
|
61
|
+
|
62
|
+
# 20003 Invalid Language Code - the language codes provided for subtitles are invalid
|
63
|
+
INVALID_LANGUAGE_CODE = 20003
|
64
|
+
|
65
|
+
# 20010 Reference Number Too Long Code - the reference number provided longer than 40 characters
|
66
|
+
REFERENCE_NUMBER_TOO_LONG = 20010
|
67
|
+
|
68
|
+
# 30001 Missing Payment Info - if the order request did not contain a payment information element
|
69
|
+
MISSING_PAYMENT_INFO = 30001
|
70
|
+
|
71
|
+
# 30002 Missing Payment Type - if the order request did not contain a payment kind element
|
72
|
+
MISSING_PAYMENT_TYPE = 30002
|
73
|
+
|
74
|
+
# 30010 Ineligible For Balance Payments - if the user on whose behalf the order request was made is not eligible for paying using account balance
|
75
|
+
INELIGIBLE_FOR_BALANCE_PAYMENT = 30010
|
76
|
+
|
77
|
+
# 30011 Account Balance Limit Exceeded - if the order request specified payment using account balance, but doing so would exceed the user's balance limit
|
78
|
+
ACCOUNT_BALANCE_LIMIT_EXCEEDED = 30011
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
module InputRequestErrorCodes
|
83
|
+
# 10001 Unsupported Content Type – if the content type of the media is not currently supported by our system.
|
84
|
+
# Supported media types for inputs are listed in https://www.rev.com/api/inputspost
|
85
|
+
UNSUPPORTED_CONTENT_TYPE = 10001
|
86
|
+
|
87
|
+
# 10002 Could not retrieve file – if we could not retrieve the file from the specified location.
|
88
|
+
COULD_NOT_RETRIEVE_MEDIA = 10002
|
89
|
+
|
90
|
+
# 10003 Invalid multipart request – If the multipart request did not contain exactly one file part, or was otherwise malformed.
|
91
|
+
INVALID_MULTIPART_REQUEST = 10003
|
92
|
+
|
93
|
+
# 10004 Unspecified filename - If the filename for the media was not specified explicitly and could not be determined automatically.
|
94
|
+
UNSPECIFIED_FILENAME = 10004
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/lib/rev-api/http_client.rb
CHANGED
@@ -1,97 +1,97 @@
|
|
1
|
-
module Rev
|
2
|
-
|
3
|
-
# HTTP client handling authentication and HTTP requests at the low level for the Api class.
|
4
|
-
# Not indended to be used directly - clients should be using the Api class instead.
|
5
|
-
class HttpClient
|
6
|
-
|
7
|
-
include HTTParty
|
8
|
-
|
9
|
-
USER_AGENT = "RevOfficialRubySDK/#{VERSION}"
|
10
|
-
|
11
|
-
# Create a new HttpClient, connecting to given host, and using the given Client and User API Keys.
|
12
|
-
#
|
13
|
-
# @param client_api_key [String] the client API key to use for authenticating
|
14
|
-
# @param user_api_key [String] the user API key to use for authenticating
|
15
|
-
# @param host [String] the host to send requests to. Should be one of Rev::Api::PRODCUTION_HOST or Rev::Api::SANDBOX_HOST
|
16
|
-
def initialize(client_api_key, user_api_key, host)
|
17
|
-
endpoint_uri = "https://#{host}/api/v1"
|
18
|
-
self.class.base_uri(endpoint_uri)
|
19
|
-
|
20
|
-
auth_string = "Rev #{client_api_key}:#{user_api_key}"
|
21
|
-
@default_headers = {
|
22
|
-
'Authorization' => auth_string,
|
23
|
-
'User-Agent' => USER_AGENT # to track usage of SDK
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
# Performs HTTP GET of JSON data.
|
28
|
-
#
|
29
|
-
# @param operation [String] URL suffix describing specific operation, like '/orders'
|
30
|
-
# @param headers [Hash] hash of headers to use for the request
|
31
|
-
# @return [HTTParty::Response] response
|
32
|
-
def get(operation, headers = {})
|
33
|
-
headers = @default_headers.merge(headers)
|
34
|
-
self.class.get(operation, :headers => headers)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Performs HTTP GET of binary data. Note, unlike post, this returns a
|
38
|
-
# Net::HTTP::Response, not HTTParty::Response.
|
39
|
-
#
|
40
|
-
# If this method is passed a block, will pass response to that block. in that case the response is not yet
|
41
|
-
# read into memory, so the block can read it progressively. otherwise, returns the response.
|
42
|
-
#
|
43
|
-
# @param operation [String] URL suffix describing specific operation, like '/orders'
|
44
|
-
# @param headers [Hash] hash of headers to use for the request
|
45
|
-
# @yieldparam resp [Net::HTTP::Response] the response, ready to be read
|
46
|
-
# @return [Net::HTTP::Response] response
|
47
|
-
def get_binary(operation, headers = {}, &block)
|
48
|
-
uri = URI.parse("#{self.class.base_uri}#{operation}")
|
49
|
-
headers = @default_headers.merge(headers)
|
50
|
-
|
51
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
52
|
-
http.use_ssl = true
|
53
|
-
|
54
|
-
get = Net::HTTP::Get.new(uri.request_uri, headers)
|
55
|
-
if block_given?
|
56
|
-
http.request(get) do |resp|
|
57
|
-
yield resp
|
58
|
-
end
|
59
|
-
else
|
60
|
-
http.request(get)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Performs HTTP POST of JSON data.
|
65
|
-
#
|
66
|
-
# @param operation[String] URL suffix describing specific operation
|
67
|
-
# @param data [Hash] hash of keys/values to post in request body
|
68
|
-
# @param headers [Hash] hash of headers to use for the request
|
69
|
-
# @return [HTTParty::Response] response
|
70
|
-
def post(operation, data = {}, headers = {})
|
71
|
-
headers = @default_headers.merge(headers)
|
72
|
-
self.class.post(operation, :headers => headers, :body => data)
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
# Performs HTTP POST of binary data. Note, unlike post, this returns a
|
77
|
-
# Net::HTTP::Response, not HTTParty::Response.
|
78
|
-
#
|
79
|
-
# @param operation[String] URL suffix describing specific operation
|
80
|
-
# @param file [File] file-like object containing the data to post
|
81
|
-
# @param headers [Hash] hash of headers to use for the request
|
82
|
-
# @return [Net::HTTP::Response] response
|
83
|
-
def post_binary(operation, file, headers = {})
|
84
|
-
uri = URI.parse("#{self.class.base_uri}#{operation}")
|
85
|
-
headers = @default_headers.merge(headers)
|
86
|
-
|
87
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
88
|
-
http.use_ssl = true
|
89
|
-
|
90
|
-
post = Net::HTTP::Post.new(uri.request_uri, headers)
|
91
|
-
post["Content-Length"] = file.stat.size.to_s
|
92
|
-
post.body_stream = file
|
93
|
-
|
94
|
-
response = http.request(post)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
1
|
+
module Rev
|
2
|
+
|
3
|
+
# HTTP client handling authentication and HTTP requests at the low level for the Api class.
|
4
|
+
# Not indended to be used directly - clients should be using the Api class instead.
|
5
|
+
class HttpClient
|
6
|
+
|
7
|
+
include HTTParty
|
8
|
+
|
9
|
+
USER_AGENT = "RevOfficialRubySDK/#{VERSION}"
|
10
|
+
|
11
|
+
# Create a new HttpClient, connecting to given host, and using the given Client and User API Keys.
|
12
|
+
#
|
13
|
+
# @param client_api_key [String] the client API key to use for authenticating
|
14
|
+
# @param user_api_key [String] the user API key to use for authenticating
|
15
|
+
# @param host [String] the host to send requests to. Should be one of Rev::Api::PRODCUTION_HOST or Rev::Api::SANDBOX_HOST
|
16
|
+
def initialize(client_api_key, user_api_key, host)
|
17
|
+
endpoint_uri = "https://#{host}/api/v1"
|
18
|
+
self.class.base_uri(endpoint_uri)
|
19
|
+
|
20
|
+
auth_string = "Rev #{client_api_key}:#{user_api_key}"
|
21
|
+
@default_headers = {
|
22
|
+
'Authorization' => auth_string,
|
23
|
+
'User-Agent' => USER_AGENT # to track usage of SDK
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Performs HTTP GET of JSON data.
|
28
|
+
#
|
29
|
+
# @param operation [String] URL suffix describing specific operation, like '/orders'
|
30
|
+
# @param headers [Hash] hash of headers to use for the request
|
31
|
+
# @return [HTTParty::Response] response
|
32
|
+
def get(operation, headers = {})
|
33
|
+
headers = @default_headers.merge(headers)
|
34
|
+
self.class.get(operation, :headers => headers)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Performs HTTP GET of binary data. Note, unlike post, this returns a
|
38
|
+
# Net::HTTP::Response, not HTTParty::Response.
|
39
|
+
#
|
40
|
+
# If this method is passed a block, will pass response to that block. in that case the response is not yet
|
41
|
+
# read into memory, so the block can read it progressively. otherwise, returns the response.
|
42
|
+
#
|
43
|
+
# @param operation [String] URL suffix describing specific operation, like '/orders'
|
44
|
+
# @param headers [Hash] hash of headers to use for the request
|
45
|
+
# @yieldparam resp [Net::HTTP::Response] the response, ready to be read
|
46
|
+
# @return [Net::HTTP::Response] response
|
47
|
+
def get_binary(operation, headers = {}, &block)
|
48
|
+
uri = URI.parse("#{self.class.base_uri}#{operation}")
|
49
|
+
headers = @default_headers.merge(headers)
|
50
|
+
|
51
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
52
|
+
http.use_ssl = true
|
53
|
+
|
54
|
+
get = Net::HTTP::Get.new(uri.request_uri, headers)
|
55
|
+
if block_given?
|
56
|
+
http.request(get) do |resp|
|
57
|
+
yield resp
|
58
|
+
end
|
59
|
+
else
|
60
|
+
http.request(get)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Performs HTTP POST of JSON data.
|
65
|
+
#
|
66
|
+
# @param operation[String] URL suffix describing specific operation
|
67
|
+
# @param data [Hash] hash of keys/values to post in request body
|
68
|
+
# @param headers [Hash] hash of headers to use for the request
|
69
|
+
# @return [HTTParty::Response] response
|
70
|
+
def post(operation, data = {}, headers = {})
|
71
|
+
headers = @default_headers.merge(headers)
|
72
|
+
self.class.post(operation, :headers => headers, :body => data)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Performs HTTP POST of binary data. Note, unlike post, this returns a
|
77
|
+
# Net::HTTP::Response, not HTTParty::Response.
|
78
|
+
#
|
79
|
+
# @param operation[String] URL suffix describing specific operation
|
80
|
+
# @param file [File] file-like object containing the data to post
|
81
|
+
# @param headers [Hash] hash of headers to use for the request
|
82
|
+
# @return [Net::HTTP::Response] response
|
83
|
+
def post_binary(operation, file, headers = {})
|
84
|
+
uri = URI.parse("#{self.class.base_uri}#{operation}")
|
85
|
+
headers = @default_headers.merge(headers)
|
86
|
+
|
87
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
88
|
+
http.use_ssl = true
|
89
|
+
|
90
|
+
post = Net::HTTP::Post.new(uri.request_uri, headers)
|
91
|
+
post["Content-Length"] = file.stat.size.to_s
|
92
|
+
post.body_stream = file
|
93
|
+
|
94
|
+
response = http.request(post)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/rev-api/models/order.rb
CHANGED
@@ -1,129 +1,129 @@
|
|
1
|
-
require 'rev-api/api_serializable'
|
2
|
-
|
3
|
-
module Rev
|
4
|
-
# Represents a Caption or Transcription order.
|
5
|
-
# Should have CaptionInfo or TranscriptionInfo, list
|
6
|
-
# of comments and attachments. Attributes names reflect
|
7
|
-
# API exposed names, but occasional hyphens are replaced
|
8
|
-
# with underscores
|
9
|
-
class Order < ApiSerializable
|
10
|
-
attr_reader :order_number, :price, :status, :attachments, :comments,
|
11
|
-
:transcription, :caption, :client_ref
|
12
|
-
|
13
|
-
# @param fields [Hash] hash of order fields parsed from JSON API response
|
14
|
-
def initialize(fields)
|
15
|
-
super fields
|
16
|
-
@attachments = fields['attachments'].map { |attachment_fields| Attachment.new(attachment_fields) }
|
17
|
-
@comments = fields['comments'].map { |comment_fields| Comment.new(comment_fields) }
|
18
|
-
@transcription = TranscriptionInfo.new(fields['transcription']) if fields['transcription']
|
19
|
-
@caption = CaptionInfo.new(fields['caption']) if fields['caption']
|
20
|
-
end
|
21
|
-
|
22
|
-
# @return [Array of Attachment] with the kind of "transcript"
|
23
|
-
def transcripts
|
24
|
-
@attachments.select { |a| a.kind == Attachment::KINDS[:transcript]}
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [Array of Attachment] with the kind of "caption"
|
28
|
-
def captions
|
29
|
-
@attachments.select { |a| a.kind == Attachment::KINDS[:caption] }
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [Array of Attachment] with the kind of "sources"
|
33
|
-
def sources
|
34
|
-
@attachments.select { |a| a.kind == Attachment::KINDS[:media]}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Order comment, containing author, creation timestamp and text
|
39
|
-
class Comment < ApiSerializable
|
40
|
-
require 'date'
|
41
|
-
|
42
|
-
attr_reader :by, :timestamp, :text
|
43
|
-
|
44
|
-
# @param fields [Hash] hash of comment fields parsed from JSON API response
|
45
|
-
def initialize(fields)
|
46
|
-
super fields
|
47
|
-
@timestamp = Date.iso8601(fields['timestamp'])
|
48
|
-
@text = fields['text'] ? fields['text'] : String.new # right now API gives no 'text' field if text is empty
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Additional information specific to transcription orders,
|
53
|
-
# such as total length in minutes, verbatim and timestamps flags
|
54
|
-
class TranscriptionInfo < ApiSerializable
|
55
|
-
attr_reader :total_length_seconds, :verbatim, :timestamps
|
56
|
-
|
57
|
-
# @deprecated use :total_length_seconds instead
|
58
|
-
attr_reader :total_length
|
59
|
-
end
|
60
|
-
|
61
|
-
# Additional information specific to caption orders
|
62
|
-
class CaptionInfo < ApiSerializable
|
63
|
-
attr_reader :total_length_seconds
|
64
|
-
|
65
|
-
# @deprecated use :total_length_seconds instead
|
66
|
-
attr_reader :total_length
|
67
|
-
end
|
68
|
-
|
69
|
-
# Represents order attachment - logical document associated with order
|
70
|
-
class Attachment < ApiSerializable
|
71
|
-
attr_reader :kind, :name, :id, :audio_length_seconds, :links, :video_length_seconds
|
72
|
-
|
73
|
-
KINDS = {
|
74
|
-
:transcript => 'transcript',
|
75
|
-
:caption => 'caption',
|
76
|
-
:media => 'media'
|
77
|
-
}
|
78
|
-
|
79
|
-
# List of supported mime-types used to request attachment's content
|
80
|
-
# within 'Accept' header
|
81
|
-
REPRESENTATIONS = {
|
82
|
-
# Supported by :transcript
|
83
|
-
:docx => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
84
|
-
:pdf => 'application/pdf',
|
85
|
-
:txt => 'text/plain',
|
86
|
-
:youtube => 'text/plain; format=youtube-transcript',
|
87
|
-
|
88
|
-
# Supported by :caption
|
89
|
-
:srt => 'application/x-subrip',
|
90
|
-
:scc => 'text/x-scc',
|
91
|
-
:mcc => 'text/x-mcc',
|
92
|
-
:ttml => 'application/ttml+xml',
|
93
|
-
:qt => 'application/x-quicktime-timedtext',
|
94
|
-
:vtt => 'text/vtt',
|
95
|
-
:dfxp => 'application/ttaf+xml',
|
96
|
-
:cap => 'application/x-cheetah-cap',
|
97
|
-
:stl => 'text/x-stl',
|
98
|
-
:avidds => 'text/vnd.avid-ds'
|
99
|
-
}
|
100
|
-
|
101
|
-
# @param fields [Hash] fields of attachment fields parsed from JSON API response
|
102
|
-
def initialize(fields)
|
103
|
-
super fields
|
104
|
-
@links = fields['links'].map { |link_fields| Link.new(link_fields) }
|
105
|
-
end
|
106
|
-
|
107
|
-
# @param ext [Symbol] extension
|
108
|
-
# @return [String] mime-type for requested extension
|
109
|
-
def self.representation_mime(ext)
|
110
|
-
REPRESENTATIONS[ext]
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Link to actual file represented by attachment
|
115
|
-
class Link < ApiSerializable
|
116
|
-
attr_reader :rel, :href, :content_type
|
117
|
-
end
|
118
|
-
|
119
|
-
# Represents a paginated list of orders, including padination info.
|
120
|
-
class OrdersListPage < ApiSerializable
|
121
|
-
attr_reader :total_count, :results_per_page, :page, :orders
|
122
|
-
|
123
|
-
# @param fields [Hash] hash of OrdersListPage fields parsed from JSON API response
|
124
|
-
def initialize(fields)
|
125
|
-
super fields
|
126
|
-
@orders = fields['orders'].map { |order_fields| Order.new(order_fields) }
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
1
|
+
require 'rev-api/api_serializable'
|
2
|
+
|
3
|
+
module Rev
|
4
|
+
# Represents a Caption or Transcription order.
|
5
|
+
# Should have CaptionInfo or TranscriptionInfo, list
|
6
|
+
# of comments and attachments. Attributes names reflect
|
7
|
+
# API exposed names, but occasional hyphens are replaced
|
8
|
+
# with underscores
|
9
|
+
class Order < ApiSerializable
|
10
|
+
attr_reader :order_number, :price, :status, :attachments, :comments,
|
11
|
+
:transcription, :caption, :client_ref
|
12
|
+
|
13
|
+
# @param fields [Hash] hash of order fields parsed from JSON API response
|
14
|
+
def initialize(fields)
|
15
|
+
super fields
|
16
|
+
@attachments = fields['attachments'].map { |attachment_fields| Attachment.new(attachment_fields) }
|
17
|
+
@comments = fields['comments'].map { |comment_fields| Comment.new(comment_fields) }
|
18
|
+
@transcription = TranscriptionInfo.new(fields['transcription']) if fields['transcription']
|
19
|
+
@caption = CaptionInfo.new(fields['caption']) if fields['caption']
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Array of Attachment] with the kind of "transcript"
|
23
|
+
def transcripts
|
24
|
+
@attachments.select { |a| a.kind == Attachment::KINDS[:transcript]}
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Array of Attachment] with the kind of "caption"
|
28
|
+
def captions
|
29
|
+
@attachments.select { |a| a.kind == Attachment::KINDS[:caption] }
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Array of Attachment] with the kind of "sources"
|
33
|
+
def sources
|
34
|
+
@attachments.select { |a| a.kind == Attachment::KINDS[:media]}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Order comment, containing author, creation timestamp and text
|
39
|
+
class Comment < ApiSerializable
|
40
|
+
require 'date'
|
41
|
+
|
42
|
+
attr_reader :by, :timestamp, :text
|
43
|
+
|
44
|
+
# @param fields [Hash] hash of comment fields parsed from JSON API response
|
45
|
+
def initialize(fields)
|
46
|
+
super fields
|
47
|
+
@timestamp = Date.iso8601(fields['timestamp'])
|
48
|
+
@text = fields['text'] ? fields['text'] : String.new # right now API gives no 'text' field if text is empty
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Additional information specific to transcription orders,
|
53
|
+
# such as total length in minutes, verbatim and timestamps flags
|
54
|
+
class TranscriptionInfo < ApiSerializable
|
55
|
+
attr_reader :total_length_seconds, :verbatim, :timestamps
|
56
|
+
|
57
|
+
# @deprecated use :total_length_seconds instead
|
58
|
+
attr_reader :total_length
|
59
|
+
end
|
60
|
+
|
61
|
+
# Additional information specific to caption orders
|
62
|
+
class CaptionInfo < ApiSerializable
|
63
|
+
attr_reader :total_length_seconds
|
64
|
+
|
65
|
+
# @deprecated use :total_length_seconds instead
|
66
|
+
attr_reader :total_length
|
67
|
+
end
|
68
|
+
|
69
|
+
# Represents order attachment - logical document associated with order
|
70
|
+
class Attachment < ApiSerializable
|
71
|
+
attr_reader :kind, :name, :id, :audio_length_seconds, :links, :video_length_seconds
|
72
|
+
|
73
|
+
KINDS = {
|
74
|
+
:transcript => 'transcript',
|
75
|
+
:caption => 'caption',
|
76
|
+
:media => 'media'
|
77
|
+
}
|
78
|
+
|
79
|
+
# List of supported mime-types used to request attachment's content
|
80
|
+
# within 'Accept' header
|
81
|
+
REPRESENTATIONS = {
|
82
|
+
# Supported by :transcript
|
83
|
+
:docx => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
84
|
+
:pdf => 'application/pdf',
|
85
|
+
:txt => 'text/plain',
|
86
|
+
:youtube => 'text/plain; format=youtube-transcript',
|
87
|
+
|
88
|
+
# Supported by :caption
|
89
|
+
:srt => 'application/x-subrip',
|
90
|
+
:scc => 'text/x-scc',
|
91
|
+
:mcc => 'text/x-mcc',
|
92
|
+
:ttml => 'application/ttml+xml',
|
93
|
+
:qt => 'application/x-quicktime-timedtext',
|
94
|
+
:vtt => 'text/vtt',
|
95
|
+
:dfxp => 'application/ttaf+xml',
|
96
|
+
:cap => 'application/x-cheetah-cap',
|
97
|
+
:stl => 'text/x-stl',
|
98
|
+
:avidds => 'text/vnd.avid-ds'
|
99
|
+
}
|
100
|
+
|
101
|
+
# @param fields [Hash] fields of attachment fields parsed from JSON API response
|
102
|
+
def initialize(fields)
|
103
|
+
super fields
|
104
|
+
@links = fields['links'].map { |link_fields| Link.new(link_fields) }
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param ext [Symbol] extension
|
108
|
+
# @return [String] mime-type for requested extension
|
109
|
+
def self.representation_mime(ext)
|
110
|
+
REPRESENTATIONS[ext]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Link to actual file represented by attachment
|
115
|
+
class Link < ApiSerializable
|
116
|
+
attr_reader :rel, :href, :content_type
|
117
|
+
end
|
118
|
+
|
119
|
+
# Represents a paginated list of orders, including padination info.
|
120
|
+
class OrdersListPage < ApiSerializable
|
121
|
+
attr_reader :total_count, :results_per_page, :page, :orders
|
122
|
+
|
123
|
+
# @param fields [Hash] hash of OrdersListPage fields parsed from JSON API response
|
124
|
+
def initialize(fields)
|
125
|
+
super fields
|
126
|
+
@orders = fields['orders'].map { |order_fields| Order.new(order_fields) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|