small changes \j
This commit is contained in:
203
modules/netmount.lua
Normal file
203
modules/netmount.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
local _
|
||||
local ofs = assert(_G.fs, "-eh?")
|
||||
-- [[ Argument Parsing ]] --
|
||||
local args = table.pack(...)
|
||||
local handle
|
||||
while true do
|
||||
for i = 1, #args do
|
||||
args[i]:gsub("(.*)=(.*)", function(k, v)
|
||||
args[k] = v
|
||||
end)
|
||||
end
|
||||
if #args < 3 then
|
||||
local keys = {
|
||||
"url",
|
||||
"username",
|
||||
"password",
|
||||
"path",
|
||||
"run"
|
||||
}
|
||||
for i = 1, #keys do
|
||||
local key = keys[i]
|
||||
if not args[key] then
|
||||
args[key] = settings.get("netmount." .. key)
|
||||
end
|
||||
end
|
||||
args.path = args.path or "net"
|
||||
end
|
||||
if (args.username and args.url and args.password) then
|
||||
handle = http.get(args.url:gsub("/$", "").."/api.lua")
|
||||
if handle then break end
|
||||
sleep(3)
|
||||
end
|
||||
sleep()
|
||||
end
|
||||
|
||||
handle.close()
|
||||
local state = assert(nm.createState(args.url, args.username, args.password))
|
||||
|
||||
local netroot = ofs.combine(args.path)
|
||||
assert(not ofs.exists(netroot), "Directory "..netroot.." already exists")
|
||||
|
||||
local function toNetRoot(path)
|
||||
path = ofs.combine(path)
|
||||
local nreplaced
|
||||
path, nreplaced = path:gsub("^" .. netroot .. "/", "")
|
||||
if path == netroot then
|
||||
return true, ""
|
||||
elseif path == netroot or nreplaced == 1 then
|
||||
return true, path
|
||||
else
|
||||
return false, path
|
||||
end
|
||||
end
|
||||
|
||||
-- [[ Websocket Request/Response Function & Netmount fs Initialization ]] --
|
||||
|
||||
local function wrapfs()
|
||||
local nfs = nm.createFs(state, args.path)
|
||||
|
||||
local api = {}
|
||||
|
||||
-- [[ Functions that can be directly ripped from old fs API ]] --
|
||||
local copyold = {
|
||||
"combine",
|
||||
"getName",
|
||||
"getDir",
|
||||
}
|
||||
|
||||
for _, fn in ipairs(copyold) do
|
||||
api[fn] = ofs[fn]
|
||||
end
|
||||
|
||||
-- [[ Network Dependent Overrides ]] --
|
||||
|
||||
local singleOverrides = {
|
||||
"makeDir", "delete", "list",
|
||||
"attributes", "exists", "isDir",
|
||||
"isReadOnly", "getDrive", "getSize",
|
||||
"getFreeSpace", "getCapacity"
|
||||
}
|
||||
|
||||
for _, name in ipairs(singleOverrides) do
|
||||
api[name] = function(path)
|
||||
local net
|
||||
net, path = toNetRoot(path)
|
||||
if net then
|
||||
return nfs[name](path)
|
||||
else
|
||||
local out = ofs[name](path)
|
||||
if #fs.combine(path) == 0 then
|
||||
if name == "list" then
|
||||
---@cast out string[]
|
||||
out[#out + 1] = args.path
|
||||
table.sort(out, function(a, b)
|
||||
return #a < #b
|
||||
end)
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local doubleOverrides = {
|
||||
"move",
|
||||
"copy"
|
||||
}
|
||||
|
||||
--- Bidirectionally handle relocating files
|
||||
---@param path string
|
||||
---@param dest string
|
||||
local function relocate(name, path, dest)
|
||||
if api.exists(dest) then
|
||||
error("/" .. api.combine(dest) .. ": File exists")
|
||||
end
|
||||
local pnet, dnet
|
||||
pnet, path = toNetRoot(path)
|
||||
dnet, dest = toNetRoot(dest)
|
||||
if pnet and dnet then
|
||||
nfs[name](path, dest)
|
||||
elseif not (pnet or dnet) then
|
||||
ofs[name](path, dest)
|
||||
else
|
||||
local pfs, dfs, perr, derr
|
||||
local estr = "Failed to open %s file %s"
|
||||
if pnet and not dnet then -- from server to client
|
||||
pfs, dfs = nfs, ofs
|
||||
perr, derr = "remote", "local"
|
||||
else -- from client to server
|
||||
pfs, dfs = ofs, nfs
|
||||
perr, derr = "local", "remote"
|
||||
end
|
||||
if pfs.isDir(path) then
|
||||
local list = pfs.list(path)
|
||||
for _, p in ipairs(list) do
|
||||
relocate(api.combine(path, p), api.combine(dest, p))
|
||||
end
|
||||
else
|
||||
local pfile, dfile = assert(pfs.open(path, "rb"), estr:format(perr, path)), assert(dfs.open(dest, "wb"), estr:format(derr, dest))
|
||||
dfile.write(pfile.readAll())
|
||||
pfile.close()
|
||||
dfile.close()
|
||||
if name == "move" then
|
||||
pfs.delete(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, name in ipairs(doubleOverrides) do
|
||||
api[name] = function(path, dest)
|
||||
relocate(name, path, dest)
|
||||
end
|
||||
end
|
||||
|
||||
-- [[ Network Dependent File Handles ]] --
|
||||
|
||||
api.open = function(path, mode)
|
||||
local net
|
||||
net, path = toNetRoot(path)
|
||||
if net then
|
||||
return nfs.open(path, mode)
|
||||
else
|
||||
return ofs.open(path, mode)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local romfs, i = "", 1
|
||||
for line in io.lines("rom/apis/fs.lua") do
|
||||
-- Rip out definition weirdness
|
||||
if not (i > 9 and i < 14) then
|
||||
romfs = romfs .. line .. "\n"
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
local env = {}
|
||||
for k, f in pairs(_ENV) do
|
||||
if f == _ENV then
|
||||
f = env
|
||||
else
|
||||
env[k] = f
|
||||
end
|
||||
end
|
||||
env.fs = api
|
||||
setmetatable(env, {__index = _G})
|
||||
assert(pcall(assert(load(romfs, "romfsapi", nil, env)))) -- find, complete, and isDriveRoot
|
||||
end
|
||||
|
||||
return api
|
||||
end
|
||||
|
||||
-- [[ Main Program / Connection handlers ]] --
|
||||
_G.fs = wrapfs()
|
||||
|
||||
local pok, err = pcall(parallel.waitForAny, nm.getSyncHandler(state), nm.getConnectionHandler(state))
|
||||
if not pok then
|
||||
printError(err)
|
||||
end
|
||||
state.close()
|
||||
print("Press any key to continue")
|
||||
os.pullEvent("key")
|
||||
_G.fs = ofs
|
||||
Reference in New Issue
Block a user