Skip to content

Commit

Permalink
fix: multipart testing
Browse files Browse the repository at this point in the history
  • Loading branch information
loks0n committed Oct 1, 2024
1 parent ac440e6 commit d4daa9d
Show file tree
Hide file tree
Showing 24 changed files with 908 additions and 757 deletions.
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
source 'https://rubygems.org'

gemspec
gem 'mime-types', '~> 3.4.1'

gemspec

2 changes: 1 addition & 1 deletion appwrite.gemspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Gem::Specification.new do |spec|

spec.name = 'appwrite'
spec.version = '12.1.0'
spec.version = '13.0.0'
spec.license = 'BSD-3-Clause'
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'
spec.author = 'Appwrite Team'
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/functions/create-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ functions = Functions.new(client)

result = functions.create_deployment(
function_id: '<FUNCTION_ID>',
code: InputFile.from_path('dir/file.png'),
code: Payload.from_file('/path/to/file.png'),
activate: false,
entrypoint: '<ENTRYPOINT>', # optional
commands: '<COMMANDS>' # optional
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/functions/create-execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ functions = Functions.new(client)

result = functions.create_execution(
function_id: '<FUNCTION_ID>',
body: '<BODY>', # optional
body: Payload.from_json({ "x": "y" }), # optional
async: false, # optional
path: '<PATH>', # optional
method: ExecutionMethod::GET, # optional
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/storage/create-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ storage = Storage.new(client)
result = storage.create_file(
bucket_id: '<BUCKET_ID>',
file_id: '<FILE_ID>',
file: InputFile.from_path('dir/file.png'),
file: Payload.from_file('/path/to/file.png'),
permissions: ["read("any")"] # optional
)
3 changes: 2 additions & 1 deletion lib/appwrite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
require_relative 'appwrite/client'
require_relative 'appwrite/service'
require_relative 'appwrite/exception'
require_relative 'appwrite/input_file'
require_relative 'appwrite/payload'
require_relative 'appwrite/multipart'
require_relative 'appwrite/query'
require_relative 'appwrite/permission'
require_relative 'appwrite/role'
Expand Down
125 changes: 46 additions & 79 deletions lib/appwrite/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,14 @@ def initialize
'x-sdk-name'=> 'Ruby',
'x-sdk-platform'=> 'server',
'x-sdk-language'=> 'ruby',
'x-sdk-version'=> '12.1.0',
'X-Appwrite-Response-Format' => '1.6.0'
}
'x-sdk-version'=> '13.0.0', 'X-Appwrite-Response-Format' => '1.6.0' }
@endpoint = 'https://cloud.appwrite.io/v1'
end

# Set Project
#
# Your project ID
#
# @param [String] value The value to set for the Project header
# # @param [String] value The value to set for the Project header
#
# @return [self]
def set_project(value)
Expand All @@ -37,8 +34,7 @@ def set_project(value)
# Set Key
#
# Your secret API key
#
# @param [String] value The value to set for the Key header
# # @param [String] value The value to set for the Key header
#
# @return [self]
def set_key(value)
Expand All @@ -50,8 +46,7 @@ def set_key(value)
# Set JWT
#
# Your secret JSON Web Token
#
# @param [String] value The value to set for the JWT header
# # @param [String] value The value to set for the JWT header
#
# @return [self]
def set_jwt(value)
Expand All @@ -74,8 +69,7 @@ def set_locale(value)
# Set Session
#
# The user session to authenticate with
#
# @param [String] value The value to set for the Session header
# # @param [String] value The value to set for the Session header
#
# @return [self]
def set_session(value)
Expand All @@ -87,8 +81,7 @@ def set_session(value)
# Set ForwardedUserAgent
#
# The user agent string of the client that made the request
#
# @param [String] value The value to set for the ForwardedUserAgent header
# # @param [String] value The value to set for the ForwardedUserAgent header
#
# @return [self]
def set_forwarded_user_agent(value)
Expand Down Expand Up @@ -119,7 +112,6 @@ def set_self_signed(self_signed = true)
self
end


# Add Header
#
# @param [String] key The key for the header to add
Expand Down Expand Up @@ -162,20 +154,9 @@ def chunked_upload(
on_progress: nil,
response_type: nil
)
input_file = params[param_name.to_sym]

case input_file.source_type
when 'path'
size = ::File.size(input_file.path)
when 'string'
size = input_file.data.bytesize
end
payload = params[param_name.to_sym]

if size < @chunk_size
if input_file.source_type == 'path'
input_file.data = IO.read(input_file.path)
end
params[param_name.to_sym] = input_file
if payload.size < @chunk_size
return call(
method: 'POST',
path: path,
Expand All @@ -199,21 +180,13 @@ def chunked_upload(
offset = chunks_uploaded * @chunk_size
end

while offset < size
case input_file.source_type
when 'path'
string = IO.read(input_file.path, @chunk_size, offset)
when 'string'
string = input_file.data.byteslice(offset, [@chunk_size, size - offset].min)
end

params[param_name.to_sym] = InputFile::from_string(
string,
filename: input_file.filename,
mime_type: input_file.mime_type
while offset < payload.size
params[param_name.to_sym] = Payload.from_binary(
payload.to_binary(offset, [@chunk_size, payload.size - offset].min),
filename: payload.filename
)

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

result = call(
method: 'POST',
Expand All @@ -230,8 +203,8 @@ def chunked_upload(

on_progress.call({
id: result['$id'],
progress: ([offset, size].min).to_f/size.to_f * 100.0,
size_uploaded: [offset, size].min,
progress: ([offset, payload.size].min).to_f/payload.size.to_f * 100.0,
size_uploaded: [offset, payload.size].min,
chunks_total: result['chunksTotal'],
chunks_uploaded: result['chunksUploaded']
}) unless on_progress.nil?
Expand All @@ -258,18 +231,27 @@ def fetch(
@http.use_ssl = !@self_signed
payload = ''

headers = @headers.merge(headers)
headers = @headers.merge(headers.transform_keys(&:to_s))

params.compact!

@boundary = "----A30#3ad1"
if method != "GET"
case headers[:'content-type']
case headers['content-type']
when 'application/json'
payload = params.to_json
when 'multipart/form-data'
payload = encode_form_data(params) + "--#{@boundary}--\r\n"
headers[:'content-type'] = "multipart/form-data; boundary=#{@boundary}"
multipart = MultipartBuilder.new()

params.each do |name, value|
if value.is_a?(Payload)
multipart.add(name, value.to_s, filename: value.filename)
else
multipart.add(name, value)
end
end

headers['content-type'] = multipart.content_type
payload = multipart.body
else
payload = encode(params)
end
Expand Down Expand Up @@ -299,7 +281,7 @@ def fetch(
return fetch(method, uri, headers, {}, response_type, limit - 1)
end

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

unless response_type.respond_to?("from")
return result
if response_type.respond_to?("from")
return response_type.from(map: result)
end

return response_type.from(map: result)
return result
end

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

if response.respond_to?("body_permitted?")
return response.body if response.body_permitted?
end
if response.content_type.start_with?('multipart/form-data')
multipart = MultipartParser.new(response.body, response['content-type'])
result = multipart.to_hash

return response
end

def encode_form_data(value, key=nil)
case value
when Hash
value.map { |k,v| encode_form_data(v,k) }.join
when Array
value.map { |v| encode_form_data(v, "#{key}[]") }.join
when nil
''
else
post_body = []
if value.instance_of? InputFile
post_body << "--#{@boundary}"
post_body << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{value.filename}\""
post_body << "Content-Type: #{value.mime_type}"
post_body << ""
post_body << value.data
else
post_body << "--#{@boundary}"
post_body << "Content-Disposition: form-data; name=\"#{key}\""
post_body << ""
post_body << value.to_s
if response_type.respond_to?("from")
return response_type.from(map: result)
end
post_body.join("\r\n") + "\r\n"

return result
end

if response.class.body_permitted?
return response.body
end

return response
end

def encode(value, key = nil)
Expand Down
3 changes: 3 additions & 0 deletions lib/appwrite/enums/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ module Runtime
PYTHON_3_11 = 'python-3.11'
PYTHON_3_12 = 'python-3.12'
PYTHON_ML_3_11 = 'python-ml-3.11'
DENO_1_21 = 'deno-1.21'
DENO_1_24 = 'deno-1.24'
DENO_1_35 = 'deno-1.35'
DENO_1_40 = 'deno-1.40'
DART_2_15 = 'dart-2.15'
DART_2_16 = 'dart-2.16'
Expand Down
33 changes: 0 additions & 33 deletions lib/appwrite/input_file.rb

This file was deleted.

13 changes: 4 additions & 9 deletions lib/appwrite/models/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,21 @@ class Document
attr_reader :updated_at
attr_reader :permissions
attr_reader :data

def initialize(
id:,
collection_id:,
database_id:,
created_at:,
updated_at:,
permissions:,
data:
)
data: )
@id = id
@collection_id = collection_id
@database_id = database_id
@created_at = created_at
@updated_at = updated_at
@permissions = permissions
@data = data
end
@data = data end

def self.from(map:)
Document.new(
Expand All @@ -37,8 +34,7 @@ def self.from(map:)
created_at: map["$createdAt"],
updated_at: map["$updatedAt"],
permissions: map["$permissions"],
data: map
)
data: map )
end

def to_map
Expand All @@ -49,8 +45,7 @@ def to_map
"$createdAt": @created_at,
"$updatedAt": @updated_at,
"$permissions": @permissions,
"data": @data
}
"data": @data }
end

def convert_to(from_json)
Expand Down
3 changes: 1 addition & 2 deletions lib/appwrite/models/document_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ def to_map

def convert_to(from_json)
documents.map { |it| it.convert_to(from_json) }
end
end
end end
end
end
Loading

0 comments on commit d4daa9d

Please sign in to comment.