transloadit 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/.gitignore +3 -1
- data/.travis.yml +4 -4
- data/CHANGELOG.md +26 -0
- data/LICENSE +1 -1
- data/README.md +141 -16
- data/examples/README.md +185 -0
- data/examples/basic/audio-concat-transcoder.rb +40 -0
- data/examples/basic/audio-transcoder.rb +37 -0
- data/examples/basic/image-transcoder.rb +27 -0
- data/examples/basic/main.rb +69 -0
- data/examples/basic/media-transcoder.rb +13 -0
- data/lib/transloadit.rb +31 -0
- data/lib/transloadit/api_model.rb +73 -0
- data/lib/transloadit/assembly.rb +103 -63
- data/lib/transloadit/exception.rb +27 -0
- data/lib/transloadit/request.rb +23 -41
- data/lib/transloadit/response/assembly.rb +25 -0
- data/lib/transloadit/template.rb +63 -0
- data/lib/transloadit/version.rb +1 -1
- data/test/fixtures/cassettes/create_template.yml +48 -0
- data/test/fixtures/cassettes/delete_template.yml +44 -0
- data/test/fixtures/cassettes/fetch_assemblies.yml +44 -0
- data/test/fixtures/cassettes/fetch_assembly_notifications.yml +44 -0
- data/test/fixtures/cassettes/fetch_assembly_ok.yml +36 -0
- data/test/fixtures/cassettes/fetch_billing.yml +44 -0
- data/test/fixtures/cassettes/{fetch_bored.yml → fetch_root.yml} +6 -6
- data/test/fixtures/cassettes/fetch_template.yml +44 -0
- data/test/fixtures/cassettes/fetch_templates.yml +44 -0
- data/test/fixtures/cassettes/rate_limit_fail.yml +105 -0
- data/test/fixtures/cassettes/rate_limit_succeed.yml +79 -0
- data/test/fixtures/cassettes/replay_assembly.yml +49 -0
- data/test/fixtures/cassettes/replay_assembly_notification.yml +48 -0
- data/test/fixtures/cassettes/submit_assembly.yml +1 -36
- data/test/fixtures/cassettes/update_template.yml +48 -0
- data/test/test_helper.rb +4 -0
- data/test/unit/test_transloadit.rb +14 -1
- data/test/unit/transloadit/test_api.rb +50 -0
- data/test/unit/transloadit/test_assembly.rb +178 -47
- data/test/unit/transloadit/test_request.rb +28 -20
- data/test/unit/transloadit/test_response.rb +44 -0
- data/test/unit/transloadit/test_template.rb +118 -0
- data/transloadit.gemspec +3 -3
- metadata +70 -33
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'transloadit'
|
2
|
+
|
3
|
+
require 'rest-client'
|
4
|
+
|
5
|
+
module Transloadit::Exception
|
6
|
+
|
7
|
+
#
|
8
|
+
# Exception raised when Rate limit error response is returned from the API.
|
9
|
+
# See {Rate Limiting}[https://transloadit.com/docs/api-docs/#rate-limiting]
|
10
|
+
#
|
11
|
+
class RateLimitReached < RestClient::RequestEntityTooLarge
|
12
|
+
|
13
|
+
def default_message
|
14
|
+
retry_msg = " Retry in #{@response.wait_time} seconds" if @response
|
15
|
+
"Transloadit Rate Limit Reached.#{retry_msg}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Exception raised when Response#reload_until_finished! reaches limit specified in :tries option
|
21
|
+
#
|
22
|
+
class ReloadLimitReached < StandardError
|
23
|
+
def message
|
24
|
+
"reload_until_finished! reached limit specified in :tries option. This is not a rate limit and you may continue to poll for updates."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/transloadit/request.rb
CHANGED
@@ -13,7 +13,7 @@ class Transloadit::Request
|
|
13
13
|
API_ENDPOINT = URI.parse('http://api2.transloadit.com/')
|
14
14
|
|
15
15
|
# The default headers to send to the API.
|
16
|
-
API_HEADERS = { 'User-Agent' =>
|
16
|
+
API_HEADERS = { 'User-Agent' => "Transloadit Ruby SDK #{Transloadit::VERSION}" }
|
17
17
|
|
18
18
|
# The HMAC algorithm used for calculation request signatures.
|
19
19
|
HMAC_ALGORITHM = OpenSSL::Digest.new('sha1')
|
@@ -24,14 +24,6 @@ class Transloadit::Request
|
|
24
24
|
# @return [String] the authentication secret to sign the request with
|
25
25
|
attr_accessor :secret
|
26
26
|
|
27
|
-
#
|
28
|
-
# Automatically sets the API endpoint to the server with the most free
|
29
|
-
# resources. This is called automatically the first time a request is made.
|
30
|
-
#
|
31
|
-
def self.bored!
|
32
|
-
self.api self.bored
|
33
|
-
end
|
34
|
-
|
35
27
|
#
|
36
28
|
# Prepares a request against an endpoint URL, optionally with an encryption
|
37
29
|
# secret. If only a path is passed, the API will automatically determine the
|
@@ -60,15 +52,16 @@ class Transloadit::Request
|
|
60
52
|
end
|
61
53
|
|
62
54
|
#
|
63
|
-
# Performs an HTTP DELETE to the request's URL. Takes an optional hash
|
64
|
-
#
|
55
|
+
# Performs an HTTP DELETE to the request's URL. Takes an optional hash
|
56
|
+
# containing the form-encoded payload.
|
65
57
|
#
|
66
|
-
# @param [Hash]
|
58
|
+
# @param [Hash] payload the payload to form-encode along with the POST
|
67
59
|
# @return [Transloadit::Response] the response
|
68
60
|
#
|
69
|
-
def delete(
|
61
|
+
def delete(payload = {})
|
70
62
|
self.request! do
|
71
|
-
|
63
|
+
options = {:payload => self.to_payload(payload)}
|
64
|
+
self.api(options = options)[url.path].delete(API_HEADERS)
|
72
65
|
end
|
73
66
|
end
|
74
67
|
|
@@ -85,6 +78,19 @@ class Transloadit::Request
|
|
85
78
|
end
|
86
79
|
end
|
87
80
|
|
81
|
+
#
|
82
|
+
# Performs an HTTP PUT to the request's URL. Takes an optional hash
|
83
|
+
# containing the form-encoded payload.
|
84
|
+
#
|
85
|
+
# @param [Hash] payload the payload to form-encode along with the POST
|
86
|
+
# @return [Transloadit::Response] the response
|
87
|
+
#
|
88
|
+
def put(payload = {})
|
89
|
+
self.request! do
|
90
|
+
self.api[url.path].put(self.to_payload(payload), API_HEADERS)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
88
94
|
#
|
89
95
|
# @return [String] a human-readable version of the prepared Request
|
90
96
|
#
|
@@ -96,30 +102,6 @@ class Transloadit::Request
|
|
96
102
|
|
97
103
|
attr_writer :url
|
98
104
|
|
99
|
-
#
|
100
|
-
# Locates the API server with the smallest job queue.
|
101
|
-
#
|
102
|
-
# @return [String] the hostname of the most bored server
|
103
|
-
#
|
104
|
-
def self.bored
|
105
|
-
self.new(API_ENDPOINT + '/instances/bored').get['api2_host']
|
106
|
-
end
|
107
|
-
|
108
|
-
#
|
109
|
-
# Sets or retrieves the base URI of the API endpoint.
|
110
|
-
#
|
111
|
-
# @overload self.api
|
112
|
-
# @return [RestClient::Resource] the current API endpoint
|
113
|
-
#
|
114
|
-
# @overload self.api(uri)
|
115
|
-
# @param [String] the hostname or URI to set the API endpoint to
|
116
|
-
# @return [RestClient::Resource] the new API endpoint
|
117
|
-
#
|
118
|
-
def self.api(uri = nil)
|
119
|
-
@api = RestClient::Resource.new(uri) if uri
|
120
|
-
@api ||= RestClient::Resource.new(self.bored)
|
121
|
-
end
|
122
|
-
|
123
105
|
#
|
124
106
|
# Retrieves the current API endpoint. If the URL of the request contains a
|
125
107
|
# hostname, then the hostname is used as the base endpoint of the API.
|
@@ -127,11 +109,11 @@ class Transloadit::Request
|
|
127
109
|
#
|
128
110
|
# @return [RestClient::Resource] the API endpoint for this instance
|
129
111
|
#
|
130
|
-
def api
|
112
|
+
def api(options = {})
|
131
113
|
@api ||= begin
|
132
114
|
case self.url.host
|
133
|
-
when String then RestClient::Resource.new(self.url.host)
|
134
|
-
else
|
115
|
+
when String then RestClient::Resource.new(self.url.host, options = options)
|
116
|
+
else RestClient::Resource.new(API_ENDPOINT.host, options = options)
|
135
117
|
end
|
136
118
|
end
|
137
119
|
end
|
@@ -29,6 +29,10 @@ module Transloadit::Response::Assembly
|
|
29
29
|
self['ok'] == 'ASSEMBLY_EXECUTING'
|
30
30
|
end
|
31
31
|
|
32
|
+
def replaying?
|
33
|
+
self['ok'] == 'ASSEMBLY_REPLAYING'
|
34
|
+
end
|
35
|
+
|
32
36
|
def finished?
|
33
37
|
aborted? || canceled? || completed? || error?
|
34
38
|
end
|
@@ -36,4 +40,25 @@ module Transloadit::Response::Assembly
|
|
36
40
|
def uploading?
|
37
41
|
self['ok'] == 'ASSEMBLY_UPLOADING'
|
38
42
|
end
|
43
|
+
|
44
|
+
def rate_limit?
|
45
|
+
self['error'] == 'RATE_LIMIT_REACHED'
|
46
|
+
end
|
47
|
+
|
48
|
+
def wait_time
|
49
|
+
self['info']['retryIn'] || 0
|
50
|
+
end
|
51
|
+
|
52
|
+
DEFAULT_RELOAD_TRIES = 600
|
53
|
+
|
54
|
+
def reload_until_finished!(options = {})
|
55
|
+
tries = options[:tries] || DEFAULT_RELOAD_TRIES
|
56
|
+
|
57
|
+
tries.times do
|
58
|
+
sleep 1; reload!
|
59
|
+
return self if finished?
|
60
|
+
end
|
61
|
+
|
62
|
+
raise Transloadit::Exception::ReloadLimitReached
|
63
|
+
end
|
39
64
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'transloadit'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Represents a Template API ready to interact with its corresponding REST API.
|
5
|
+
#
|
6
|
+
# See the Transloadit {documentation}[https://transloadit.com/docs/api-docs/#template-api]
|
7
|
+
# for futher information on Templates and their parameters.
|
8
|
+
#
|
9
|
+
class Transloadit::Template < Transloadit::ApiModel
|
10
|
+
#
|
11
|
+
# Submits a template to be created.
|
12
|
+
#
|
13
|
+
# @param [Hash] params POST data to submit with the request.
|
14
|
+
# must contain keys 'name' and 'template'
|
15
|
+
#
|
16
|
+
# @option params [String] :name name assigned to the newly created template
|
17
|
+
# @option params [Hash] :template key, value pair of template content
|
18
|
+
# see {template}[https://transloadit.com/templates]
|
19
|
+
#
|
20
|
+
def create(params)
|
21
|
+
_do_request('/templates', params, 'post')
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Returns a list of all templates
|
26
|
+
# @param [Hash] additional GET data to submit with the request
|
27
|
+
#
|
28
|
+
def list(params = {})
|
29
|
+
_do_request('/templates', params)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Returns a single template object specified by the template id
|
34
|
+
# @param [String] id id of the desired template
|
35
|
+
# @param [Hash] additional GET data to submit with the request
|
36
|
+
#
|
37
|
+
def get(id, params = {})
|
38
|
+
_do_request("/templates/#{id}", params)
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Updates the template object specified by the template id
|
43
|
+
# @param [String] id id of the desired template
|
44
|
+
# @param [Hash] additional POST data to submit with the request
|
45
|
+
# must contain keys 'name' and 'template'
|
46
|
+
#
|
47
|
+
# @option params [String] :name name assigned to the newly created template
|
48
|
+
# @option params [Hash] :template key, value pair of template content
|
49
|
+
# see {template}[https://transloadit.com/templates]
|
50
|
+
#
|
51
|
+
def update(id, params = {})
|
52
|
+
_do_request("/templates/#{id}", params, 'put')
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Deletes the template object specified by the template id
|
57
|
+
# @param [String] id id of the desired template
|
58
|
+
# @param [Hash] additional POST data to submit with the request
|
59
|
+
#
|
60
|
+
def delete(id, params = {})
|
61
|
+
_do_request("/templates/#{id}", params, 'delete')
|
62
|
+
end
|
63
|
+
end
|
data/lib/transloadit/version.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: http://api2.transloadit.com/templates
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: params=%7B%22auth%22%3A%7B%22key%22%3A%22%22%7D%2C%22name%22%3A%22foo%22%2C%22template%22%3A%7B%22key%22%3A%22value%22%7D%7D
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Transloadit Ruby SDK 1.2.0
|
16
|
+
Content-Length:
|
17
|
+
- '124'
|
18
|
+
Content-Type:
|
19
|
+
- application/x-www-form-urlencoded
|
20
|
+
Host:
|
21
|
+
- api2.transloadit.com
|
22
|
+
response:
|
23
|
+
status:
|
24
|
+
code: 200
|
25
|
+
message: OK
|
26
|
+
headers:
|
27
|
+
Access-Control-Allow-Headers:
|
28
|
+
- X-Requested-With, Content-Type, Cache-Control, Accept, Content-Length
|
29
|
+
Access-Control-Allow-Methods:
|
30
|
+
- POST, GET, PUT, DELETE, OPTIONS
|
31
|
+
Access-Control-Allow-Origin:
|
32
|
+
- "*"
|
33
|
+
Cache-Control:
|
34
|
+
- no-cache
|
35
|
+
Content-Type:
|
36
|
+
- application/json; charset=utf-8
|
37
|
+
Date:
|
38
|
+
- Thu, 25 Aug 2016 10:13:30 GMT
|
39
|
+
Content-Length:
|
40
|
+
- '104'
|
41
|
+
Connection:
|
42
|
+
- keep-alive
|
43
|
+
body:
|
44
|
+
encoding: UTF-8
|
45
|
+
string: '{"ok":"TEMPLATE_CREATED","template_name":"foo","template_content": {"key": "value"}}'
|
46
|
+
http_version:
|
47
|
+
recorded_at: Thu, 25 Aug 2016 10:13:31 GMT
|
48
|
+
recorded_with: VCR 3.0.3
|
@@ -0,0 +1,44 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: delete
|
5
|
+
uri: http://api2.transloadit.com/templates/55c965a063a311e6ba2d379ef10b28f7
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Transloadit Ruby SDK 1.2.0
|
16
|
+
Host:
|
17
|
+
- api2.transloadit.com
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Access-Control-Allow-Headers:
|
24
|
+
- X-Requested-With, Content-Type, Cache-Control, Accept, Content-Length
|
25
|
+
Access-Control-Allow-Methods:
|
26
|
+
- POST, GET, PUT, DELETE, OPTIONS
|
27
|
+
Access-Control-Allow-Origin:
|
28
|
+
- "*"
|
29
|
+
Cache-Control:
|
30
|
+
- no-cache
|
31
|
+
Content-Type:
|
32
|
+
- application/json; charset=utf-8
|
33
|
+
Date:
|
34
|
+
- Wed, 24 Aug 2016 11:15:20 GMT
|
35
|
+
Content-Length:
|
36
|
+
- '65'
|
37
|
+
Connection:
|
38
|
+
- keep-alive
|
39
|
+
body:
|
40
|
+
encoding: UTF-8
|
41
|
+
string: '{"ok":"TEMPLATE_DELETED","message":"Your template was successfully deleted."}'
|
42
|
+
http_version:
|
43
|
+
recorded_at: Wed, 24 Aug 2016 11:15:19 GMT
|
44
|
+
recorded_with: VCR 3.0.3
|
@@ -0,0 +1,44 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://api2.transloadit.com/assemblies?params=%7B%22auth%22:%7B%22key%22:%22%22%7D%7D
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Transloadit Ruby SDK 1.2.0
|
16
|
+
Host:
|
17
|
+
- api2.transloadit.com
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Access-Control-Allow-Headers:
|
24
|
+
- X-Requested-With, Content-Type, Cache-Control, Accept, Content-Length
|
25
|
+
Access-Control-Allow-Methods:
|
26
|
+
- POST, GET, PUT, DELETE, OPTIONS
|
27
|
+
Access-Control-Allow-Origin:
|
28
|
+
- "*"
|
29
|
+
Cache-Control:
|
30
|
+
- no-cache
|
31
|
+
Content-Type:
|
32
|
+
- application/json; charset=utf-8
|
33
|
+
Date:
|
34
|
+
- Tue, 16 Aug 2016 09:09:24 GMT
|
35
|
+
Content-Length:
|
36
|
+
- '22'
|
37
|
+
Connection:
|
38
|
+
- keep-alive
|
39
|
+
body:
|
40
|
+
encoding: UTF-8
|
41
|
+
string: '{"items":[],"count":0}'
|
42
|
+
http_version:
|
43
|
+
recorded_at: Tue, 16 Aug 2016 09:09:24 GMT
|
44
|
+
recorded_with: VCR 3.0.3
|
@@ -0,0 +1,44 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://api2.transloadit.com/assembly_notifications?params=%7B%22auth%22:%7B%22key%22:%22%22%7D%7D
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Transloadit Ruby SDK 1.2.0
|
16
|
+
Host:
|
17
|
+
- api2.transloadit.com
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Access-Control-Allow-Headers:
|
24
|
+
- X-Requested-With, Content-Type, Cache-Control, Accept, Content-Length
|
25
|
+
Access-Control-Allow-Methods:
|
26
|
+
- POST, GET, PUT, DELETE, OPTIONS
|
27
|
+
Access-Control-Allow-Origin:
|
28
|
+
- "*"
|
29
|
+
Cache-Control:
|
30
|
+
- no-cache
|
31
|
+
Content-Type:
|
32
|
+
- application/json; charset=utf-8
|
33
|
+
Date:
|
34
|
+
- Tue, 16 Aug 2016 10:38:22 GMT
|
35
|
+
Content-Length:
|
36
|
+
- '22'
|
37
|
+
Connection:
|
38
|
+
- keep-alive
|
39
|
+
body:
|
40
|
+
encoding: UTF-8
|
41
|
+
string: '{"items":[],"count":0}'
|
42
|
+
http_version:
|
43
|
+
recorded_at: Tue, 16 Aug 2016 10:38:22 GMT
|
44
|
+
recorded_with: VCR 3.0.3
|
@@ -1,5 +1,41 @@
|
|
1
1
|
---
|
2
2
|
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://api2.transloadit.com/assemblies/76fe5df1c93a0a530f3e583805cf98b4
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- ! '*/*; q=0.5, application/xml'
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
response:
|
15
|
+
status:
|
16
|
+
code: 200
|
17
|
+
message: OK
|
18
|
+
headers:
|
19
|
+
Content-Type:
|
20
|
+
- text/plain
|
21
|
+
Access-Control-Allow-Origin:
|
22
|
+
- ! '*'
|
23
|
+
Access-Control-Allow-Methods:
|
24
|
+
- POST, GET, PUT, DELETE, OPTIONS
|
25
|
+
Access-Control-Allow-Headers:
|
26
|
+
- X-Requested-With, Content-Type, Accept, Content-Length
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
body:
|
30
|
+
encoding: UTF-8
|
31
|
+
string: ! '{"ok":"ASSEMBLY_COMPLETED","message":"The assembly was successfully
|
32
|
+
completed.","assembly_id":"76fe5df1c93a0a530f3e583805cf98b4","assembly_url":"http://api2.jane.transloadit.com/assemblies/76fe5df1c93a0a530f3e583805cf98b4","bytes_received":95355,"bytes_expected":95355,"client_agent":"Transloadit
|
33
|
+
Ruby SDK 0.1.2","client_ip":"74.95.29.209","client_referer":null,"start_date":"2011/02/21
|
34
|
+
15:54:17 GMT","upload_duration":0.394,"execution_duration":0.006,"fields":{},"uploads":[{"id":"0767b43537389a177a1be96ab06e8a4b","name":"test.png","basename":"test","ext":"png","size":95010,"mime":"image/jpeg","type":"image","field":"file_0","original_id":"0767b43537389a177a1be96ab06e8a4b","url":"http://tmp.jane.transloadit.com/upload/bf7801cb21fb96cbafd403467244d125.png","meta":{"width":640,"height":480,"date_recorded":null,"date_file_created":null,"date_file_modified":"2011/02/21
|
35
|
+
15:54:17 GMT","title":null,"description":null,"location":null,"city":null,"state":null,"country":null,"country_code":null,"keywords":"Photo
|
36
|
+
Booth","aperture":null,"exposure_compensation":null,"exposure_mode":null,"exposure_time":null,"flash":null,"focal_length":null,"f_number":null,"iso":null,"light_value":null,"metering_mode":null,"shutter_speed":null,"white_balance":null,"device_name":null,"device_vendor":null,"device_software":null,"latitude":null,"longitude":null,"frame_count":null}}],"results":{}}'
|
37
|
+
http_version: '1.1'
|
38
|
+
recorded_at: Fri, 08 Mar 2013 15:13:10 GMT
|
3
39
|
- request:
|
4
40
|
method: get
|
5
41
|
uri: http://api2.jane.transloadit.com/assemblies/76fe5df1c93a0a530f3e583805cf98b4
|