appwrite 24.1.0 → 24.2.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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/appwrite/client.rb +109 -32
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 117e69f27971b35ba99f0ccc63cfb9a3494955eef4e214048b38aa4ba57e1b80
4
- data.tar.gz: d0e41de1a5f8550c33b3db61262a9e4f7b4facfafdfccc63f1e2a9d9947b045e
3
+ metadata.gz: 1815561145e36dee35678ad27a1bbdf13c53ed1fad59dd8c07805321f6073627
4
+ data.tar.gz: a4c4d5cf12077a7eedfb240b13c632040f3f8d220421704156b9cc07353e687f
5
5
  SHA512:
6
- metadata.gz: 5ef18be9f1d2867aac51d1bd83955e5da5e9cf6f92d6d42759d1e7f45c1e95f4e66606e70e1e965e7092f3274923dd04f9cf041a51eaf9a6b7b0df085bfa31d7
7
- data.tar.gz: 7afc04eac74397f0381624d0a3ddce3da33ff80468414856b6ec9e35028437ccee66bfc71f88af12c7f8242def21f63e783053112029271b4e90248a014b74b1
6
+ metadata.gz: '018c916f75afc5a11b45837d4498b371241156e5a765903815a6bfbefaf848b15b457b0988e384a3331b51c8cc291c52c9a0015bec63960ed73aee57f1886d8f'
7
+ data.tar.gz: 2274734af1f1c1434d2aa945d84d6ca704d7c155e633b2c71e58f086c69809b1c46af12a703769d46a3d087291eb22854dd57718ccc8c7e09eb7fb8017f0a628
@@ -15,7 +15,7 @@ module Appwrite
15
15
  'x-sdk-name'=> 'Ruby',
16
16
  'x-sdk-platform'=> 'server',
17
17
  'x-sdk-language'=> 'ruby',
18
- 'x-sdk-version'=> '24.1.0',
18
+ 'x-sdk-version'=> '24.2.0',
19
19
  'X-Appwrite-Response-Format' => '1.9.5'
20
20
  }
21
21
  @endpoint = 'https://cloud.appwrite.io/v1'
@@ -262,56 +262,133 @@ module Appwrite
262
262
 
263
263
  offset = 0
264
264
  id_param_name = id_param_name.to_sym if id_param_name
265
+ upload_id = nil
266
+ chunks_uploaded = 0
265
267
  if id_param_name&.empty? == false
268
+ upload_id = params[id_param_name]
266
269
  # Make a request to check if a file already exists
267
- current = call(
268
- method: "GET",
269
- path: "#{path}/#{params[id_param_name]}",
270
- headers: headers,
271
- params: {}
272
- )
273
- chunks_uploaded = current['chunksUploaded'].to_i
274
- offset = chunks_uploaded * @chunk_size
270
+ begin
271
+ current = call(
272
+ method: "GET",
273
+ path: "#{path}/#{params[id_param_name]}",
274
+ headers: headers,
275
+ params: {}
276
+ )
277
+ chunks_uploaded = current['chunksUploaded'].to_i
278
+ offset = chunks_uploaded * @chunk_size
279
+ rescue Appwrite::Exception => error
280
+ raise error unless error.code.to_i == 404
281
+ end
275
282
  end
276
283
 
284
+ total_chunks = (size.to_f / @chunk_size).ceil
285
+ chunks = []
277
286
  while offset < size
287
+ chunks << {
288
+ index: chunks_uploaded.to_i,
289
+ start: offset,
290
+ ending: [offset + @chunk_size, size].min
291
+ }
292
+ offset += @chunk_size
293
+ chunks_uploaded = chunks_uploaded.to_i + 1
294
+ end
295
+
296
+ result = current if defined?(current)
297
+ return result unless chunks.any?
298
+
299
+ upload_chunk = lambda do |chunk, current_upload_id|
278
300
  case input_file.source_type
279
301
  when 'path'
280
- string = IO.read(input_file.path, @chunk_size, offset)
302
+ string = IO.read(input_file.path, chunk[:ending] - chunk[:start], chunk[:start])
281
303
  when 'string'
282
- string = input_file.data.byteslice(offset, [@chunk_size, size - offset].min)
304
+ string = input_file.data.byteslice(chunk[:start], chunk[:ending] - chunk[:start])
283
305
  end
284
306
 
285
- params[param_name.to_sym] = InputFile::from_string(
307
+ chunk_params = params.merge(param_name.to_sym => InputFile::from_string(
286
308
  string,
287
309
  filename: input_file.filename,
288
310
  mime_type: input_file.mime_type
289
- )
311
+ ))
290
312
 
291
- headers['content-range'] = "bytes #{offset}-#{[offset + @chunk_size - 1, size - 1].min}/#{size}"
313
+ chunk_headers = headers.merge('content-range' => "bytes #{chunk[:start]}-#{chunk[:ending] - 1}/#{size}")
314
+ chunk_headers['x-appwrite-id'] = current_upload_id if current_upload_id
292
315
 
293
- result = call(
316
+ call(
294
317
  method: 'POST',
295
318
  path: path,
296
- headers: headers,
297
- params: params,
319
+ headers: chunk_headers,
320
+ params: chunk_params,
298
321
  )
322
+ end
299
323
 
300
- offset += @chunk_size
324
+ result = upload_chunk.call(chunks.first, upload_id)
325
+ upload_id = result['$id'] if result['$id']
326
+ completed_count = chunks.first[:index] + 1
327
+ uploaded_size = chunks.first[:ending]
301
328
 
302
- if defined? result['$id']
303
- headers['x-appwrite-id'] = result['$id']
304
- end
329
+ upload_complete = lambda do |chunk_result|
330
+ chunks_uploaded = chunk_result['chunksUploaded']
331
+ return false if chunks_uploaded.nil?
305
332
 
306
- on_progress.call({
307
- id: result['$id'],
308
- progress: ([offset, size].min).to_f/size.to_f * 100.0,
309
- size_uploaded: [offset, size].min,
310
- chunks_total: result['chunksTotal'],
311
- chunks_uploaded: result['chunksUploaded']
312
- }) unless on_progress.nil?
333
+ chunks_total = chunk_result['chunksTotal'] || total_chunks
334
+ chunks_uploaded.to_i >= chunks_total.to_i
313
335
  end
314
336
 
337
+ on_progress.call({
338
+ id: result['$id'],
339
+ progress: uploaded_size.to_f/size.to_f * 100.0,
340
+ size_uploaded: uploaded_size,
341
+ chunks_total: result['chunksTotal'] || total_chunks,
342
+ chunks_uploaded: result['chunksUploaded'] || completed_count
343
+ }) unless on_progress.nil?
344
+
345
+ mutex = Mutex.new
346
+ queue = Queue.new
347
+ chunks.drop(1).each { |chunk| queue << chunk }
348
+ first_error = nil
349
+ last_result = result
350
+ completed_result = nil
351
+
352
+ workers = [8, queue.size].min.times.map do
353
+ Thread.new do
354
+ loop do
355
+ break if mutex.synchronize { !first_error.nil? }
356
+
357
+ chunk = begin
358
+ queue.pop(true)
359
+ rescue ThreadError
360
+ nil
361
+ end
362
+ break unless chunk
363
+
364
+ begin
365
+ chunk_result = upload_chunk.call(chunk, upload_id)
366
+ rescue => error
367
+ mutex.synchronize { first_error ||= error }
368
+ break
369
+ end
370
+ mutex.synchronize do
371
+ completed_count += 1
372
+ uploaded_size += chunk[:ending] - chunk[:start]
373
+ last_result = chunk_result
374
+ completed_result = chunk_result if upload_complete.call(chunk_result)
375
+ on_progress.call({
376
+ id: upload_id,
377
+ progress: uploaded_size.to_f/size.to_f * 100.0,
378
+ size_uploaded: uploaded_size,
379
+ chunks_total: chunk_result['chunksTotal'] || total_chunks,
380
+ chunks_uploaded: chunk_result['chunksUploaded'] || completed_count
381
+ }) unless on_progress.nil?
382
+ end
383
+ end
384
+ end
385
+ end
386
+
387
+ workers.each(&:join)
388
+ raise first_error if first_error
389
+
390
+ result = completed_result || last_result
391
+
315
392
  return result unless response_type.respond_to?("from")
316
393
 
317
394
  response_type.from(map: result)
@@ -329,8 +406,8 @@ module Appwrite
329
406
  )
330
407
  raise ArgumentError, 'Too Many HTTP Redirects' if limit == 0
331
408
 
332
- @http = Net::HTTP.new(uri.host, uri.port) unless defined? @http
333
- @http.use_ssl = !@self_signed
409
+ http = Net::HTTP.new(uri.host, uri.port)
410
+ http.use_ssl = !@self_signed
334
411
  payload = ''
335
412
 
336
413
  headers = @headers.merge(headers)
@@ -351,7 +428,7 @@ module Appwrite
351
428
  end
352
429
 
353
430
  begin
354
- response = @http.send_request(method, uri.request_uri, payload, headers)
431
+ response = http.send_request(method, uri.request_uri, payload, headers)
355
432
  rescue => error
356
433
  raise Appwrite::Exception.new(error.message)
357
434
  end
@@ -382,7 +459,7 @@ module Appwrite
382
459
  end
383
460
 
384
461
  if response.code.to_i >= 400
385
- raise Appwrite::Exception.new(result['message'], result['status'], result['type'], response.body)
462
+ raise Appwrite::Exception.new(result['message'], response.code, result['type'], response.body)
386
463
  end
387
464
 
388
465
  unless response_type.respond_to?("from")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appwrite
3
3
  version: !ruby/object:Gem::Version
4
- version: 24.1.0
4
+ version: 24.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Appwrite Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-20 00:00:00.000000000 Z
11
+ date: 2026-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mime-types