filestack 2.6.3 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 782df68e180640baf40fd8f51c596fc40849eb6d
4
- data.tar.gz: 4817fda90f5dd4bba20696bac89facf9c70004ee
2
+ SHA256:
3
+ metadata.gz: 36cd3251f64e64ffcdb9d42c73cbf6d49bcda8a2533cb8053e0087229a077bf2
4
+ data.tar.gz: f2e38e698557c0b336c332be5b68775fe2624e046a56e1c521717554f23b6495
5
5
  SHA512:
6
- metadata.gz: 0a2d6741c4a14cc85c1fc07f9557fba4d07b962d34757941fb09dfd4925f2cab89abfc11529e558eef1d02400c9b97fa27b2593c4b76b24a935edc6eac98fb49
7
- data.tar.gz: 5a429781202688ceddcda90e2d44d9bca1db1189e9354400e71276cd7ae8a48ecd813d6e46321835fdffd905f4b105631b55eb582a9f5684788df0d528aa25a7
6
+ metadata.gz: 26a1b21b1ad69ae42708e94323e28d7656881824e668677b0dc27a4bb13a035ed6f5b104f90615a0e53bf3b454621fa3a3e129a6a412eed15dd7271f33100f84
7
+ data.tar.gz: 4d2c6c3e96da48df28e067f6990e3313669ffb2cf0f33f62964db5f708b42b0818c9992cec713c0b70acc6db72425bb727545726a1757c9c64c9dc7addcf6090
@@ -1,5 +1,20 @@
1
1
  # Filestack-Ruby Changelog
2
2
 
3
+ ## 2.7.0 (September 28, 2020)
4
+ - Add workflows
5
+
6
+ ## 2.6.7 (August 4, 2020)
7
+ - Add content disposition task
8
+
9
+ ## 2.6.6 (June 19, 2020)
10
+ - Add compress task to transformations
11
+
12
+ ## 2.6.5 (January 9, 2020)
13
+ - Updated version of the parallel gem
14
+
15
+ ## 2.6.4 (November 4, 2019)
16
+ - Fix issue with file upload
17
+
3
18
  ## 2.6.3 (August 12, 2019)
4
19
  - Add animate to transformations
5
20
 
data/README.md CHANGED
@@ -44,41 +44,50 @@ Or install it yourself as:
44
44
  require 'filestack'
45
45
  ```
46
46
  Intialize the client using your API key, and security if you are using it.
47
+
47
48
  ```ruby
48
49
  client = FilestackClient.new('YOUR_API_KEY', security: security_object)
49
50
  ```
50
51
  ### Uploading
51
- Filestack uses multipart uploading by default, which is faster for larger files. This can be turned off by passing in ```multipart: false```. Multipart is disabled when uploading external URLs.
52
52
  ```ruby
53
- filelink = client.upload(filepath: '/path/to/file')
54
-
55
- filelink = client.upload(filepath: '/path/to/file', multipart: false)
53
+ filelink = client.upload(filepath: '/path/to/localfile')
56
54
 
57
55
  # OR
58
56
 
59
- filelink = client.upload(external_url: 'http://someurl.com')
57
+ filelink = client.upload(external_url: 'http://domain.com/image.png')
60
58
  ```
61
59
 
62
60
  To upload a local and an external file with query parameters:
63
61
  ```ruby
64
- filelink = client.upload(filepath: '/path/to/file', options: {mimetype: 'image/png'})
62
+ filelink = client.upload(filepath: '/path/to/localfile', options: { mimetype: 'image/png' })
65
63
 
66
- filelink = client.upload(external_url: 'http://someurl.com/image.png', options: {mimetype: 'image/jpeg'})
64
+ filelink = client.upload(external_url: 'http://domain.com/image.png', options: { mimetype: 'image/jpeg' })
67
65
  ```
68
66
 
69
67
  To store file on `dropbox`, `azure`, `gcs` or `rackspace`, you must have the chosen provider configured in the developer portal to enable this feature. By default the file is stored on `s3`. You can add more details of the storage in `options`.
70
68
 
71
69
  ```ruby
72
- filelink = client.upload(filepath: '/path/to/file', storage: 'dropbox', options: {path: 'folder_name/'})
70
+ filelink = client.upload(filepath: '/path/to/file', storage: 's3', options: { path: 'folder_name/', container: 'container_name', location: 's3', region: 'region_name' })
71
+
72
+ filelink = client.upload(external_url: 'http://someurl.com/image.png', options: { location: 'dropbox', path: 'folder_name' })
73
+ ```
74
+
75
+ ### Workflows
76
+ Workflows allow you to wire up conditional logic and image processing to enforce business processes, automate ingest, and save valuable development time. In order to trigger the workflow job for each upload:
77
+
78
+ ```ruby
79
+ filelink = client.upload(filepath: '/path/to/file', options: { workflows: ["workflow_id_1", "workflow_id_2"] })
80
+
81
+ #OR
73
82
 
74
- filelink = client.upload(external_url: 'http://someurl.com/image.png', storage: 'dropbox', options: {path: 'folder_name/'})
83
+ filelink = client.upload(external_url: 'http://someurl.com/image.png', options: { workflows: ["workflow_id_1"] })
75
84
  ```
76
85
 
77
86
  ### Security
78
87
  If security is enabled on your account, or if you are using certain actions that require security (delete, overwrite and certain transformations), you will need to create a security object and pass it into the client on instantiation.
79
88
 
80
89
  ```ruby
81
- security = FilestackSecurity.new('YOUR_APP_SECRET', options: {call: %w[read store pick]})
90
+ security = FilestackSecurity.new('YOUR_APP_SECRET', options: {call: %w[read store pick runWorkflow]})
82
91
  client = FilestackClient.new('YOUR_API_KEY', security: security)
83
92
  ```
84
93
 
@@ -123,13 +132,20 @@ Return `default` file if the source of the transformation does not work or the t
123
132
  To use fallback, you should provide `handle` of the file that should be returned. Optionally, you can add `cache`, which means number of seconds fallback response should be cached in CDN.
124
133
 
125
134
  ```ruby
126
- transform = client.transform_external('https://someurl.com').fallback(handle: 'DEFAULT_HANDLE')
135
+ transform = client.transform_external('https://someurl.com/file.png').fallback(file: 'DEFAULT_HANDLE_OR_FILEPATH')
127
136
  ```
128
137
 
129
138
  If you are using fallback handle that belongs to different application than the one which runs transformation (APIKEY) and it is secured with security policy, appropriate signature and policy with read call should be used:
130
139
 
131
140
  ```ruby
132
- transform = client.transform_external('https://someurl.com').fallback(handle: 'DEFAULT_HANDLE?policy=HANDLE_APIKEY_POLICY&signature=HANDLE_APIKEY_SIGNATURE', cache: 10)
141
+ transform = client.transform_external('https://someurl.com/file.png').fallback(file: 'DEFAULT_HANDLE_OR_FILEPATH?policy=HANDLE_APIKEY_POLICY&signature=HANDLE_APIKEY_SIGNATURE', cache: 10)
142
+ ```
143
+
144
+ ### Content
145
+ Sets `Content-Disposition` header for given file.
146
+
147
+ ```ruby
148
+ transform = filelink.transform.content(filename: 'DEFAULT_FILENAME', type: 'TYPE')
133
149
  ```
134
150
 
135
151
  ### Tagging
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.6.3
1
+ 2.7.0
@@ -114,7 +114,8 @@
114
114
  </span><span class='tstring_content'> partial_pixelate</span><span class='words_sep'> </span><span class='tstring_content'>partial_blur</span><span class='words_sep'> </span><span class='tstring_content'>collage</span><span class='words_sep'> </span><span class='tstring_content'>upscale</span><span class='words_sep'> </span><span class='tstring_content'>enhance</span><span class='words_sep'>
115
115
  </span><span class='tstring_content'> redeye</span><span class='words_sep'> </span><span class='tstring_content'>ascii</span><span class='words_sep'> </span><span class='tstring_content'>filetype_conversion</span><span class='words_sep'> </span><span class='tstring_content'>quality</span><span class='words_sep'> </span><span class='tstring_content'>urlscreenshot</span><span class='words_sep'>
116
116
  </span><span class='tstring_content'> no_metadata</span><span class='words_sep'></span><span class='tstring_content'> fallback</span><span class='words_sep'></span><span class='tstring_content'> pdfinfo</span><span class='words_sep'></span><span class='tstring_content'> pdfconvert</span><span class='words_sep'></span><span class='tstring_content'> cache</span><span class='words_sep'></span><span class='tstring_content'> auto_image</span><span class='words_sep'>
117
- </span><span class='tstring_content'> minify_js</span><span class='words_sep'></span><span class='tstring_content'> minify_css</span><span class='words_sep'></span><span class='tstring_content'> animate</span><span class='words_sep'></span>
117
+ </span><span class='tstring_content'> minify_js</span><span class='words_sep'></span><span class='tstring_content'> minify_css</span><span class='words_sep'></span><span class='tstring_content'> animate</span><span class='words_sep'></span><span class='tstring_content'> video_convert</span><span class='words_sep'></span><span class='tstring_content'> video_playlist</span><span class='words_sep'>
118
+ </span><span class='tstring_content'> compress</span><span class='words_sep'></span><span class='tstring_content'> content</span><span class='words_sep'></span>
118
119
  <span class='tstring_end'>]</span></span><span class='period'>.</span><span class='id identifier rubyid_freeze'>freeze</span></pre></dd>
119
120
 
120
121
  </dl>
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_dependency "typhoeus", "~> 1.1"
26
- spec.add_dependency "parallel", "~> 1.11.2"
26
+ spec.add_dependency "parallel", "~> 1.11", ">= 1.11.2"
27
27
  spec.add_dependency "mimemagic", "~> 0.3.2"
28
28
  spec.add_dependency "progress_bar"
29
29
 
@@ -7,11 +7,6 @@ class FilestackConfig
7
7
  CDN_URL = 'https://cdn.filestackcontent.com'.freeze
8
8
  PROCESS_URL = 'https://process.filestackapi.com'.freeze
9
9
 
10
- MULTIPART_START_URL = 'https://upload.filestackapi.com/multipart/start'.freeze
11
- MULTIPART_UPLOAD_URL = 'https://upload.filestackapi.com/multipart/upload'.freeze
12
- MULTIPART_COMMIT_URL = 'https://upload.filestackapi.com/multipart/commit'.freeze
13
- MULTIPART_COMPLETE_URL = 'https://upload.filestackapi.com/multipart/complete'.freeze
14
-
15
10
  MULTIPART_PARAMS = %w[
16
11
  store_location store_region store_container
17
12
  store_path store_access
@@ -22,10 +17,28 @@ class FilestackConfig
22
17
  VERSION = Filestack::Ruby::VERSION
23
18
  HEADERS = {
24
19
  'User-Agent' => "filestack-ruby #{VERSION}",
25
- 'Filestack-Source' => "Ruby-#{VERSION}"
20
+ 'Filestack-Source' => "Ruby-#{VERSION}",
21
+ 'Content-Type' => "application/json",
22
+ 'Accept-Encoding' => "application/json"
26
23
  }.freeze
27
24
 
28
25
  INTELLIGENT_ERROR_MESSAGES = ['BACKEND_SERVER', 'BACKEND_NETWORK', 'S3_SERVER', 'S3_NETWORK']
26
+
27
+ def self.multipart_start_url
28
+ "https://upload.filestackapi.com/multipart/start"
29
+ end
30
+
31
+ def self.multipart_upload_url(base_url)
32
+ "https://#{base_url}/multipart/upload"
33
+ end
34
+
35
+ def self.multipart_commit_url(base_url)
36
+ "https://#{base_url}/multipart/commit"
37
+ end
38
+
39
+ def self.multipart_complete_url(base_url)
40
+ "https://#{base_url}/multipart/complete"
41
+ end
29
42
  end
30
43
 
31
44
  class TransformConfig
@@ -37,6 +50,7 @@ class TransformConfig
37
50
  partial_pixelate partial_blur collage upscale enhance
38
51
  redeye ascii filetype_conversion quality urlscreenshot
39
52
  no_metadata fallback pdfinfo pdfconvert cache auto_image
40
- minify_js minify_css animate
53
+ minify_js minify_css animate video_convert video_playlist
54
+ compress content
41
55
  ].freeze
42
56
  end
@@ -26,26 +26,19 @@ class FilestackClient
26
26
  # Upload a local file or external url
27
27
  # @param [String] filepath The path of a local file
28
28
  # @param [String] external_url An external URL
29
- # @param [Bool] multipart Switch for miltipart
30
- # (Default: true)
31
29
  # @param [Hash] options User-supplied upload options
32
30
  #
33
31
  # return [Filestack::FilestackFilelink]
34
- def upload(filepath: nil, external_url: nil, multipart: true, options: {}, storage: 's3', intelligent: false, timeout: 60)
35
- if filepath && external_url
36
- return 'You cannot upload a URL and file at the same time'
37
- end
38
- response = if filepath && multipart
32
+ def upload(filepath: nil, external_url: nil, options: {}, intelligent: false, timeout: 60, storage: 'S3')
33
+ return 'You cannot upload a URL and file at the same time' if filepath && external_url
34
+
35
+ response = if filepath
39
36
  multipart_upload(@apikey, filepath, @security, options, timeout, storage, intelligent: intelligent)
40
37
  else
41
- send_upload(
42
- @apikey,
43
- filepath: filepath,
44
- external_url: external_url,
45
- options: options,
46
- security: @security,
47
- storage: storage
48
- )
38
+ send_upload(@apikey,
39
+ external_url: external_url,
40
+ options: options,
41
+ security: @security)
49
42
  end
50
43
  FilestackFilelink.new(response['handle'], security: @security, apikey: @apikey)
51
44
  end
@@ -1,5 +1,5 @@
1
1
  module Filestack
2
2
  module Ruby
3
- VERSION = '2.6.3'.freeze
3
+ VERSION = '2.7.0'.freeze
4
4
  end
5
5
  end
@@ -23,16 +23,6 @@ module MultipartUploadUtils
23
23
  [filename, filesize, mimetype.to_s]
24
24
  end
25
25
 
26
- def multipart_options(options)
27
- [:region, :container, :path, :access].each do |key|
28
- if options.has_key?(key)
29
- options[:"store_#{key}"] = options[key]
30
- options.delete(key)
31
- end
32
- end
33
- return options
34
- end
35
-
36
26
  # Send start response to multipart endpoint
37
27
  #
38
28
  # @param [String] apikey Filestack API key
@@ -45,28 +35,27 @@ module MultipartUploadUtils
45
35
  # multipart uploads
46
36
  #
47
37
  # @return [Typhoeus::Response]
48
- def multipart_start(apikey, filename, filesize, mimetype, security, storage, options = {})
38
+ def multipart_start(apikey, filename, filesize, mimetype, security, storage, options = {}, intelligent)
49
39
  params = {
50
40
  apikey: apikey,
51
41
  filename: filename,
52
42
  mimetype: mimetype,
53
43
  size: filesize,
54
- store_location: storage,
55
- file: Tempfile.new(filename),
56
- 'multipart' => 'true'
44
+ store: { location: storage },
45
+ fii: intelligent
57
46
  }
58
- options = multipart_options(options)
59
- params = params.merge!(options) if options
47
+
48
+ params[:store].merge!(options) if options
60
49
 
61
50
  unless security.nil?
62
51
  params[:policy] = security.policy
63
52
  params[:signature] = security.signature
64
53
  end
65
54
 
66
- response = Typhoeus.post(
67
- FilestackConfig::MULTIPART_START_URL, body: params,
68
- headers: FilestackConfig::HEADERS
69
- )
55
+ response = Typhoeus.post(FilestackConfig.multipart_start_url,
56
+ body: params.to_json,
57
+ headers: FilestackConfig::HEADERS)
58
+
70
59
  if response.code == 200
71
60
  JSON.parse(response.body)
72
61
  else
@@ -92,7 +81,7 @@ module MultipartUploadUtils
92
81
  seek_point = 0
93
82
  while seek_point < filesize
94
83
  part_info = {
95
- seek: seek_point,
84
+ seek_point: seek_point,
96
85
  filepath: filepath,
97
86
  filename: filename,
98
87
  apikey: apikey,
@@ -103,10 +92,10 @@ module MultipartUploadUtils
103
92
  upload_id: start_response['upload_id'],
104
93
  location_url: start_response['location_url'],
105
94
  start_response: start_response,
106
- store_location: storage
95
+ store: { location: storage }
107
96
  }
108
- options = multipart_options(options)
109
- part_info = part_info.merge!(options) if options
97
+
98
+ part_info[:store].merge!(options) if options
110
99
 
111
100
  if seek_point + FilestackConfig::DEFAULT_CHUNK_SIZE > filesize
112
101
  size = filesize - (seek_point)
@@ -134,9 +123,9 @@ module MultipartUploadUtils
134
123
  # multipart uploads
135
124
  #
136
125
  # @return [Typhoeus::Response]
137
- def upload_chunk(job, apikey, filepath, options)
126
+ def upload_chunk(job, apikey, filepath, options, storage)
138
127
  file = File.open(filepath)
139
- file.seek(job[:seek])
128
+ file.seek(job[:seek_point])
140
129
  chunk = file.read(FilestackConfig::DEFAULT_CHUNK_SIZE)
141
130
 
142
131
  md5 = Digest::MD5.new
@@ -149,14 +138,14 @@ module MultipartUploadUtils
149
138
  uri: job[:uri],
150
139
  region: job[:region],
151
140
  upload_id: job[:upload_id],
152
- store_location: job[:store_location],
141
+ store: { location: storage },
153
142
  file: Tempfile.new(job[:filename])
154
143
  }
155
144
  data = data.merge!(options) if options
156
- fs_response = Typhoeus.post(
157
- FilestackConfig::MULTIPART_UPLOAD_URL, body: data,
158
- headers: FilestackConfig::HEADERS
159
- ).body
145
+
146
+ fs_response = Typhoeus.post(FilestackConfig.multipart_upload_url(job[:location_url]),
147
+ body: data.to_json,
148
+ headers: FilestackConfig::HEADERS).body
160
149
  fs_response = JSON.parse(fs_response)
161
150
  Typhoeus.put(
162
151
  fs_response['url'], headers: fs_response['headers'], body: chunk
@@ -171,17 +160,17 @@ module MultipartUploadUtils
171
160
  # multipart uploads
172
161
  #
173
162
  # @return [Array] Array of parts/etags strings
174
- def run_uploads(jobs, apikey, filepath, options)
163
+ def run_uploads(jobs, apikey, filepath, options, storage)
175
164
  bar = ProgressBar.new(jobs.length)
176
165
  results = Parallel.map(jobs, in_threads: 4) do |job|
177
166
  response = upload_chunk(
178
- job, apikey, filepath, options
167
+ job, apikey, filepath, options, storage
179
168
  )
180
169
  if response.code == 200
181
170
  bar.increment!
182
171
  part = job[:part]
183
172
  etag = response.headers[:etag]
184
- "#{part}:#{etag}"
173
+ { part_number: part, etag: etag }
185
174
  end
186
175
  end
187
176
  results
@@ -204,40 +193,22 @@ module MultipartUploadUtils
204
193
  #
205
194
  # @return [Typhoeus::Response]
206
195
  def multipart_complete(apikey, filename, filesize, mimetype, start_response, parts_and_etags, options, storage, intelligent = false)
207
- if !intelligent
208
- data = {
209
- apikey: apikey,
210
- uri: start_response['uri'],
211
- region: start_response['region'],
212
- upload_id: start_response['upload_id'],
213
- filename: filename,
214
- size: filesize,
215
- mimetype: mimetype,
216
- parts: parts_and_etags.join(';'),
217
- store_location: storage,
218
- file: Tempfile.new(filename)
219
- }
220
- else
221
- data = {
222
- apikey: apikey,
223
- uri: start_response['uri'],
224
- region: start_response['region'],
225
- upload_id: start_response['upload_id'],
226
- filename: filename,
227
- size: filesize,
228
- mimetype: mimetype,
229
- store_location: storage,
230
- file: Tempfile.new(filename),
231
- 'multipart' => 'true'
232
- }
233
- end
234
- options = multipart_options(options)
235
- data = data.merge!(options) if options
196
+ data = {
197
+ apikey: apikey,
198
+ uri: start_response['uri'],
199
+ region: start_response['region'],
200
+ upload_id: start_response['upload_id'],
201
+ filename: filename,
202
+ size: filesize,
203
+ mimetype: mimetype,
204
+ store: { location: storage },
205
+ }
206
+ data[:store].merge!(options) if options
207
+ data.merge!(intelligent ? { fii: intelligent } : { parts: parts_and_etags })
236
208
 
237
- Typhoeus.post(
238
- FilestackConfig::MULTIPART_COMPLETE_URL, body: data,
239
- headers: FilestackConfig::HEADERS
240
- )
209
+ Typhoeus.post(FilestackConfig.multipart_complete_url(start_response['location_url']),
210
+ body: data.to_json,
211
+ headers: FilestackConfig::HEADERS)
241
212
  end
242
213
 
243
214
  # Run entire multipart process through with file and options
@@ -252,27 +223,24 @@ module MultipartUploadUtils
252
223
  # @return [Hash]
253
224
  def multipart_upload(apikey, filepath, security, options, timeout, storage, intelligent: false)
254
225
  filename, filesize, mimetype = get_file_info(filepath)
226
+
255
227
  start_response = multipart_start(
256
- apikey, filename, filesize, mimetype, security, storage, options
228
+ apikey, filename, filesize, mimetype, security, storage, options, intelligent
257
229
  )
258
230
 
259
- unless start_response['upload_type'].nil?
260
- intelligent_enabled = ((start_response['upload_type'].include? 'intelligent_ingestion')) && intelligent
261
- end
262
-
263
231
  jobs = create_upload_jobs(
264
232
  apikey, filename, filepath, filesize, start_response, storage, options
265
233
  )
266
234
 
267
- if intelligent_enabled
235
+ if intelligent
268
236
  state = IntelligentState.new
269
- run_intelligent_upload_flow(jobs, state)
237
+ run_intelligent_upload_flow(jobs, state, storage)
270
238
  response_complete = multipart_complete(
271
239
  apikey, filename, filesize, mimetype,
272
240
  start_response, nil, options, storage, intelligent
273
241
  )
274
242
  else
275
- parts_and_etags = run_uploads(jobs, apikey, filepath, options)
243
+ parts_and_etags = run_uploads(jobs, apikey, filepath, options, storage)
276
244
  response_complete = multipart_complete(
277
245
  apikey, filename, filesize, mimetype,
278
246
  start_response, parts_and_etags, options, storage
@@ -62,36 +62,43 @@ module UploadUtils
62
62
  )
63
63
  end
64
64
 
65
+ def build_store_task(options = {})
66
+ return 'store' if options.empty?
67
+ tasks = []
68
+ options.each do |key, value|
69
+ value = case key
70
+ when :workflows
71
+ [value.join('","')]
72
+ when :path
73
+ "\"#{value}\""
74
+ else
75
+ value
76
+ end
77
+ tasks.push("#{key}:#{value.to_s.downcase}")
78
+ end
79
+ "store=#{tasks.join(',')}"
80
+ end
81
+
65
82
  # Uploads to v1 REST API (for external URLs or if multipart is turned off)
66
83
  #
67
84
  # @param [String] apikey Filestack API key
68
- # @param [String] filepath Local path to file
69
85
  # @param [String] external_url External URL to be uploaded
70
86
  # @param [FilestackSecurity] security Security object with
71
87
  # policy/signature
72
88
  # @param [Hash] options User-defined options for
73
89
  # multipart uploads
74
- # @param [String] storage Storage destination
75
- # (s3, rackspace, etc)
76
90
  # @return [Hash]
77
- def send_upload(apikey, filepath: nil, external_url: nil, security: nil, options: nil, storage: 'S3')
78
- data = if filepath
79
- { fileUpload: File.open(filepath) }
80
- else
81
- { url: external_url }
82
- end
83
-
84
- # adds any user-defined upload options to request payload
85
- data = data.merge!(options) unless options.nil?
86
- base = "#{FilestackConfig::API_URL}/store/#{storage}?key=#{apikey}"
91
+ def send_upload(apikey, external_url: nil, security: nil, options: nil)
92
+ base = "#{FilestackConfig::CDN_URL}/#{apikey}/#{build_store_task(options)}"
87
93
 
88
94
  if security
89
95
  policy = security.policy
90
96
  signature = security.signature
91
- base = "#{base}&signature=#{signature}&policy=#{policy}"
97
+ base = "#{base}/security=s:#{signature},p:#{policy}"
92
98
  end
93
99
 
94
- response = make_call(base, 'post', parameters: data)
100
+ response = Typhoeus.post("#{base}/#{external_url}", headers: FilestackConfig::HEADERS)
101
+
95
102
  if response.code == 200
96
103
  response_body = JSON.parse(response.body)
97
104
  handle = response_body['url'].split('/').last
@@ -192,7 +199,7 @@ module IntelligentUtils
192
199
  # @param [IntelligentState] state An IntelligentState object
193
200
  #
194
201
  # @return [Array]
195
- def run_intelligent_upload_flow(jobs, state)
202
+ def run_intelligent_upload_flow(jobs, state, storage)
196
203
  bar = ProgressBar.new(jobs.length)
197
204
  generator = create_intelligent_generator(jobs)
198
205
  working_offset = FilestackConfig::DEFAULT_OFFSET_SIZE
@@ -200,7 +207,7 @@ module IntelligentUtils
200
207
  batch = get_generator_batch(generator)
201
208
  # run parts
202
209
  Parallel.map(batch, in_threads: 4) do |part|
203
- state = run_intelligent_uploads(part, state)
210
+ state = run_intelligent_uploads(part, state, storage)
204
211
  # condition: a chunk has failed but we have not reached the maximum retries
205
212
  while bad_state(state)
206
213
  # condition: timeout to S3, requiring offset size to be changed
@@ -212,7 +219,7 @@ module IntelligentUtils
212
219
  sleep(state.backoff)
213
220
  end
214
221
  state.add_retry
215
- state = run_intelligent_uploads(part, state)
222
+ state = run_intelligent_uploads(part, state, storage)
216
223
  end
217
224
  raise "Upload has failed. Please try again later." unless state.ok
218
225
  bar.increment!
@@ -268,13 +275,14 @@ module IntelligentUtils
268
275
  # multipart_start
269
276
  #
270
277
  # @return [Dict]
271
- def chunk_job(job, state, apikey, filename, filepath, filesize, start_response)
278
+ def chunk_job(job, state, apikey, filename, filepath, filesize, start_response, storage)
272
279
  offset = 0
273
- seek_point = job[:seek]
280
+ seek_point = job[:seek_point]
274
281
  chunk_list = []
282
+
275
283
  while (offset < FilestackConfig::DEFAULT_CHUNK_SIZE) && (seek_point + offset) < filesize
276
284
  chunk_list.push(
277
- seek: seek_point,
285
+ seek_point: seek_point,
278
286
  filepath: filepath,
279
287
  filename: filename,
280
288
  apikey: apikey,
@@ -284,7 +292,7 @@ module IntelligentUtils
284
292
  region: start_response['region'],
285
293
  upload_id: start_response['upload_id'],
286
294
  location_url: start_response['location_url'],
287
- store_location: job[:store_location],
295
+ store: { location: storage },
288
296
  offset: offset
289
297
  )
290
298
  offset += state.offset
@@ -299,15 +307,15 @@ module IntelligentUtils
299
307
  # @param [IntelligentState] state An IntelligentState object
300
308
  #
301
309
  # @return [IntelligentState]
302
- def run_intelligent_uploads(part, state)
310
+ def run_intelligent_uploads(part, state, storage)
303
311
  failed = false
304
312
  chunks = chunk_job(
305
313
  part, state, part[:apikey], part[:filename], part[:filepath],
306
- part[:filesize], part[:start_response]
314
+ part[:filesize], part[:start_response], storage
307
315
  )
308
316
  Parallel.map(chunks, in_threads: 3) do |chunk|
309
317
  begin
310
- upload_chunk_intelligently(chunk, state, part[:apikey], part[:filepath], part[:options])
318
+ upload_chunk_intelligently(chunk, state, part[:apikey], part[:filepath], part[:options], storage)
311
319
  rescue => e
312
320
  state.error_type = e.message
313
321
  failed = true
@@ -321,6 +329,7 @@ module IntelligentUtils
321
329
  else
322
330
  state.ok = true
323
331
  end
332
+
324
333
  commit_params = {
325
334
  apikey: part[:apikey],
326
335
  uri: part[:uri],
@@ -328,12 +337,14 @@ module IntelligentUtils
328
337
  upload_id: part[:upload_id],
329
338
  size: part[:filesize],
330
339
  part: part[:part],
331
- location_url: part[:location_url],
332
- store_location: part[:store_location],
333
- file: Tempfile.new(part[:filename])
340
+ location_url: part[:start_response]['location_url'],
341
+ store: { location: storage }
334
342
  }
335
- response = Typhoeus.post(FilestackConfig::MULTIPART_COMMIT_URL, body: commit_params,
336
- headers: FilestackConfig::HEADERS)
343
+
344
+ response = Typhoeus.post(FilestackConfig.multipart_commit_url(commit_params[:location_url]),
345
+ body: commit_params.to_json,
346
+ headers: FilestackConfig::HEADERS)
347
+
337
348
  if response.code == 200
338
349
  state.reset
339
350
  else
@@ -353,9 +364,10 @@ module IntelligentUtils
353
364
  # multipart uploads
354
365
  #
355
366
  # @return [Typhoeus::Response]
356
- def upload_chunk_intelligently(job, state, apikey, filepath, options)
367
+ def upload_chunk_intelligently(job, state, apikey, filepath, options, storage)
357
368
  file = File.open(filepath)
358
- file.seek(job[:seek] + job[:offset])
369
+ file.seek(job[:seek_point] + job[:offset])
370
+
359
371
  chunk = file.read(state.offset)
360
372
  md5 = Digest::MD5.new
361
373
  md5 << chunk
@@ -367,17 +379,17 @@ module IntelligentUtils
367
379
  uri: job[:uri],
368
380
  region: job[:region],
369
381
  upload_id: job[:upload_id],
370
- store_location: job[:store_location],
382
+ store: { location: storage },
371
383
  offset: job[:offset],
372
- file: Tempfile.new(job[:filename]),
373
- 'multipart' => 'true'
384
+ fii: true
374
385
  }
375
386
 
376
387
  data = data.merge!(options) if options
377
- fs_response = Typhoeus.post(
378
- FilestackConfig::MULTIPART_UPLOAD_URL, body: data,
379
- headers: FilestackConfig::HEADERS
380
- )
388
+
389
+ fs_response = Typhoeus.post(FilestackConfig.multipart_upload_url(job[:location_url]),
390
+ body: data.to_json,
391
+ headers: FilestackConfig::HEADERS)
392
+
381
393
  # POST to multipart/upload
382
394
  begin
383
395
  unless fs_response.code == 200
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filestack
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.3
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Filestack
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-12 00:00:00.000000000 Z
11
+ date: 2020-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -29,6 +29,9 @@ dependencies:
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.11'
34
+ - - ">="
32
35
  - !ruby/object:Gem::Version
33
36
  version: 1.11.2
34
37
  type: :runtime
@@ -36,6 +39,9 @@ dependencies:
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.11'
44
+ - - ">="
39
45
  - !ruby/object:Gem::Version
40
46
  version: 1.11.2
41
47
  - !ruby/object:Gem::Dependency
@@ -195,7 +201,7 @@ homepage: https://github.com/filestack/filestack-ruby
195
201
  licenses:
196
202
  - MIT
197
203
  metadata: {}
198
- post_install_message:
204
+ post_install_message:
199
205
  rdoc_options: []
200
206
  require_paths:
201
207
  - lib
@@ -210,9 +216,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
216
  - !ruby/object:Gem::Version
211
217
  version: '0'
212
218
  requirements: []
213
- rubyforge_project:
214
- rubygems_version: 2.6.14
215
- signing_key:
219
+ rubygems_version: 3.0.8
220
+ signing_key:
216
221
  specification_version: 4
217
222
  summary: Official Ruby SDK for the Filestack API
218
223
  test_files: []