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.
Files changed (44) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +3 -1
  3. data/.travis.yml +4 -4
  4. data/CHANGELOG.md +26 -0
  5. data/LICENSE +1 -1
  6. data/README.md +141 -16
  7. data/examples/README.md +185 -0
  8. data/examples/basic/audio-concat-transcoder.rb +40 -0
  9. data/examples/basic/audio-transcoder.rb +37 -0
  10. data/examples/basic/image-transcoder.rb +27 -0
  11. data/examples/basic/main.rb +69 -0
  12. data/examples/basic/media-transcoder.rb +13 -0
  13. data/lib/transloadit.rb +31 -0
  14. data/lib/transloadit/api_model.rb +73 -0
  15. data/lib/transloadit/assembly.rb +103 -63
  16. data/lib/transloadit/exception.rb +27 -0
  17. data/lib/transloadit/request.rb +23 -41
  18. data/lib/transloadit/response/assembly.rb +25 -0
  19. data/lib/transloadit/template.rb +63 -0
  20. data/lib/transloadit/version.rb +1 -1
  21. data/test/fixtures/cassettes/create_template.yml +48 -0
  22. data/test/fixtures/cassettes/delete_template.yml +44 -0
  23. data/test/fixtures/cassettes/fetch_assemblies.yml +44 -0
  24. data/test/fixtures/cassettes/fetch_assembly_notifications.yml +44 -0
  25. data/test/fixtures/cassettes/fetch_assembly_ok.yml +36 -0
  26. data/test/fixtures/cassettes/fetch_billing.yml +44 -0
  27. data/test/fixtures/cassettes/{fetch_bored.yml → fetch_root.yml} +6 -6
  28. data/test/fixtures/cassettes/fetch_template.yml +44 -0
  29. data/test/fixtures/cassettes/fetch_templates.yml +44 -0
  30. data/test/fixtures/cassettes/rate_limit_fail.yml +105 -0
  31. data/test/fixtures/cassettes/rate_limit_succeed.yml +79 -0
  32. data/test/fixtures/cassettes/replay_assembly.yml +49 -0
  33. data/test/fixtures/cassettes/replay_assembly_notification.yml +48 -0
  34. data/test/fixtures/cassettes/submit_assembly.yml +1 -36
  35. data/test/fixtures/cassettes/update_template.yml +48 -0
  36. data/test/test_helper.rb +4 -0
  37. data/test/unit/test_transloadit.rb +14 -1
  38. data/test/unit/transloadit/test_api.rb +50 -0
  39. data/test/unit/transloadit/test_assembly.rb +178 -47
  40. data/test/unit/transloadit/test_request.rb +28 -20
  41. data/test/unit/transloadit/test_response.rb +44 -0
  42. data/test/unit/transloadit/test_template.rb +118 -0
  43. data/transloadit.gemspec +3 -3
  44. 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
@@ -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' => %{Transloadit Ruby SDK #{Transloadit::VERSION}} }
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 of
64
- # query params.
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] params additional query parameters
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(params = {})
61
+ def delete(payload = {})
70
62
  self.request! do
71
- self.api[url.path + self.to_query(params)].delete(API_HEADERS)
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 self.class.api
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
@@ -1,3 +1,3 @@
1
1
  class Transloadit
2
- VERSION = '1.2.0'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -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