1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-11-08 11:38:07 +11:00
OC-KittenOS/code/libs/sys-filevfs.lua
20kdc f761ad5824 Remove overwrite confirmations because life is short and UX nitpick bugs are long.
Have fun with this. If anyone complains I'm calling it the April 1st release.
2020-03-31 18:10:55 +01:00

217 lines
5.7 KiB
Lua

-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- Used by filedialog to provide a sane relative environment.
-- Essentially, the filedialog is just a 'thin' UI wrapper over this.
-- Returns the root node.
local function dialog(name, parent)
return {
name = name,
list = function () return {{"Back", function () return nil, parent end}} end,
unknownAvailable = false,
selectUnknown = function (text) end
}
end
local getFsNode, getRoot
local setupCopyNode
function setupCopyNode(parent, myRoot, op, complete)
local function handleResult(aRes, res)
if aRes then
return complete(res, true)
else
return nil, setupCopyNode(parent, res, op, complete)
end
end
return {
name = "(" .. op .. ") " .. myRoot.name,
list = function ()
local l = {}
table.insert(l, {"Cancel Operation: " .. op, function ()
complete(nil, false)
return false, parent
end})
for _, v in ipairs(myRoot.list()) do
table.insert(l, {v[1], function ()
return handleResult(v[2]())
end})
end
return l
end,
unknownAvailable = myRoot.unknownAvailable,
selectUnknown = function (tx)
return handleResult(myRoot.selectUnknown(tx))
end
}
end
local function setupCopyVirtualEnvironment(fs, parent, fwrap, impliedName)
if not fwrap then
return false, dialog("Could not open source", parent)
end
local myRoot = getRoot(fs, true, impliedName)
-- Setup wrapping node
return setupCopyNode(parent, myRoot, "Copy", function (fwrap2, intent)
if not fwrap2 then
fwrap.close()
if intent then
return false, dialog("Could not open dest.", parent)
end
return false, parent
end
local data = fwrap.read(neo.readBufSize)
while data do
fwrap2.write(data)
data = fwrap.read(neo.readBufSize)
end
fwrap.close()
fwrap2.close()
return false, dialog("Completed copy.", parent)
end)
end
function getFsNode(fs, parent, fsc, path, mode, impliedName)
local va = fsc.address:sub(1, 4)
local fscrw = not fsc.isReadOnly()
local dir = path:sub(#path, #path) == "/"
local confirmedDel = false
local t
local function selectUnknown(text)
-- Relies on text being nil if used in leaf node
local rt, re = require("sys-filewrap").create(fsc, path .. (text or ""), mode)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return true, rt
end
t = {
name = ((dir and "DIR: ") or "FILE: ") .. va .. path,
list = function ()
local n = {}
n[1] = {"..", function ()
return nil, parent
end}
if dir then
for k, v in ipairs(fsc.list(path)) do
local nm = "F: " .. v
local fp = path .. v
local cDir = fsc.isDirectory(fp)
if cDir then
nm = "D: " .. v
end
if (not cDir) and (fscrw or mode == false) and (mode ~= nil) then
local vn = v
n[k + 1] = {nm, function () return selectUnknown(vn) end}
else
n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode, impliedName) end}
end
end
else
table.insert(n, {"Copy", function ()
local rt, re = require("sys-filewrap").create(fsc, path, false)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
end})
end
if fscrw then
if dir then
table.insert(n, {"Mk. Directory", function ()
return nil, {
name = "MKDIR...",
list = function () return {{
"Cancel", function ()
return false, t
end
}} end,
unknownAvailable = true,
selectUnknown = function (text)
fsc.makeDirectory(path .. text)
return nil, dialog("Done!", t)
end
}
end})
end
if path ~= "/" then
local delText = "Delete"
if confirmedDel then
delText = "Delete <ARMED>"
end
table.insert(n, {delText, function ()
if not confirmedDel then
confirmedDel = true
return nil, t
end
fsc.remove(path)
return nil, dialog("Done.", parent)
end})
else
table.insert(n, {"Relabel Disk", function ()
return nil, {
name = "Disk Relabel...",
list = function () return {{
fsc.getLabel() or "Cancel",
function ()
return false, t
end
}} end,
unknownAvailable = true,
selectUnknown = function (tx)
fsc.setLabel(tx)
return false, t
end
}
end})
end
end
if not dir then
elseif impliedName then
table.insert(n, {"Implied: " .. impliedName, function ()
return selectUnknown(impliedName)
end})
end
return n
end,
unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw),
selectUnknown = selectUnknown
}
return t
end
function getRoot(fs, mode, defName)
local t
t = {
name = "DRVS:",
list = function ()
local l = {}
for fsi in fs.list() do
local id = fsi.getLabel()
if fsi == fs.primary then
id = "NEO" .. ((id and (":" .. id)) or " Disk")
elseif fsi == fs.temporary then
id = "RAM" .. ((id and (" " .. id)) or "Disk")
else
id = id or "Disk"
end
local used, total = fsi.spaceUsed(), fsi.spaceTotal()
local amount = string.format("%02i", math.ceil((used / total) * 100))
local mb = math.floor(total / (1024 * 1024))
if fsi.isReadOnly() then
id = "RO " .. amount .. "% " .. mb .. "M " .. id
else
id = "RW " .. amount .. "% " .. mb .. "M " .. id
end
table.insert(l, {fsi.address:sub(1, 4) .. " " .. id, function ()
return nil, getFsNode(fs, t, fsi, "/", mode, defName)
end})
end
return l
end,
unknownAvailable = false,
selectUnknown = function (text)
return false, dialog("Ow, that hurt...", t)
end
}
return t
end
return getRoot