Update and rename tapewrite.lua to mtape.lua

Completely remade and added features
This commit is contained in:
LDDestroier 2023-09-30 03:16:32 -04:00 committed by GitHub
parent 91289aa72e
commit de5df4f760
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 330 additions and 51 deletions

330
mtape.lua Normal file
View File

@ -0,0 +1,330 @@
-- Mtape
-- tape managing program
-- made by LDDestroier
local function checkOption(argName, argInfo, isShort)
for i = 1, #argInfo do
if argInfo[i][isShort and 2 or 3] == argName then
return i
end
end
return false
end
local function argParse(argInput, argInfo)
local sDelim = "-"
local lDelim = "--"
local optOutput = {}
local argOutput = {}
local argError = {}
local usedTokens = {}
local lOpt, sOpt, optNum
for i = 1, #argInfo do
optOutput[i] = {}
end
for i = 1, #argInput do
lOpt = argInput[i]
-- check type of delimiter
if lOpt:sub(1, #lDelim) == lDelim then
-- handle long delimiter
lOpt = lOpt:sub(#lDelim + 1)
optNum = checkOption(lOpt, argInfo, false)
if optNum then
if argInfo[optNum][1] == 0 then
optOutput[optNum] = true
else
optOutput[optNum] = {}
for ii = 1, argInfo[optNum][1] do
if argInput[i + ii] then
optOutput[optNum][#optOutput[optNum] + 1] = argInput[i + ii]
usedTokens[i + ii] = true
else
argError[#argError + 1] = "expected parameter " .. tostring(ii) .. " for argument " .. lDelim .. lOpt
break
end
end
i = i + argInfo[optNum][1]
end
else
argError[#argError + 1] = "invalid argument " .. lDelim .. lOpt
end
elseif lOpt:sub(1, #sDelim) == sDelim then
-- handle short delimiter
lOpt = lOpt:sub(#sDelim + 1)
for si = 1, #lOpt do
sOpt = lOpt:sub(si, si)
optNum = checkOption(sOpt, argInfo, true)
if optNum then
if argInfo[optNum][1] == 0 then
optOutput[optNum] = true
elseif si == #lOpt then
optOutput[optNum] = {}
for ii = 1, argInfo[optNum][1] do
if argInput[i + ii] then
optOutput[optNum][#optOutput[optNum] + 1] = argInput[i + ii]
usedTokens[i + ii] = true
else
argError[#argError + 1] = "expected parameter " .. tostring(ii) .. " for argument " .. sDelim .. sOpt
break
end
end
i = i + argInfo[optNum][1]
else
argError[#argError + 1] = "options with parameters must be at the end of their group"
break
end
else
argError[#argError + 1] = "invalid argument " .. sDelim .. sOpt
break
end
end
elseif not usedTokens[i] then
argOutput[#argOutput + 1] = lOpt
end
end
return argOutput, optOutput, argError
end
local function getHelp(specify)
if not specify then
print("mtape [file / url] (label)")
print("mtape [-i --info]")
print("mtape [-e --erase]")
print("mtape [-u --unclean]")
print("mtape [-c --cc-media]")
else
if specify == "--info" then
print("Prints information about the connected tape drive.")
print("This includes the label, size, minutes length, and current seeking position.")
elseif specify == "--erase" then
print("Erases the connected tape drive.")
elseif specify == "--unclean" then
print("Normally, tapes are erased before writing them anew. Use this option to not erase them first.")
print("If the tape has something longer written to it beforehand, you'll hear it after whatever is written now.")
elseif specify == "--ldd-github" then
print("Adds URL info from LDDestroier's personal CC-Media github to make it easier to pull from there.")
print("Ex. 'tapey -c krabii'")
print(" 'tapey -c simple'")
end
end
end
local function getFileContents(path, isURL)
local file, contents
if isURL then
file = http.get(path, nil, true)
else
file = fs.open(fs.combine(shell.dir(), path))
end
if not file then
return false, ""
else
contents = file.readAll()
file.close()
return true, contents
end
end
local function getTapeDrive(side)
local tape
if side then
tape = peripheral.wrap(side)
if not tape then
return false, "No such tape drive found.", 0
elseif peripheral.getType(tape) ~= "tape_drive" then
return false, "Not a tape drive.", 0
else
return true, tape, tape.getSize()
end
else
tape = peripheral.find("tape_drive")
if not tape then
return false, "Tape drive not connected.", 0
else
return true, tape, tape.getSize()
end
end
end
local function writeToTape(tape, contents, tapeName)
local output = ""
if not tape then error("expected tape peripheral") end
if not contents then error("expected contents") end
local totalTapeSize = tape.getSize()
if tapeName then
tape.setLabel(tapeName)
end
tape.seek(-tape.getPosition())
if #contents > totalTapeSize then
contents = contents:sub(1, totalTapeSize)
output = "Tape too small. Audio was written incompletely."
end
tape.write(contents)
tape.seek(-tape.getPosition())
end
local function infoMode(tape)
local scr_x, scr_y = term.getSize()
print("Info for tape drive:")
print(("-"):rep(scr_x))
local gi = tape.getItem(1).getMetadata()
local info = {
inserted = gi ~= nil
}
local tierInfo = {
-- damage value indicates type of tape
-- value of tierInfo indicates minutes of storage
[0] = 4,
[1] = 8,
[2] = 16,
[3] = 32,
[4] = 64,
[5] = 2,
[6] = 6,
[8] = 128
}
local minute = 360000
if not info.inserted then
print("No tape inserted.")
else
info.displayname = gi.displayName
info.label = gi.media.label
info.itemname = gi.name
info.damage = gi.damage
info.minutes = tierInfo[info.damage]
info.maxsize = tape.getSize()
info.position = tape.getPosition()
print(info.displayname .. " inserted.")
print("Label: \"" .. info.label .. "\"")
write("Stores " .. tostring(info.minutes) .. " minutes")
print(" (" .. tostring(info.maxsize) .. " bytes)")
print("Seeked to " .. tostring(info.position) .. "/" .. tostring(info.maxsize))
end
return info
end
local argInfo = {
[1] = {0, "h", "help"},
[2] = {0, "i", "info"},
[3] = {1, "d", "drive"},
[4] = {0, "e", "erase"},
[5] = {0, "u", "unclean"},
[6] = {1, "c", "cc-media"}
}
local arguments, options, errors = argParse({...}, argInfo)
local tape, totalTapeSize, success, contents
if #errors > 0 then
for i = 1, #errors do
printError(errors[i])
end
return
end
local fileName = arguments[1]
local tapeName = arguments[2]
local tapeDriveName = options[3][1]
local wantedHelp = options[1] == true
local wantedInfo = options[2] == true
local wantedErase = options[4] == true
local doUnclean = options[5] == true
local getFromGithub = options[6][1]
if wantedHelp then
if wantedInfo then
getHelp("--info")
elseif wantedErase then
getHelp("--erase")
elseif doUnclean then
getHelp("--unclean")
elseif getFromGithub then
getHelp("--ldd-github")
else
getHelp()
end
return
end
-- Try to wrap specified tape drive OR find tape drive
success, tape, totalTapeSize = getTapeDrive(tapeDriveName)
if not success then
print(tape)
return
end
if wantedInfo then
infoMode(tape)
return true
end
if wantedErase then
success = writeToTape(tape, string.char(0):rep(tape.getSize()), tapeName)
print("Tape erased.")
return
end
if getFromGithub then
print("Pulling from CC-Media.")
fileName = "https://github.com/LDDestroier/CC-Media/raw/master/DFPWM/" .. getFromGithub .. ".dfpwm"
end
if not fileName then
getHelp()
return
end
-- Make file, and detect URL
if fileName:sub(1,8) == "https://" then
write("Downloading...")
success, contents = getFileContents(fileName, true)
print("Done.")
else
success, contents = getFileContents(fileName, false)
end
if not success then
error("Could not get file. Abort.")
end
-- Adds null data to the end of the file if you want a clean tape write
if doUnclean then
print("Won't clean up tape first.")
else
contents = contents .. string.char(0):rep(totalTapeSize - #contents)
end
print("Writing...")
success = writeToTape(tape, contents, tapeName)
if success then
print(success)
print("Nonetheless, it is written.")
else
print("\nIt is written.")
end
return true

View File

@ -1,51 +0,0 @@
local tArg = {...}
local fileName = tArg[1]
local tapeName = tArg[2]
local function getHelp()
print("tapewrite [file / url] [name]")
end
if not fileName then
getHelp()
return
end
local tape = peripheral.find("tape_drive")
if not tape then
print("Tape drive not connected.")
return
end
local totalSize = tape.getSize()
-- Make file, and detect URL
local file, contents
if fileName:sub(1,8) == "https://" then
write("Downloading...")
file = http.get(fileName, nil, true)
print("Done.")
else
file = fs.open(fs.combine(shell.dir(), fileName), "r")
end
contents = file.readAll()
file.close()
if tapeName then
tape.setLabel(tapeName)
end
tape.seek(-tape.getPosition())
print("Writing...")
if #contents > totalSize then
contents = contents:sub(1, totalSize)
print("Tape too small. Audio was written incompletely.")
end
tape.write(contents)
tape.seek(-tape.getPosition())
print("\nIt is written. (" .. tostring(#contents) .. " bytes)")