Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- if dropbox then os.unloadAPI("dropbox") end
- if not dropbox then os.loadAPI("dropbox") end
- if not dropbox then error("Cannot find dropbox", 0) end
- --Prints out the usage for the function
- local commands = {
- upload = '<LOCAL> [REMOTE]',
- download = '<REMOTE> [LOCAL]',
- delete = '<REMOTE>',
- move = '<SRC> <DEST>',
- copy = '<SRC> <DEST>',
- mkdir = '<REMOTE_DIR>',
- list = '[REMOTE_DIR]',
- }
- local function usage(command)
- if command then
- error("Incorrect usage: " .. command .. " " .. commands[command], 0)
- end
- print([[
- Dropbox Uploader 1.0
- Usage: COMMAND [PARAMETERS]...
- Commands:
- upload <LOCAL> [REMOTE]
- download <REMOTE> [LOCAL]
- delete <REMOTE>
- move <SRC> <DEST>
- copy <SRC> <DEST>
- mkdir <REMOTE_DIR>
- list [REMOTE_DIR]
- ]])
- error("Incorrect usage", 0)
- end
- --Setup variables
- local function setup()
- write("App key >")
- local key = read()
- write("App Secret >")
- local secret = read()
- local app = {
- app_key = key,
- app_secret = secret,
- }
- -- These requests a token from online
- local tokens = dropbox.requestToken(app)
- if not tokens then error("Failed, check app key and secret", 0) end
- print("Please open the following url and allow the uploader")
- print(tokens.url) -- URL to visit, same as before
- print("Press any key to continue")
- os.pullEvent("key")
- -- This gets an access token
- config = dropbox.accessToken(app, tokens)
- if not config then error("Failed, please try again", 0) end
- return config
- end
- local config_file = '/.dropbox'
- local config
- if not fs.exists(config_file) then
- config = setup()
- -- Save the data
- local handle = fs.open(config_file, "w")
- handle.write(textutils.serialize(config))
- handle.close()
- else
- local handle = fs.open(config_file, "r")
- config = textutils.unserialize(handle.readAll())
- handle.close()
- end
- -- Create a VFS with the specified config
- local drop = dropbox.create(config)
- local args = {...}
- local action = table.remove(args, 1)
- if action == "upload" then
- -- This is a slightly overcomplicated upload
- if #args < 1 or #args > 2 then
- usage("upload")
- end
- local from = shell.resolve(args[1])
- if not fs.exists(from) then error("No such file", 0) end
- local to = args[2] or fs.combine("", args[1]):gsub("%.%./?", "")
- -- Here we check if the file is a directory. If we are a local file and
- -- are uploading to a directory then add the file name to the end
- if not fs.isDir(from) and drop.isDir(to) then
- to = fs.combine(to, fs.getName(from))
- end
- local queue = { { from, to } }
- local todo = {}
- while #queue > 0 do
- local from, to = unpack(table.remove(queue, 1))
- if fs.isDir(from) then
- -- Add additional files to the check queue
- for _, v in pairs(fs.list(from)) do
- table.insert(queue, { fs.combine(from, v), fs.combine(to, v)})
- end
- else
- -- Add additional files to the download queue
- -- we execute them in parallel to speed everything up - the limiting
- -- factor is network speed, so start them as soon as possible
- table.insert(todo, function()
- local handle = fs.open(from, "r")
- if not handle then
- printError("Cannot upload " .. from)
- return
- end
- local remote = drop.open(to, "w")
- remote.write(handle.readAll())
- handle.close()
- remote.close()
- end)
- end
- end
- parallel.waitForAll(unpack(todo))
- elseif action == "download" then
- -- Pretty much the same as above
- if #args < 1 or #args > 2 then
- usage("download")
- end
- local from = fs.combine("", args[1]):gsub("%.%./?", "")
- local to = shell.resolve(args[2] or args[1])
- local isDir = drop.isDir(from)
- if fs.isDir(to) and isDir then
- to = fs.combine(to, fs.getName(from))
- end
- local queue = { { from, to, isDir } }
- local todo = {}
- while #queue > 0 do
- local from, to, isDir = unpack(table.remove(queue, 1))
- -- This call could be optimised by downloading files
- -- straight away rather than gathering a folder tree and then downloading
- if isDir then
- local meta = drop.getMetadata(from)
- if not meta then
- printError("Cannot read " .. from)
- end
- for _, v in pairs(meta.contents) do
- -- We pass the is_dir flag as a minor optimisation so we don't check
- -- for every file
- table.insert(queue, { v.path, fs.combine(to, fs.getName(v.path)), v.is_dir})
- end
- else
- table.insert(todo, function()
- local remote = drop.open(from, "r")
- if not remote then
- printError("Cannot download " .. from)
- return
- end
- local handle = fs.open(to, "w")
- handle.write(remote.readAll())
- handle.close()
- remote.close()
- end)
- end
- end
- if #todo == 0 then error("Nothing to download", 0) end
- parallel.waitForAll(unpack(todo))
- elseif action == "list" or action == "ls" or action == "dir" then
- -- Pretty basic, only difference being that
- -- we get additional information to
- local rows = drop.list(args[1] or "/", true)
- local files, dirs = {}, {}
- for _, file in pairs(rows) do
- table.insert(file.is_dir and dirs or files, fs.getName(file.path))
- end
- table.sort(files)
- table.sort(dirs)
- if term.isColour() then
- textutils.pagedTabulate(colors.green, dirs, colors.white, files)
- else
- textutils.pagedTabulate(dirs, files)
- end
- -- The reset of these are really obvious
- elseif action == "copy" or action == "cp" then
- if #args ~= 2 then
- usage("copy")
- end
- drop.copy(args[1], args[2])
- elseif action == "move" or action == "rename" or action == "mv"then
- if #args ~= 2 then
- usage("move")
- end
- drop.move(args[1], args[2])
- elseif action == "delete" or action == "remove" then
- if #args ~= 1 then
- usage("delete")
- end
- drop.delete(args[1])
- elseif action == "mkdir" then
- if #args ~= 1 then
- usage("mkdir")
- end
- drop.makeDir(args[1])
- else
- usage()
- end
Advertisement
Add Comment
Please, Sign In to add comment