diff --git a/README.md b/README.md index 21423e0..8b39e6b 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,8 @@ The file server to proxy connection can be dropped, we have to ensure the commun * dodb is used to keep track of the files, using its tag system * messages are: JSON encoded, 1KB buffered data * message example: { message-id: "UUID", chunk: "UUID", data: [1KB BINARY DATA] } + + +# TODO + +* Quotas diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..2e9474f --- /dev/null +++ b/shard.yml @@ -0,0 +1,26 @@ +name: filestorage +version: 0.1.0 + +authors: + - Karchnu + +description: | + A file storage service. + +dependencies: + ipc: + git: https://git.karchnu.fr/WeirdOS/ipc.cr + dodb: + git: https://git.karchnu.fr/WeirdOS/dodb.cr + authd: + git: https://github.com/Lukc/authd + +targets: + json-tests: + main: src/json_tests.cr + filestorage: + main: src/main.cr + filestorageclient: + main: src/client.cr + +license: MIT diff --git a/src/client.cr b/src/client.cr index 631a8f1..b9e3321 100644 --- a/src/client.cr +++ b/src/client.cr @@ -1,12 +1,71 @@ +require "option_parser" require "ipc" require "json" require "./common.cr" -client = IPC::Client.new("pong") +service_name = "filestorage" + +files_and_directories_to_transfer = Array(String).new + + +OptionParser.parse do |parser| + parser.on "-s service-name", "--service-name service-name", "Service name." do |name| + service_name = name + end + + parser.unknown_args do |arg| + files_and_directories_to_transfer = arg + end + + parser.on "-h", "--help", "Show this help" do + puts parser + exit 0 + end +end + +client = IPC::Client.new service_name + + +# +# Get informations about files to transfer +# + +files_info = Array(FileInfo).new + +puts "files and directories to transfer" +files_and_directories_to_transfer.each do |f| + puts "- #{f}" + + if File.directory? f + # TODO + puts "Directories not supported, for now" + elsif File.file?(f) && File.readable? f + File.open(f) do |file| + files_info << FileInfo.new file + end + else + if File.exists? f + puts "#{f} does not exist" + elsif File.file? f + puts "#{f} is neither a directory or a file" + elsif File.readable? f + puts "#{f} is not readable" + end + end +end + +pp! files_info + +exit 0 + +# +# Create the authentication message, including files info +# token = Token.new 1002, "karchnu" -authentication_message = AuthenticationMessage.new token +authentication_message = AuthenticationMessage.new token, files_info + client.send(1.to_u8, authentication_message.to_json) @@ -22,6 +81,24 @@ else puts "Message IDs from authentication message and its response differ" end +# +# file transfer +# + +puts "transfer" +files_and_directories_to_transfer.each do |f| + puts "- #{f}" + + if File.directory? f + # TODO + elsif File.file?(f) && File.readable? f + File.open(f) do |file| + # TODO + # file + end + end +end + client.close #client.loop do |event| diff --git a/src/common.cr b/src/common.cr index 71f0ebb..92a76b7 100644 --- a/src/common.cr +++ b/src/common.cr @@ -1,4 +1,3 @@ - require "uuid" class Token @@ -11,13 +10,31 @@ class Token end end +class FileInfo + JSON.mapping({ + name: String, + size: UInt32, + tags: Array(String)? + }) + + def initialize(@name, @size, @tags = nil) + end + + def initialize(file : File, @tags = nil) + @name = file.basename + @size = file.size + end +end + class AuthenticationMessage JSON.mapping({ mid: String, - token: Token + token: Token, + files: Array(FileInfo), + tags: Array(String)? }) - def initialize(@token) + def initialize(@token, @files, @tags = nil) @mid = UUID.random.to_s end end @@ -32,3 +49,15 @@ class Response def initialize(@mid, @response, @reason = nil) end end + +class Transfer + JSON.mapping({ + mid: String, + chunk: String, + data: Slice(UInt8) + }) + + def initialize(@chunk, @data) + @mid = UUID.random.to_s + end +end diff --git a/src/main.cr b/src/main.cr index 9d10362..12c4f99 100644 --- a/src/main.cr +++ b/src/main.cr @@ -4,6 +4,8 @@ require "json" require "./colors" +# require "dodb" + require "./common.cr" storage_directory = "./storage" @@ -77,6 +79,10 @@ service.loop do |event| authentication_message = AuthenticationMessage.from_json(String.new event.message.payload) + authentication_message.files.each do |file| + puts "uploading #{file.name} - #{file.size} bytes" + end + new_user = User.new authentication_message.token connected_users[event.connection.fd] = new_user puts "New user is: #{new_user.token.login}"