193 lines
5.0 KiB
Plaintext
193 lines
5.0 KiB
Plaintext
--:Minify:--
|
|
local apis = ({...})[1]
|
|
local BOOT_DRIVE_PATH=apis.BOOT_DRIVE_PATH or "/$"
|
|
local fs = apis.fs
|
|
local native = apis.peripheral
|
|
local peripheral = {}
|
|
local sides = {"top", "bottom", "left", "right", "front", "back"}
|
|
|
|
function peripheral.getType(name)
|
|
if native.isPresent(name) then
|
|
return native.getType(name)
|
|
end
|
|
for n = 1, #sides do
|
|
local side = sides[n]
|
|
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
|
|
return native.call(side, "getTypeRemote", name)
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function peripheral.getNames()
|
|
local names = {}
|
|
for n = 1, #sides do
|
|
local side = sides[n]
|
|
if native.isPresent(side) then
|
|
table.insert(names, side)
|
|
end
|
|
if native.hasType(side, "peripheral_hub") then
|
|
local hubSides = native.call(side, "getConnectedSides")
|
|
for _, hubSide in ipairs(hubSides) do
|
|
table.insert(names, hubSide)
|
|
end
|
|
end
|
|
end
|
|
return names
|
|
end
|
|
|
|
---------------------------------------------------------
|
|
-- STORAGE
|
|
---------------------------------------------------------
|
|
local disks = {} -- real disks
|
|
local internal = {} -- "$" disk
|
|
|
|
---------------------------------------------------------
|
|
-- HELPERS
|
|
---------------------------------------------------------
|
|
local function norm(path)
|
|
if not path or path == "" then return "/" end
|
|
return fs.combine("/", path)
|
|
end
|
|
|
|
--- Creates a disk object given a base path
|
|
local function createDisk(id, basePath, readonly, periph)
|
|
basePath = norm(basePath)
|
|
|
|
local disk = {address=id,isReadOnly=function() return readonly end}
|
|
|
|
function disk:spaceUsed()
|
|
return fs.getCapacity(basePath) - fs.getFreeSpace(basePath)
|
|
end
|
|
|
|
function disk:spaceTotal()
|
|
return fs.getCapacity(basePath)
|
|
end
|
|
|
|
function disk:list(path)
|
|
local p = fs.combine(basePath, path)
|
|
if not fs.exists(p) or not fs.isDir(p) then return nil, "not directory" end
|
|
return fs.list(p)
|
|
end
|
|
|
|
function disk:fileExists(path)
|
|
local p = fs.combine(basePath, path)
|
|
return fs.exists(p) and not fs.isDir(p)
|
|
end
|
|
|
|
function disk:directoryExists(path)
|
|
local p = fs.combine(basePath, path)
|
|
return fs.exists(p) and fs.isDir(p)
|
|
end
|
|
|
|
function disk:type(path)
|
|
local p = fs.combine(basePath, path)
|
|
if not fs.exists(p) then
|
|
return nil
|
|
elseif fs.isDir(p) then
|
|
return "directory"
|
|
else
|
|
return "file"
|
|
end
|
|
end
|
|
|
|
function disk:makeDirectory(path)
|
|
local p = fs.combine(basePath, path)
|
|
fs.makeDir(p)
|
|
return true
|
|
end
|
|
|
|
function disk:remove(path)
|
|
local p = fs.combine(basePath, path)
|
|
if fs.exists(p) then fs.delete(p) end
|
|
return true
|
|
end
|
|
|
|
function disk:setLabel(label)
|
|
periph.setLabel(label)
|
|
end
|
|
|
|
function disk:getLabel(label)
|
|
return periph.getLabel()
|
|
end
|
|
|
|
function disk:attributes(path)
|
|
local p = fs.combine(basePath, path)
|
|
return fs.attributes(p)
|
|
end
|
|
|
|
function disk:open(path, mode)
|
|
local p = fs.combine(basePath, path)
|
|
return fs.open(p, mode)
|
|
end
|
|
|
|
return disk
|
|
end
|
|
|
|
---------------------------------------------------------
|
|
-- INTERNAL DISK "$" (mapped to "/")
|
|
---------------------------------------------------------
|
|
internal["$"] = createDisk("$", BOOT_DRIVE_PATH, false, {
|
|
setLabel=function(label)
|
|
local h = fs.open("/.label", "w")
|
|
h.write(label)
|
|
h.close()
|
|
end,
|
|
getLabel=function()
|
|
local h = fs.open("/.label", "r")
|
|
local label = h.readAll()
|
|
h.close()
|
|
return label
|
|
end
|
|
})
|
|
|
|
---------------------------------------------------------
|
|
-- SCAN REAL DISK PERIPHERALS
|
|
---------------------------------------------------------
|
|
local function refresh()
|
|
-- remove disks that no longer exist
|
|
for id, _ in pairs(disks) do
|
|
if not peripheral.getType(id) then
|
|
disks[id] = nil
|
|
end
|
|
end
|
|
|
|
-- detect new disks
|
|
for _, name in ipairs(peripheral.getNames()) do
|
|
if peripheral.getType(name) == "disk" then
|
|
if not disks[name] then
|
|
local mount = disk.getMountPath(name)
|
|
if mount then
|
|
disks[name] = createDisk(name, mount, false, disk)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------
|
|
-- ITERATOR
|
|
---------------------------------------------------------
|
|
local function iter()
|
|
refresh()
|
|
-- first internal
|
|
local combined = {}
|
|
|
|
for id, obj in pairs(internal) do
|
|
combined[id] = obj
|
|
end
|
|
for id, obj in pairs(disks) do
|
|
combined[id] = obj
|
|
end
|
|
|
|
return pairs(combined)
|
|
end
|
|
|
|
---------------------------------------------------------
|
|
-- MODULE RETURN
|
|
---------------------------------------------------------
|
|
return {
|
|
refresh = refresh,
|
|
list = iter
|
|
}
|