jfmachine

tapedl

Jul 8th, 2023 (edited)
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.44 KB | None | 0 0
  1. --[[ A Utility Program for Computronics Cassette Tapes.
  2. Provides:
  3.     - automatic tape writing from web location
  4.     - automatic tape looping
  5.     - More in future updates
  6. ]]
  7.  
  8. local args = { ... }
  9.  
  10. --tape check
  11. local tape = peripheral.find("tape_drive")
  12. if not tape then
  13.   print("This program requires a tape drive to run.")
  14.   return
  15. end
  16.  
  17. local function helpText()
  18.     print("Usage:")
  19.     print(" - 'tape-util' to display this help text")
  20.     print(" - 'tape-util loop' to loop a cassette tape")
  21.     print(" - 'tape-util dl [num files] [web dir]' to write web directory to tape")
  22.     print(" - 'tape-util dl' to display full download utility help text")
  23.     return
  24. end
  25.  
  26. local function helpTextDl()
  27.     print("Usage:")
  28.     print(" - 'tape-util dl' to display this help text")
  29.     print(" - 'tape-util dl [num files] [web dir]' to write web directory to tape")
  30.     print("directory url must contain ending forward-slash.\nFiles must be named their order number .dfpwm, ex:\n'1.dfpwm', '2.dfpwm', etc")
  31. end
  32.  
  33. --add helpText for loop util, when more features are added.
  34.  
  35.  
  36.  
  37.  
  38.  
  39. --TAPE LOOP CONTENT------------
  40. --Program for looping tracks
  41.  
  42. local tape = peripheral.find("tape_drive")
  43. if not tape then
  44. --  print("This program requires a tape drive to run.")
  45. --  return
  46. end
  47.  
  48. --Returns true if position 1 away is zero
  49. local function seekNCheck()
  50.     --seek 1 and check
  51.     tape.seek(1)
  52.     print("Seeking 1...")
  53.     if tape.read() == 0 then
  54.         return true
  55.     else return false
  56.     end
  57. end
  58.  
  59. --Checks multiple bits into distance to make sure it is actual end of track, and not just a quiet(?) part
  60. local function seekNCheckMultiple()
  61.     for i=1,10 do
  62.         if seekNCheck() == false then
  63.             return false
  64.         end
  65.     end
  66.     return true
  67. end
  68.    
  69. -- this could be made into a more efficient algo?
  70. local function findTapeEnd( ... )
  71.  
  72.     local accuracy = 100
  73.     print("Using accuracy of " .. accuracy)
  74.  
  75.     local tapeSize = tape.getSize()
  76.     print("Tape has size of: " .. tapeSize)
  77.     tape.seek(-tapeSize) -- rewind tape
  78.     local runningEnd = 0
  79.  
  80.     for i=0,tapeSize do --for every piece of the tape
  81.    
  82.         os.queueEvent("randomEvent") -- timeout
  83.         os.pullEvent()               -- prevention
  84.  
  85.  
  86.         tape.seek(accuracy) --seek forward one unit (One takes too long, bigger values not as accurate)
  87.         if tape.read() ~= 0 then --if current location is not a zero
  88.             runningEnd = i*accuracy --Update Running runningEnd var. i * accuracy gets current location in tape
  89.             print("End Candidate: " .. runningEnd)
  90.         elseif seekNCheckMultiple() then --check a few spots away to see if zero as well
  91.             return runningEnd
  92.         --else return runningEnd --otherwise, (if 0) return runningEnd
  93.         end --end if
  94.     end
  95.  
  96. end
  97.  
  98. --Main Function
  99. local function looper( ... )
  100.     print("Initializing...")
  101.     --find tape end
  102.     print("Locating end of song...")
  103.     local endLoc = findTapeEnd()
  104.     print("End of song at position " .. endLoc .. ", or " .. endLoc/6000 .. " seconds in\n")
  105.  
  106.     print("Starting Loop! Hold Ctrl+T to Terminate")
  107.     while true do
  108.         tape.seek(-tape.getSize())
  109.         tape.play()
  110.         print("... Playing")
  111.         sleep(endLoc/6000)
  112.         print("Song Ended, Restarting...")
  113.     end
  114.  
  115.     --play tape until
  116. end
  117.  
  118. --END TAPE LOOP CONTENT---------------------------------
  119.  
  120.  
  121.  
  122.  
  123.  
  124. --START TAPE DL CONTENT--------------------------------
  125. --Credit to the writers of Computronics for the bulk of wrtieTapeModified() function, see README for more info.
  126. local function writeTapeModified(relPath)
  127.     --check for tape drive
  128.     local tape = peripheral.find("tape_drive")
  129.     if not tape then
  130.         print("This program requires a tape drive to run.")
  131.         return
  132.     end
  133.   local file, msg, _, y, success
  134.   local block = 8192 --How much to read at a time
  135.  
  136.   -- if not confirm("Are you sure you want to write to this tape?") then return end
  137.   tape.stop()
  138.   --tape.seek(-tape.getSize()) --MODIFIED this part has been removed to stop seeking back to start between writes
  139.   tape.stop() --Just making sure
  140.  
  141.   local path = shell.resolve(relPath)
  142.   local bytery = 0 --For the progress indicator
  143.   local filesize = fs.getSize(path)
  144.   print("Path: " .. path)
  145.   file, msg = fs.open(path, "rb")
  146.   if not fs.exists(path) then msg = "file not found" end
  147.   if not file then
  148.     printError("Failed to open file " .. relPath .. (msg and ": " .. tostring(msg)) or "")
  149.     return
  150.   end
  151.  
  152.   print("Writing...")
  153.  
  154.   _, y = term.getCursorPos()
  155.  
  156.   if filesize > tape.getSize() then
  157.     term.setCursorPos(1, y)
  158.     printError("Error: File is too large for tape, shortening file")
  159.     _, y = term.getCursorPos()
  160.     filesize = tape.getSize()
  161.   end
  162.  
  163.   repeat
  164.     local bytes = {}
  165.     for i = 1, block do
  166.       local byte = file.read()
  167.       if not byte then break end
  168.       bytes[#bytes + 1] = byte
  169.     end
  170.     if #bytes > 0 then
  171.       if not tape.isReady() then
  172.         io.stderr:write("\nError: Tape was removed during writing.\n")
  173.         file.close()
  174.         return
  175.       end
  176.       term.setCursorPos(1, y)
  177.       bytery = bytery + #bytes
  178.       term.write("Read " .. tostring(math.min(bytery, filesize)) .. " of " .. tostring(filesize) .. " bytes...")
  179.       for i = 1, #bytes do
  180.         tape.write(bytes[i])
  181.       end
  182.       sleep(0)
  183.     end
  184.   until not bytes or #bytes <= 0 or bytery > filesize
  185.   file.close()
  186.   tape.stop()
  187.   --tape.seek(-tape.getSize()) --MODIFIED same reaosn as above...
  188.   tape.stop() --Just making sure
  189.   print("\nDone.")
  190. end
  191.  
  192. local function tapeDl(numParts,urls)
  193.     --check for tape drive.
  194.     local tape = peripheral.find("tape_drive")
  195.     if not tape then
  196.         print("This program requires a tape drive to run.")
  197.         return
  198.     end
  199.  
  200.     local i = 1 --iterator
  201.  
  202.     --Main Loop
  203.     while i <= tonumber(numParts) do
  204.         shell.run("wget", "" .. urls[i+2], "/tmp/temp_dl.dfpwm") --wget file
  205.         writeTapeModified("/tmp/temp_dl.dfpwm") --write to tape
  206.         shell.run("rm", "/tmp/temp_dl.dfpwm") -- rm temp file
  207.         i = i + 1 -- i++
  208.     end
  209.     tape.seek(-tape.getSize()) --rewind tape
  210. end
  211. --END TAPE DL CONTENT----------------------------------
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218. if args[1] == "loop" then
  219.     looper()
  220. elseif args[1] == "dl" then
  221.     if args[2] ~= nil then
  222.         print("running tapeDl")
  223.         tapeDl(args[2],args)
  224.     else helpTextDl()
  225.     end
  226. else
  227.     helpText()
  228. end
  229.  
  230.  
  231. --[[ known issues:
  232. tape-util dl, does not rewind at start.
  233. tape-util dl, should say when it rewinds at end, that the program is finished.
  234. findTapeEnd, timeout protection might not be necessary anymore, adding bloat.
  235. looper(), could do with some cleaner prints. can screen be cleared?
  236. looper(), needs accuracy argument! will be very slow on larger cassettes to find length
  237. ]]
Add Comment
Please, Sign In to add comment