2019-12-19 11:47:32 +01:00
|
|
|
require "option_parser"
|
2020-06-08 04:49:55 +02:00
|
|
|
require "authd"
|
2019-12-18 11:47:24 +01:00
|
|
|
require "ipc"
|
|
|
|
require "json"
|
|
|
|
|
2020-01-02 09:21:11 +01:00
|
|
|
require "base64"
|
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
require "baguette-crystal-base"
|
|
|
|
|
2020-06-08 04:49:55 +02:00
|
|
|
require "./authd_api.cr"
|
2020-10-21 03:27:51 +02:00
|
|
|
require "./lib.cr"
|
2020-06-08 04:49:55 +02:00
|
|
|
require "../server/network.cr"
|
|
|
|
require "../server/storage.cr"
|
|
|
|
require "../server/storage/*"
|
2020-01-02 09:21:11 +01:00
|
|
|
|
2019-12-20 17:20:08 +01:00
|
|
|
# TODO
|
|
|
|
# For now, this example only upload files.
|
|
|
|
# In a near future, we should be able to download files, too.
|
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
class Context
|
|
|
|
class_property authd_login : String = "test"
|
|
|
|
class_property authd_pass : String = "test"
|
|
|
|
|
2020-10-21 19:59:57 +02:00
|
|
|
class_property path : String = "."
|
|
|
|
|
|
|
|
class_property args = Array(String).new
|
2019-12-19 11:47:32 +01:00
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
class_property service_name = "filestorage"
|
|
|
|
class_property command = "unknown"
|
|
|
|
end
|
2019-12-19 11:47:32 +01:00
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
opt_unknown_args = ->(parser : OptionParser) {
|
|
|
|
parser.unknown_args do |arg|
|
2020-10-21 19:59:57 +02:00
|
|
|
Context.args = arg
|
2020-10-21 15:43:41 +02:00
|
|
|
end
|
|
|
|
}
|
2019-12-19 11:47:32 +01:00
|
|
|
|
|
|
|
OptionParser.parse do |parser|
|
2020-10-21 15:43:41 +02:00
|
|
|
parser.banner = "#{PROGRAM_NAME} [OPTIONS] <files-to-upload>"
|
2019-12-20 17:20:08 +01:00
|
|
|
parser.on "-s service-name",
|
|
|
|
"--service-name service-name",
|
|
|
|
"Service name." do |name|
|
2020-10-21 15:43:41 +02:00
|
|
|
Context.service_name = name
|
|
|
|
end
|
|
|
|
|
|
|
|
parser.on "get", "Get files from IDs (file digests)." do
|
|
|
|
parser.banner = "#{PROGRAM_NAME} get digest [digest…] [OPTIONS]"
|
|
|
|
Context.command = "get"
|
|
|
|
opt_unknown_args.call parser
|
|
|
|
end
|
|
|
|
parser.on "put", "Send files." do
|
|
|
|
parser.banner = "#{PROGRAM_NAME} put path [path…] [OPTIONS]"
|
|
|
|
Context.command = "put"
|
|
|
|
opt_unknown_args.call parser
|
2019-12-19 11:47:32 +01:00
|
|
|
end
|
|
|
|
|
2020-06-08 04:49:55 +02:00
|
|
|
parser.on "-l login",
|
|
|
|
"--login login-name",
|
|
|
|
"Login name for authd." do |name|
|
2020-10-21 15:43:41 +02:00
|
|
|
Context.authd_login = name
|
2020-06-08 04:49:55 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on "-p pass",
|
|
|
|
"--pass pass",
|
|
|
|
"Password for authd." do |pass|
|
2020-10-21 15:43:41 +02:00
|
|
|
Context.authd_pass = pass
|
2020-06-08 04:49:55 +02:00
|
|
|
end
|
|
|
|
|
2020-10-21 19:59:57 +02:00
|
|
|
parser.on "-d directory",
|
|
|
|
"--directory path",
|
|
|
|
"Path where to put downloaded files." do |path|
|
|
|
|
Context.path = path
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
parser.on "-v verbosity",
|
|
|
|
"--verbosity level",
|
|
|
|
"Verbosity. From 0 to 4." do |v|
|
|
|
|
Baguette::Context.verbosity = v.to_i
|
2019-12-19 11:47:32 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on "-h", "--help", "Show this help" do
|
|
|
|
puts parser
|
2020-06-08 04:49:55 +02:00
|
|
|
exit -1
|
2019-12-19 11:47:32 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
def put(client : FileStorage::Client)
|
|
|
|
Baguette::Log.info "Putting files on the server"
|
|
|
|
#
|
|
|
|
# Verify we can read files
|
|
|
|
#
|
|
|
|
|
|
|
|
files = [] of String
|
|
|
|
|
2020-10-21 19:59:57 +02:00
|
|
|
Context.args.each do |f|
|
2020-10-21 15:43:41 +02:00
|
|
|
if File.directory? f
|
|
|
|
# TODO
|
|
|
|
Baguette::Log.warning "Directories not supported, for now"
|
|
|
|
elsif File.file?(f) && File.readable? f
|
|
|
|
files << f
|
|
|
|
else
|
|
|
|
if ! File.exists? f
|
|
|
|
Baguette::Log.error "#{f} does not exist"
|
|
|
|
elsif ! File.file? f
|
|
|
|
Baguette::Log.error "#{f} is neither a directory or a file"
|
|
|
|
elsif ! File.readable? f
|
|
|
|
Baguette::Log.error "#{f} is not readable"
|
|
|
|
end
|
2019-12-19 11:47:32 +01:00
|
|
|
end
|
|
|
|
end
|
2020-10-21 15:43:41 +02:00
|
|
|
|
|
|
|
files.each do |file|
|
2020-10-22 02:08:12 +02:00
|
|
|
file_info = File.open(file) do |f|
|
|
|
|
FileStorage::FileInfo.new f
|
|
|
|
end
|
2020-10-21 19:59:57 +02:00
|
|
|
response = client.upload file
|
2020-10-22 02:08:12 +02:00
|
|
|
case response
|
|
|
|
when FileStorage::Errors::FileFullyUploaded
|
2020-10-21 19:59:57 +02:00
|
|
|
Baguette::Log.warning "file #{file} already uploaded, digest: #{file_info.digest}"
|
|
|
|
next
|
2020-10-22 02:08:12 +02:00
|
|
|
when FileStorage::Errors::FileTooBig
|
|
|
|
Baguette::Log.warning "file #{file} too big, accepting up to #{response.limit} bytes"
|
|
|
|
next
|
2020-10-21 19:59:57 +02:00
|
|
|
end
|
|
|
|
Baguette::Log.info "transfering: #{file}"
|
2020-10-21 15:43:41 +02:00
|
|
|
client.transfer file
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get(client : FileStorage::Client)
|
2020-10-21 19:59:57 +02:00
|
|
|
files = Context.args
|
|
|
|
files.each do |filedigest|
|
|
|
|
response = client.download filedigest
|
|
|
|
case response
|
|
|
|
when FileStorage::Response::Download
|
|
|
|
Baguette::Log.info "downloading file #{filedigest} with #{response.file_info.nb_chunks} chunks"
|
|
|
|
client.get_chunks response, Context.path
|
|
|
|
else
|
2020-10-21 23:24:53 +02:00
|
|
|
Baguette::Log.error "#{response.class.name}"
|
2020-10-21 19:59:57 +02:00
|
|
|
next
|
|
|
|
end
|
|
|
|
end
|
2019-12-19 11:47:32 +01:00
|
|
|
end
|
|
|
|
|
2019-12-20 17:20:08 +01:00
|
|
|
|
2020-01-04 10:45:39 +01:00
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
def main
|
|
|
|
#
|
|
|
|
# Connection to the service
|
|
|
|
#
|
|
|
|
|
|
|
|
token = authd_get_token login: Context.authd_login, pass: Context.authd_pass
|
|
|
|
|
|
|
|
# Connection and authentication to filestoraged.
|
|
|
|
client = FileStorage::Client.new token, Context.service_name
|
|
|
|
client.login
|
|
|
|
|
|
|
|
case Context.command
|
|
|
|
when /put/
|
|
|
|
put client
|
|
|
|
when /get/
|
|
|
|
get client
|
|
|
|
else
|
|
|
|
Baguette::Log.error "unkown command"
|
|
|
|
end
|
2020-01-02 09:21:11 +01:00
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
client.close
|
2019-12-19 11:47:32 +01:00
|
|
|
end
|
|
|
|
|
2020-10-21 15:43:41 +02:00
|
|
|
main
|