Skip to content

Commit d4daa9d

Browse files
committed
fix: multipart testing
1 parent ac440e6 commit d4daa9d

24 files changed

+908
-757
lines changed

Gemfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
source 'https://rubygems.org'
22

3-
gemspec
3+
gem 'mime-types', '~> 3.4.1'
4+
5+
gemspec
6+

appwrite.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Gem::Specification.new do |spec|
22

33
spec.name = 'appwrite'
4-
spec.version = '12.1.0'
4+
spec.version = '13.0.0'
55
spec.license = 'BSD-3-Clause'
66
spec.summary = 'Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API'
77
spec.author = 'Appwrite Team'

docs/examples/functions/create-deployment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ functions = Functions.new(client)
1111

1212
result = functions.create_deployment(
1313
function_id: '<FUNCTION_ID>',
14-
code: InputFile.from_path('dir/file.png'),
14+
code: Payload.from_file('/path/to/file.png'),
1515
activate: false,
1616
entrypoint: '<ENTRYPOINT>', # optional
1717
commands: '<COMMANDS>' # optional

docs/examples/functions/create-execution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ functions = Functions.new(client)
1111

1212
result = functions.create_execution(
1313
function_id: '<FUNCTION_ID>',
14-
body: '<BODY>', # optional
14+
body: Payload.from_json({ "x": "y" }), # optional
1515
async: false, # optional
1616
path: '<PATH>', # optional
1717
method: ExecutionMethod::GET, # optional

docs/examples/storage/create-file.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ storage = Storage.new(client)
1212
result = storage.create_file(
1313
bucket_id: '<BUCKET_ID>',
1414
file_id: '<FILE_ID>',
15-
file: InputFile.from_path('dir/file.png'),
15+
file: Payload.from_file('/path/to/file.png'),
1616
permissions: ["read("any")"] # optional
1717
)

lib/appwrite.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
require_relative 'appwrite/client'
77
require_relative 'appwrite/service'
88
require_relative 'appwrite/exception'
9-
require_relative 'appwrite/input_file'
9+
require_relative 'appwrite/payload'
10+
require_relative 'appwrite/multipart'
1011
require_relative 'appwrite/query'
1112
require_relative 'appwrite/permission'
1213
require_relative 'appwrite/role'

lib/appwrite/client.rb

Lines changed: 46 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,14 @@ def initialize
1515
'x-sdk-name'=> 'Ruby',
1616
'x-sdk-platform'=> 'server',
1717
'x-sdk-language'=> 'ruby',
18-
'x-sdk-version'=> '12.1.0',
19-
'X-Appwrite-Response-Format' => '1.6.0'
20-
}
18+
'x-sdk-version'=> '13.0.0', 'X-Appwrite-Response-Format' => '1.6.0' }
2119
@endpoint = 'https://cloud.appwrite.io/v1'
2220
end
2321

2422
# Set Project
2523
#
2624
# Your project ID
27-
#
28-
# @param [String] value The value to set for the Project header
25+
# # @param [String] value The value to set for the Project header
2926
#
3027
# @return [self]
3128
def set_project(value)
@@ -37,8 +34,7 @@ def set_project(value)
3734
# Set Key
3835
#
3936
# Your secret API key
40-
#
41-
# @param [String] value The value to set for the Key header
37+
# # @param [String] value The value to set for the Key header
4238
#
4339
# @return [self]
4440
def set_key(value)
@@ -50,8 +46,7 @@ def set_key(value)
5046
# Set JWT
5147
#
5248
# Your secret JSON Web Token
53-
#
54-
# @param [String] value The value to set for the JWT header
49+
# # @param [String] value The value to set for the JWT header
5550
#
5651
# @return [self]
5752
def set_jwt(value)
@@ -74,8 +69,7 @@ def set_locale(value)
7469
# Set Session
7570
#
7671
# The user session to authenticate with
77-
#
78-
# @param [String] value The value to set for the Session header
72+
# # @param [String] value The value to set for the Session header
7973
#
8074
# @return [self]
8175
def set_session(value)
@@ -87,8 +81,7 @@ def set_session(value)
8781
# Set ForwardedUserAgent
8882
#
8983
# The user agent string of the client that made the request
90-
#
91-
# @param [String] value The value to set for the ForwardedUserAgent header
84+
# # @param [String] value The value to set for the ForwardedUserAgent header
9285
#
9386
# @return [self]
9487
def set_forwarded_user_agent(value)
@@ -119,7 +112,6 @@ def set_self_signed(self_signed = true)
119112
self
120113
end
121114

122-
123115
# Add Header
124116
#
125117
# @param [String] key The key for the header to add
@@ -162,20 +154,9 @@ def chunked_upload(
162154
on_progress: nil,
163155
response_type: nil
164156
)
165-
input_file = params[param_name.to_sym]
166-
167-
case input_file.source_type
168-
when 'path'
169-
size = ::File.size(input_file.path)
170-
when 'string'
171-
size = input_file.data.bytesize
172-
end
157+
payload = params[param_name.to_sym]
173158

174-
if size < @chunk_size
175-
if input_file.source_type == 'path'
176-
input_file.data = IO.read(input_file.path)
177-
end
178-
params[param_name.to_sym] = input_file
159+
if payload.size < @chunk_size
179160
return call(
180161
method: 'POST',
181162
path: path,
@@ -199,21 +180,13 @@ def chunked_upload(
199180
offset = chunks_uploaded * @chunk_size
200181
end
201182

202-
while offset < size
203-
case input_file.source_type
204-
when 'path'
205-
string = IO.read(input_file.path, @chunk_size, offset)
206-
when 'string'
207-
string = input_file.data.byteslice(offset, [@chunk_size, size - offset].min)
208-
end
209-
210-
params[param_name.to_sym] = InputFile::from_string(
211-
string,
212-
filename: input_file.filename,
213-
mime_type: input_file.mime_type
183+
while offset < payload.size
184+
params[param_name.to_sym] = Payload.from_binary(
185+
payload.to_binary(offset, [@chunk_size, payload.size - offset].min),
186+
filename: payload.filename
214187
)
215188

216-
headers['content-range'] = "bytes #{offset}-#{[offset + @chunk_size - 1, size - 1].min}/#{size}"
189+
headers['content-range'] = "bytes #{offset}-#{[offset + @chunk_size - 1, payload.size - 1].min}/#{payload.size}"
217190

218191
result = call(
219192
method: 'POST',
@@ -230,8 +203,8 @@ def chunked_upload(
230203

231204
on_progress.call({
232205
id: result['$id'],
233-
progress: ([offset, size].min).to_f/size.to_f * 100.0,
234-
size_uploaded: [offset, size].min,
206+
progress: ([offset, payload.size].min).to_f/payload.size.to_f * 100.0,
207+
size_uploaded: [offset, payload.size].min,
235208
chunks_total: result['chunksTotal'],
236209
chunks_uploaded: result['chunksUploaded']
237210
}) unless on_progress.nil?
@@ -258,18 +231,27 @@ def fetch(
258231
@http.use_ssl = !@self_signed
259232
payload = ''
260233

261-
headers = @headers.merge(headers)
234+
headers = @headers.merge(headers.transform_keys(&:to_s))
262235

263236
params.compact!
264237

265-
@boundary = "----A30#3ad1"
266238
if method != "GET"
267-
case headers[:'content-type']
239+
case headers['content-type']
268240
when 'application/json'
269241
payload = params.to_json
270242
when 'multipart/form-data'
271-
payload = encode_form_data(params) + "--#{@boundary}--\r\n"
272-
headers[:'content-type'] = "multipart/form-data; boundary=#{@boundary}"
243+
multipart = MultipartBuilder.new()
244+
245+
params.each do |name, value|
246+
if value.is_a?(Payload)
247+
multipart.add(name, value.to_s, filename: value.filename)
248+
else
249+
multipart.add(name, value)
250+
end
251+
end
252+
253+
headers['content-type'] = multipart.content_type
254+
payload = multipart.body
273255
else
274256
payload = encode(params)
275257
end
@@ -299,7 +281,7 @@ def fetch(
299281
return fetch(method, uri, headers, {}, response_type, limit - 1)
300282
end
301283

302-
if response.content_type == 'application/json'
284+
if response.content_type.start_with?('application/json')
303285
begin
304286
result = JSON.parse(response.body)
305287
rescue JSON::ParserError => e
@@ -310,48 +292,33 @@ def fetch(
310292
raise Appwrite::Exception.new(result['message'], result['status'], result['type'], result)
311293
end
312294

313-
unless response_type.respond_to?("from")
314-
return result
295+
if response_type.respond_to?("from")
296+
return response_type.from(map: result)
315297
end
316298

317-
return response_type.from(map: result)
299+
return result
318300
end
319301

320302
if response.code.to_i >= 400
321303
raise Appwrite::Exception.new(response.body, response.code, response)
322304
end
323305

324-
if response.respond_to?("body_permitted?")
325-
return response.body if response.body_permitted?
326-
end
306+
if response.content_type.start_with?('multipart/form-data')
307+
multipart = MultipartParser.new(response.body, response['content-type'])
308+
result = multipart.to_hash
327309

328-
return response
329-
end
330-
331-
def encode_form_data(value, key=nil)
332-
case value
333-
when Hash
334-
value.map { |k,v| encode_form_data(v,k) }.join
335-
when Array
336-
value.map { |v| encode_form_data(v, "#{key}[]") }.join
337-
when nil
338-
''
339-
else
340-
post_body = []
341-
if value.instance_of? InputFile
342-
post_body << "--#{@boundary}"
343-
post_body << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{value.filename}\""
344-
post_body << "Content-Type: #{value.mime_type}"
345-
post_body << ""
346-
post_body << value.data
347-
else
348-
post_body << "--#{@boundary}"
349-
post_body << "Content-Disposition: form-data; name=\"#{key}\""
350-
post_body << ""
351-
post_body << value.to_s
310+
if response_type.respond_to?("from")
311+
return response_type.from(map: result)
352312
end
353-
post_body.join("\r\n") + "\r\n"
313+
314+
return result
354315
end
316+
317+
if response.class.body_permitted?
318+
return response.body
319+
end
320+
321+
return response
355322
end
356323

357324
def encode(value, key = nil)

lib/appwrite/enums/runtime.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ module Runtime
2121
PYTHON_3_11 = 'python-3.11'
2222
PYTHON_3_12 = 'python-3.12'
2323
PYTHON_ML_3_11 = 'python-ml-3.11'
24+
DENO_1_21 = 'deno-1.21'
25+
DENO_1_24 = 'deno-1.24'
26+
DENO_1_35 = 'deno-1.35'
2427
DENO_1_40 = 'deno-1.40'
2528
DART_2_15 = 'dart-2.15'
2629
DART_2_16 = 'dart-2.16'

lib/appwrite/input_file.rb

Lines changed: 0 additions & 33 deletions
This file was deleted.

lib/appwrite/models/document.rb

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,21 @@ class Document
1010
attr_reader :updated_at
1111
attr_reader :permissions
1212
attr_reader :data
13-
1413
def initialize(
1514
id:,
1615
collection_id:,
1716
database_id:,
1817
created_at:,
1918
updated_at:,
2019
permissions:,
21-
data:
22-
)
20+
data: )
2321
@id = id
2422
@collection_id = collection_id
2523
@database_id = database_id
2624
@created_at = created_at
2725
@updated_at = updated_at
2826
@permissions = permissions
29-
@data = data
30-
end
27+
@data = data end
3128

3229
def self.from(map:)
3330
Document.new(
@@ -37,8 +34,7 @@ def self.from(map:)
3734
created_at: map["$createdAt"],
3835
updated_at: map["$updatedAt"],
3936
permissions: map["$permissions"],
40-
data: map
41-
)
37+
data: map )
4238
end
4339

4440
def to_map
@@ -49,8 +45,7 @@ def to_map
4945
"$createdAt": @created_at,
5046
"$updatedAt": @updated_at,
5147
"$permissions": @permissions,
52-
"data": @data
53-
}
48+
"data": @data }
5449
end
5550

5651
def convert_to(from_json)

0 commit comments

Comments
 (0)