disk copy app
This commit is contained in:
200
core/DiskCopy.lua
Normal file
200
core/DiskCopy.lua
Normal file
@@ -0,0 +1,200 @@
|
||||
local Ansi = require('ansi')
|
||||
local Event = require('event')
|
||||
local UI = require('ui')
|
||||
local Util = require('util')
|
||||
|
||||
local colors = _G.colors
|
||||
local fs = _G.fs
|
||||
local peripheral = _G.peripheral
|
||||
|
||||
local drives = { }
|
||||
peripheral.find('drive', function(n, v)
|
||||
if not drives.left then
|
||||
drives.left = Util.shallowCopy(v)
|
||||
drives.left.name = n
|
||||
else
|
||||
drives.right = Util.shallowCopy(v)
|
||||
drives.right.name = n
|
||||
end
|
||||
end)
|
||||
|
||||
if not (drives.left and drives.right) then
|
||||
error('Two drives are required')
|
||||
end
|
||||
|
||||
local COPY_LEFT = 1
|
||||
local COPY_RIGHT = 2
|
||||
local directions = {
|
||||
[ COPY_LEFT ] = { text = '-->>' },
|
||||
[ COPY_RIGHT ] = { text = '<<--' },
|
||||
}
|
||||
local copyDir = COPY_LEFT
|
||||
|
||||
local page = UI.Page {
|
||||
linfo = UI.Window {
|
||||
x = 2, y = 2, ey = 5, width = 18,
|
||||
},
|
||||
rinfo = UI.Window {
|
||||
x = -19, y = 2, ey = 5, width = 18,
|
||||
},
|
||||
dir = UI.Button {
|
||||
x = 17, y = 7, width = 6,
|
||||
event = 'change_dir',
|
||||
},
|
||||
progress = UI.ProgressBar {
|
||||
x = 2, ex = -2, y = -4,
|
||||
backgroundColor = colors.black,
|
||||
},
|
||||
copyButton = UI.Button {
|
||||
x = -7, y = -2,
|
||||
text = 'Copy',
|
||||
event = 'copy',
|
||||
inactive = true,
|
||||
},
|
||||
warning = UI.Text {
|
||||
x = 2, ex = -9, y = -2,
|
||||
textColor = colors.orange,
|
||||
},
|
||||
notification = UI.Notification { },
|
||||
}
|
||||
|
||||
function page:enable()
|
||||
Util.merge(self.dir, directions[copyDir])
|
||||
UI.Page.enable(self)
|
||||
end
|
||||
|
||||
local function isValid(drive)
|
||||
return drive.isDiskPresent() and drive.getMountPath()
|
||||
end
|
||||
|
||||
local function needsLabel(drive)
|
||||
return drive.isDiskPresent() and not drive.getMountPath()
|
||||
end
|
||||
|
||||
function page:drawInfo(drive, textArea)
|
||||
local function getLabel()
|
||||
return not drive.isDiskPresent() and 'empty' or
|
||||
not drive.getMountPath() and 'invalid' or
|
||||
drive.getDiskLabel() or 'unlabeled'
|
||||
end
|
||||
|
||||
local function getUsed()
|
||||
return isValid(drive) and fs.getSize(drive.getMountPath(), true) or 0
|
||||
end
|
||||
|
||||
local function getFree()
|
||||
return isValid(drive) and fs.getFreeSpace(drive.getMountPath()) or 0
|
||||
end
|
||||
|
||||
textArea:setCursorPos(1, 1)
|
||||
textArea:print(string.format('Drive: %s%s%s\nLabel: %s%s%s\nUsed: %s%s%s\nFree: %s%s%s',
|
||||
Ansi.yellow, drive.name, Ansi.reset,
|
||||
isValid(drive) and Ansi.yellow or Ansi.orange, getLabel():sub(1, 10), Ansi.reset,
|
||||
Ansi.yellow, Util.toBytes(getUsed()), Ansi.reset,
|
||||
Ansi.yellow, Util.toBytes(getFree()), Ansi.reset))
|
||||
end
|
||||
|
||||
function page:scan()
|
||||
local showWarning = needsLabel(drives.left) or needsLabel(drives.right)
|
||||
local valid = isValid(drives.left) and isValid(drives.right)
|
||||
|
||||
self.warning.value = showWarning and 'Computers must be labeled'
|
||||
self.copyButton.inactive = not valid
|
||||
|
||||
self:draw()
|
||||
self.progress:centeredWrite(1, 'Analyzing Disks..')
|
||||
self.progress:sync()
|
||||
|
||||
self:drawInfo(drives.left, self.linfo)
|
||||
self:drawInfo(drives.right, self.rinfo)
|
||||
|
||||
self.progress:clear()
|
||||
end
|
||||
|
||||
function page:copy(sdrive, tdrive)
|
||||
local totalFiles = 0
|
||||
local throttle = Util.throttle()
|
||||
|
||||
local function countFiles(source, target)
|
||||
if fs.isDir(source) then
|
||||
local list = fs.list(source)
|
||||
for _,f in pairs(list) do
|
||||
countFiles(fs.combine(source, f), fs.combine(target, f))
|
||||
end
|
||||
else
|
||||
totalFiles = totalFiles + 1
|
||||
end
|
||||
throttle()
|
||||
end
|
||||
|
||||
local copied = 0
|
||||
local function rawCopy(source, target)
|
||||
if fs.isDir(source) then
|
||||
if not fs.exists(target) then
|
||||
fs.makeDir(target)
|
||||
end
|
||||
local list = fs.list(source)
|
||||
for _,f in pairs(list) do
|
||||
rawCopy(fs.combine(source, f), fs.combine(target, f))
|
||||
end
|
||||
|
||||
else
|
||||
if fs.exists(target) then
|
||||
fs.delete(target)
|
||||
end
|
||||
|
||||
fs.copy(source, target)
|
||||
copied = copied + 1
|
||||
self.progress.value = copied * 100 / totalFiles
|
||||
self.progress:draw()
|
||||
self.progress:sync()
|
||||
end
|
||||
throttle()
|
||||
end
|
||||
|
||||
self.progress:centeredWrite(1, 'Computing..')
|
||||
self.progress:sync()
|
||||
countFiles(sdrive.getMountPath(), tdrive.getMountPath())
|
||||
|
||||
self.progress:clear()
|
||||
rawCopy(sdrive.getMountPath(), tdrive.getMountPath())
|
||||
self.progress:centeredWrite(1, 'Copy Complete', colors.lime, colors.black)
|
||||
self.progress:sync()
|
||||
|
||||
self.progress.value = 0
|
||||
self.progress:clear()
|
||||
|
||||
self:scan()
|
||||
end
|
||||
|
||||
function page:eventHandler(event)
|
||||
if event.type == 'change_dir' then
|
||||
copyDir = (copyDir) % 2 + 1
|
||||
Util.merge(self.dir, directions[copyDir])
|
||||
self.dir:draw()
|
||||
|
||||
elseif event.type == 'copy' then
|
||||
if copyDir == COPY_LEFT then
|
||||
self:copy(drives.left, drives.right)
|
||||
else
|
||||
self:copy(drives.right, drives.left)
|
||||
end
|
||||
|
||||
else
|
||||
return UI.Page.eventHandler(self, event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
Event.on({ 'disk', 'disk_eject' }, function()
|
||||
page:scan()
|
||||
page:sync()
|
||||
end)
|
||||
|
||||
Event.onTimeout(.2, function()
|
||||
page:scan()
|
||||
page:sync()
|
||||
end)
|
||||
|
||||
UI:setPage(page)
|
||||
UI:pullEvents()
|
||||
@@ -24,6 +24,11 @@ Needs work
|
||||
\130\139\141\0311\130\131\0310\142\135\129",
|
||||
run = "Events.lua",
|
||||
},
|
||||
[ "f1e14c30480042e8c71b5482d92ef161815b915e" ] = {
|
||||
title = "DiskCopy",
|
||||
category = "System",
|
||||
run = "DiskCopy",
|
||||
},
|
||||
[ "7ef35cac539f84722b0a988caee03b2df734c56a" ] = {
|
||||
title = "AppStore",
|
||||
category = "System",
|
||||
|
||||
Reference in New Issue
Block a user