filestoraged/src/client/lib.cr

97 lines
2.5 KiB
Crystal

require "ipc"
class FileStorage::Client < IPC::Client
property auth_token : String
def initialize(@auth_token, service_name = "filestorage")
super service_name
end
# TODO: parse_message should raise exception if response not anticipated
def parse_message(expected_messages, message)
em = Array(IPC::JSON.class).new
expected_messages.each do |e|
em << e
end
em << FileStorage::Errors::GenericError
em << FileStorage::Errors::Authorization
em << FileStorage::Errors::ChunkAlreadyUploaded
em << FileStorage::Errors::ChunkUploadDenied
em << FileStorage::Errors::FileExists
em << FileStorage::Errors::FileDoesNotExist
em << FileStorage::Errors::FileFullyUploaded
em.parse_ipc_json message
end
end
class FileStorage::Client < IPC::Client
def login
request = FileStorage::Request::Login.new @auth_token
send_now @server_fd.not_nil!, request
parse_message [ FileStorage::Response::Login ], read
end
# Helper function.
def get_file_info(file_path : String)
file_info : FileStorage::FileInfo
file = File.open(file_path)
file_info = FileStorage::FileInfo.new file
file.close
file_info.not_nil!
end
def transfer(file_path : String)
file_info = get_file_info file_path
File.open(file_path) do |file|
buffer_size = FileStorage.message_buffer_size
buffer = Bytes.new buffer_size
counter = 0
size = 0
while (size = file.read(buffer)) > 0
# transfer message = file_info, chunk count, data (will be base64'd)
transfer_message = FileStorage::Request::PutChunk.new file_info,
counter,
buffer[0 ... size]
send_now @server_fd.not_nil!, transfer_message
counter += 1
buffer = Bytes.new buffer_size
# Check for the response
response = parse_message [ FileStorage::Response::PutChunk ], read
if response.responds_to? :mid
if response.mid != transfer_message.mid
raise "request and response mid !=: #{response.mid} != #{transfer_message.mid}"
else
pp! response
end
else
raise "response doesn't have mid"
end
end
end
end
def download(filedigest = nil, name = nil, tags = nil)
request = FileStorage::Request::Download.new filedigest, name, tags
send_now @server_fd.not_nil!, request
parse_message [ FileStorage::Response::Download ], read
end
def upload(file : String)
file_info : FileStorage::FileInfo
File.open(file) do |f|
file_info = FileStorage::FileInfo.new f
request = FileStorage::Request::Upload.new file_info
send_now @server_fd.not_nil!, request
end
parse_message [ FileStorage::Response::Upload ], read
end
end