MKlegoman357

RedFile 1.3

May 26th, 2013
441
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 26.45 KB | None | 0 0
  1. --Version:1.3
  2. --
  3. --Easy to use RedNet file Sender and Receiver with graphical interface
  4. --    - To open file browser just run the program
  5. --      - In file browser you can choose your file, open menu (press m) and send it to any other computer that has this program
  6. --      - File browser also has functions like open, edit, create folder/file, delete
  7. --    - You can also run this program with arguments (this way you can send and get files using other programs; eg.: shell.run("RedFile", "send", "14", "myfile"))
  8. --      - Sending: RedFile send <computer id> <file>
  9. --          RedFile - this program
  10. --          send - 1st argument tells what to do, in this case 'send'
  11. --          <computer id> - 2nd argument is ID of computer that you want to send to (recipient)
  12. --          <file> 3rd argument is file you want to send
  13. --          
  14. --          Example: RedFile send 28 myprogram
  15. --        
  16. --      - Getting: RedFile get <computer id>
  17. --          RedFile - this program
  18. --          get - 1st argument tells what to do, in this case 'get'
  19. --          <computer id> - 2nd argument is optional; use it if you want to get file from a specific computer
  20. --          
  21. --          Example: RedFile get 28
  22. --    
  23. --     features:
  24. --       - Sending any type of file with any characters
  25. --       - When getting a file you can save it where ever you want
  26. --       - If there is 1 modem attached on a computer - uses that; If there is more than 1 modem - lets you choose wich one you want to use
  27. --       - See proggress in percents when sending and getting a file (try sending rom/programs/secret/alongtimeago, it will crash when it will try to save it, but you will see how it shows the proggress)
  28. --       - You can use this as your file browser
  29. --       - Working on Advanced and normal computers
  30.  
  31. local version = "1.3"
  32. local sides = {}
  33. local side = ""
  34. local col = term.isColor()
  35. local arg = {...}
  36. local path = ""
  37. local sendID = 0
  38. local sendb = false
  39. local getb = false
  40. local running = true
  41. local programName = shell.getRunningProgram()
  42.  
  43. --Helper functions
  44.  
  45. local function getSides ()
  46.   local sides = {}
  47.  
  48.   for _, sid in pairs(rs.getSides()) do
  49.     if peripheral.isPresent(sid) and peripheral.getType(sid) == "modem" then
  50.      sides[#sides + 1] = sid
  51.     end
  52.   end
  53.  
  54.   return sides
  55. end
  56.  
  57. local function clear ()
  58.   term.clear()
  59.   term.setCursorPos(1, 1)
  60. end
  61.  
  62. local function resetColors ()
  63.   term.setTextColor(colors.white)
  64.   term.setBackgroundColor(colors.black)
  65. end
  66.  
  67. local function reset ()
  68.   resetColors()
  69.   clear()
  70. end
  71.  
  72. local function conTColor (ColorColor)
  73.   if col or ColorColor == colors.white or ColorColor == colors.black then
  74.     return ColorColor or colors.white
  75.   else
  76.     return colors.black
  77.   end
  78. end
  79.  
  80. local function conBColor (ColorColor)
  81.   if col or ColorColor == colors.white or ColorColor == colors.black then
  82.     return ColorColor or colors.black
  83.   else
  84.     return colors.white
  85.   end
  86. end
  87.  
  88. local function writeText (text, tColor, bColor, x, y, clear)
  89.   if not x then
  90.     x = term.getCursorPos()
  91.   end
  92.  
  93.   if not y then
  94.     _, y = term.getCursorPos()
  95.   end
  96.  
  97.   if tColor then
  98.     term.setTextColor(conTColor(tColor))
  99.   end
  100.  
  101.   if bColor then
  102.     term.setBackgroundColor(conBColor(bColor))
  103.   end
  104.  
  105.   term.setCursorPos(x, y)
  106.  
  107.   if clear == true then
  108.     term.clear()
  109.   end
  110.  
  111.   term.write(tostring(text))
  112. end
  113.  
  114. local function vRep (text, times, tColor, bColor, x, y)
  115.   local w, h = term.getSize()
  116.  
  117.   if not x then
  118.     x = term.getCursorPos()
  119.   end
  120.  
  121.   if not y then
  122.     _, y = term.getCursorPos()
  123.   end
  124.  
  125.   times = times or 1
  126.  
  127.   for i = 1, times do
  128.     writeText(text, tColor, bColor, x, y)
  129.     y = y + 1
  130.   end
  131. end
  132.  
  133. local function clamp (Number, min, max)
  134.   if Number < min then
  135.     return min
  136.   elseif Number > max then
  137.     return max
  138.   else
  139.     return Number
  140.   end
  141. end
  142.  
  143. local function round (Number)
  144.   return math.floor(Number + 0.5)
  145. end
  146.  
  147. local function getMin (...)
  148.   local arg = {...}
  149.   local num
  150.  
  151.   for i, number in pairs(arg) do
  152.     if not arg[i - 1] then
  153.       num = tonumber(number)
  154.     else
  155.       if tonumber(number) < num then
  156.         num = number
  157.       end
  158.     end
  159.   end
  160.  
  161.   return num
  162. end
  163.  
  164. local function getMax (...)
  165.   local arg = {...}
  166.   local num
  167.  
  168.   for i, number in pairs(arg) do
  169.     if not arg[i - 1] then
  170.       num = tonumber(number)
  171.     else
  172.       if tonumber(number) > num then
  173.         num = number
  174.       end
  175.     end
  176.   end
  177.  
  178.   return num
  179. end
  180.  
  181. local function selectionMenu(TableSelections, NumberKey, limit)
  182.   local xO, yO = term.getCursorPos()
  183.   local x, y = term.getCursorPos()
  184.   local xm, ym = term.getCursorPos()
  185.   local w, h = term.getSize()
  186.   local selection = 1
  187.   local pos = 1
  188.   local enable = false
  189.  
  190.   limit = limit or #TableSelections
  191.  
  192.   local function scroll ()
  193.     if selection < pos then
  194.       pos = selection
  195.     elseif selection > pos + limit - 1 then
  196.       pos = selection - limit + 1
  197.     end
  198.   end
  199.  
  200.   while true do
  201.   x, y = xO + 1, yO
  202.   term.setCursorPos(x, y)
  203.  
  204.   scroll()
  205.  
  206.   for n = pos, getMin(#TableSelections, limit + pos - 1) do
  207.     resetColors()
  208.    
  209.     if TableSelections[n] == "" then
  210.       term.setCursorPos(x, y)
  211.       term.write(TableSelections[n])
  212.       y = y + 1
  213.     elseif TableSelections[n] then
  214.       term.setCursorPos(x, y)
  215.      
  216.       if selection == n then
  217.         term.setBackgroundColor(conBColor(colors.blue))
  218.         term.setTextColor(conTColor(colors.yellow))
  219.       end
  220.      
  221.       term.write(TableSelections[n])
  222.       y = y + 1
  223.     end
  224.   end
  225.  
  226.   resetColors()
  227.  
  228.   x, y = xO, yO
  229.   term.setCursorPos(x, y)
  230.  
  231.   if #TableSelections > 1 then
  232.     local b = limit < #TableSelections
  233.     local limit = getMin(#TableSelections, limit)
  234.     term.setBackgroundColor(conBColor(colors.blue))
  235.     term.setTextColor(conTColor(colors.yellow))
  236.    
  237.     local start = getMax(round(pos / #TableSelections * limit), 1)
  238.     local finish = getMin(start + getMax(round(limit / #TableSelections * limit), 1), limit)
  239.    
  240.     for n = start, finish do
  241.       term.setCursorPos(x, y + n - 1)
  242.       term.write(" ")
  243.     end
  244.   end
  245.  
  246.   local event, p1, x, y = os.pullEvent()
  247.  
  248.   if event == "key" then
  249.     if p1 == keys.down then
  250.       repeat
  251.         selection = selection + 1
  252.       until TableSelections[selection] ~= "" or selection <= 1
  253.     elseif p1 == keys.up then
  254.       repeat
  255.         selection = selection - 1
  256.       until TableSelections[selection] ~= "" or selection >= #TableSelections
  257.     elseif p1 == keys.enter then
  258.       return selection
  259.     elseif NumberKey and p1 == NumberKey then
  260.       return selection, true
  261.     else
  262.       x, y = xO, yO
  263.       term.setCursorPos(x, y)
  264.     end
  265.   elseif event == "mouse_scroll" then
  266.     if p1 < 0 then
  267.       repeat
  268.         selection = selection - 1
  269.       until TableSelections[selection] ~= "" or selection >= #TableSelections
  270.     else
  271.       repeat
  272.         selection = selection + 1
  273.       until TableSelections[selection] ~= "" or selection <= 1
  274.     end
  275.   elseif event == "mouse_click" then
  276.     local xw, yw = xO, yO
  277.     xp, yp = xO, yO
  278.     local ok = false
  279.    
  280.     enable = false
  281.    
  282.     for n = pos, getMin(#TableSelections, limit + pos - 1) do
  283.       if y == yw and x >= xw + 1 and x <= xw + #TableSelections[n] then
  284.         selection = n
  285.         ok = true
  286.         break
  287.       end
  288.      
  289.       yw = yw + 1
  290.     end
  291.    
  292.     if not ok then
  293.       local limit = getMin(#TableSelections, limit)
  294.       local start = getMax(round(pos / #TableSelections * (limit)), 1)
  295.       local finish = getMin(start + getMax(round(limit / #TableSelections * limit), 1), limit)
  296.      
  297.       for n = start, finish do
  298.         term.setCursorPos(xp, yp + n - 1)
  299.         term.write(" ")
  300.        
  301.         if x == xp and y == yp + n - 1 then
  302.           enable = true
  303.           break
  304.         end
  305.       end
  306.     end
  307.    
  308.     if ok == true and p1 == 1 then
  309.       return selection
  310.     elseif p1 == 2 then
  311.       return selection, true
  312.     end
  313.   elseif event == "mouse_drag" and enable == true then
  314.     local moved = clamp(y - ym, -1, 1)
  315.    
  316.     if moved > 0 then
  317.       local limit = getMin(#TableSelections, limit)
  318.       local start = getMax(round(pos / #TableSelections * limit), 1)
  319.       local finish = getMin(start + getMax(round(limit / #TableSelections * limit), 1), limit) + 1
  320.      
  321.       local temp = round(finish / limit * #TableSelections)
  322.      
  323.       selection = temp
  324.     else
  325.       local limit = getMin(#TableSelections, limit)
  326.       local start = getMax(round(pos / #TableSelections * limit), 1) - 1
  327.      
  328.       local temp = round(start / limit * #TableSelections)
  329.      
  330.       selection = temp
  331.     end
  332.    
  333.     xm, ym = x, y
  334.   end
  335.  
  336.   x, y = xO, yO
  337.   term.setCursorPos(x, y)
  338.  
  339.   for n = pos, getMin(#TableSelections, limit + pos - 1) do
  340.     if TableSelections[n] then
  341.       resetColors()
  342.       term.setCursorPos(x, y)
  343.       term.write(string.rep(" ", #TableSelections[n] + 1))
  344.       y = y + 1
  345.     end
  346.   end
  347.  
  348.   selection = clamp(selection, 1, #TableSelections)
  349.   end
  350. end
  351.  
  352. local function closeSides ()
  353.   sides = getSides()
  354.  
  355.   if #sides > 0 then
  356.     for _, s in pairs(sides) do
  357.       rednet.close(s)
  358.     end
  359.   end
  360. end
  361.  
  362. local function readAll (StringPath)
  363.   if not fs.exists(StringPath) then
  364.     return
  365.   end
  366.  
  367.   local file = fs.open(StringPath, "r")
  368.   local line = file.readLine()
  369.   local lines = {}
  370.  
  371.   while line ~= nil do
  372.     table.insert(lines, line)
  373.     line = file.readLine()
  374.   end
  375.  
  376.   file.close()
  377.  
  378.   return lines
  379. end
  380.  
  381. local function list (StringPath, StringType)
  382.   if not fs.isDir(StringPath) then
  383.     return
  384.   end
  385.  
  386.   local list = {}
  387.   local files = {}
  388.  
  389.   if string.sub(StringPath, #StringPath - 1) ~= "/" then
  390.     StringPath = StringPath .. "/"
  391.   end
  392.  
  393.   list = fs.list(StringPath)
  394.  
  395.   if list ~= {} then
  396.     if StringType == "files" or StringType == "file" or StringType == "doc" or StringType == "document" or StringType == "documents" then
  397.       for _, file in pairs(list) do
  398.         if not fs.isDir(StringPath .. file) and fs.exists(StringPath .. file) then
  399.           table.insert(files, file)
  400.         end
  401.       end
  402.     elseif StringType == "folders" or StringType == "directories" or StringType == "folder" or StringType == "dir" or StringType == "directorie" then
  403.       for _, file in pairs(list) do
  404.         if fs.isDir(StringPath .. file) then
  405.           table.insert(files, file .. "/")
  406.         end
  407.       end
  408.     else
  409.       files = list
  410.     end
  411.   end
  412.  
  413.   table.sort(files)
  414.  
  415.   return files
  416. end
  417.  
  418. local function toString (TableText)
  419.   local text = ""
  420.  
  421.   for i = 1, #TableText do
  422.     text = text .. TableText[i] .. "\n"
  423.   end
  424.  
  425.   text = text:sub(1, #text - 1)
  426.  
  427.   return text
  428. end
  429.  
  430. local function formatString(Text)
  431.   if Text:len() == 0 then
  432.     return
  433.   end
  434.  
  435.   return string.upper(Text:sub(1, 1)) .. string.lower(Text:sub(2))
  436. end
  437.  
  438. local function writeAll (StringPath, StringText)
  439.   local file = fs.open(StringPath, "w")
  440.  
  441.   file.write(StringText or "")
  442.  
  443.   file.close()
  444. end
  445.  
  446. local function getSize (StringPath)
  447.   if not fs.exists(StringPath) or fs.isDir(StringPath) then
  448.     return nil
  449.   end
  450.  
  451.   local file = fs.open(StringPath, "rb")
  452.   local text = file.read()
  453.   local len = 0
  454.  
  455.   while text ~= nil do
  456.     len = len + 1
  457.     text = file.read()
  458.   end
  459.  
  460.   return len
  461. end
  462.  
  463. local function checkFolders (text)
  464.   local folders = {}
  465.   local p1, p2
  466.   local path = ""
  467.  
  468.   text = shell.resolve(text)
  469.  
  470.   for i = 1, #text do
  471.     if text:sub(i, i) ~= "/" then
  472.       if not p1 then
  473.         p1 = i
  474.       end
  475.      
  476.       if i == #text then
  477.         folders[#folders + 1] = text:sub(p1)
  478.       end
  479.     else
  480.       p2 = i - 1
  481.      
  482.       folders[#folders + 1] = text:sub(p1, p2)
  483.      
  484.       p1, p2 = nil, nil
  485.     end
  486.   end
  487.  
  488.   for _, folder in pairs(folders) do
  489.     if not fs.isDir(folder) then
  490.       fs.makeDir(path .. folder)
  491.     end
  492.    
  493.     path = path .. folder .. "/"
  494.   end
  495. end
  496.  
  497. --Error checking and setting variables
  498.  
  499. local function usage (err)
  500.   if err then
  501.     writeText(err, colors.yellow)
  502.     print()
  503.   end
  504.  
  505.   resetColors()
  506.  
  507.   print("Usage:")
  508.   print(programName .. " send <computer id> <file to send>")
  509.   print(programName .. " get <computer id>")
  510.   print()
  511.   print("Don't use any arguments to run GUI version of this utility.")
  512.   print()
  513.   print('Ps: only specify "<computer id>" when getting a file if you want to get it from a specific computer.')
  514.  
  515.   error()
  516. end
  517.  
  518. if #arg > 0 then
  519.   if arg[1]:lower() == "send" then
  520.     if #arg == 3 then
  521.       if fs.exists(arg[3]) and not fs.isDir(arg[3]) then
  522.         path = arg[3]
  523.       else
  524.         usage("Invalid argument (3); specified file doesn't exist.")
  525.       end
  526.      
  527.       if tonumber(arg[2]) and tonumber(arg[2]) > 0 then
  528.         sendID = tonumber(arg[2])
  529.       else
  530.         usage("Invalid argument (2); specified computer id is not valid.")
  531.       end
  532.     else
  533.       usage()
  534.     end
  535.    
  536.     sendb = true
  537.   elseif arg[1]:lower() == "get" then
  538.     if tonumber(arg[2]) and tonumber(arg[2]) > 0 then
  539.       sendID = tonumber(arg[2])
  540.     end
  541.    
  542.     getb = true
  543.   else
  544.     usage()
  545.   end
  546. end
  547.  
  548. --{{Main Code}}
  549.  
  550. local function drawFrame (small, ColorClear)
  551.   local x, y = 1, 1
  552.   local w, h = term.getSize()
  553.  
  554.   if small == true then
  555.     x = w / 4
  556.     y = h / 4
  557.     w = w / 2
  558.     h = h / 2
  559.    
  560.     x = math.floor(x + 0.5)
  561.     y = math.floor(y + 0.5)
  562.     w = math.floor(w + 0.5)
  563.     h = math.floor(h + 0.5)
  564.   end
  565.  
  566.   vRep(" ", h, nil, colors.lightBlue, x, y)
  567.   vRep(" ", h, nil, colors.lightBlue, x + w - 1, y)
  568.   writeText(string.rep(" ", w), nil, colors.lightBlue, x, y)
  569.   writeText(string.rep(" ", w), nil, colors.lightBlue, x, y + h - 1)
  570.  
  571.   for x = x + 1, w + x - 2 do
  572.     for y = y + 1, h + y - 2 do
  573.       writeText(" ", nil, ColorClear or colors.black, x, y)
  574.     end
  575.   end
  576.  
  577.   resetColors()
  578. end
  579.  
  580. local function window (TableContent)
  581.   local x, y = 1, 1
  582.   local w, h = term.getSize()
  583.  
  584.   w, h = w - 1, h - 1
  585.   x, y = w / 4 + 2, h / 4 + 2
  586.  
  587.   drawFrame(true)
  588.  
  589.   for i = 1, #TableContent do
  590.     writeText(TableContent[i], nil, nil, x, y + i - 1)
  591.   end
  592. end
  593.  
  594. --Checking for modems
  595.  
  596. local function waitForModem ()
  597.   drawFrame(true)
  598.  
  599.   local x, y = 1, 1
  600.   local w, h = term.getSize()
  601.  
  602.   w, h = w - 1, h - 1
  603.  
  604.   while running do
  605.     sides = getSides()
  606.     x, y = w / 4 + 2, h / 4 + 2
  607.    
  608.     if #sides > 0 then
  609.       for i, side in pairs(sides) do
  610.         sides[i] = formatString(side)
  611.       end
  612.      
  613.       if #sides == 1 then
  614.         side = sides[1]:lower()
  615.         running = false
  616.       else
  617.         writeText("Select modem:", nil, nil, x, y)
  618.         term.setCursorPos(x, y + 1)
  619.        
  620.         side = sides[selectionMenu(sides)]:lower()
  621.         running = false
  622.       end
  623.     else
  624.       writeText("Attach a modem", nil, nil, x, y)
  625.       writeText("Press any key to cancel", nil, nil, x, y + 2)
  626.      
  627.       repeat
  628.         local event, side = os.pullEvent()
  629.        
  630.         if event == "key" then
  631.           return false
  632.         end
  633.       until event == "peripheral" and peripheral.getType(side) == "modem"
  634.     end
  635.   end
  636.  
  637.   rednet.open(side)
  638.  
  639.   running = true
  640.   return true
  641. end
  642.  
  643. --Sending function
  644.  
  645. local function send ()
  646.   if not waitForModem() then
  647.     return false
  648.   end
  649.  
  650.   local event, id, message
  651.   local name = fs.getName(path)
  652.   local percent = 0
  653.   local file = toString(readAll(path))
  654.   local subfile = ""
  655.   local i = 0
  656.   local x, y = 1, 1
  657.   local w, h = term.getSize()
  658.  
  659.   w, h = w - 1, h - 1
  660.   x, y = w / 4 + 2, h / 4 + 2
  661.  
  662.   local function toPercent ()
  663.     local per = tostring(percent)
  664.    
  665.     while #per < 3 do
  666.       per = per .. " "
  667.     end
  668.    
  669.     return per
  670.   end
  671.  
  672.   while running do
  673.     window({"Waiting for recipient ".. sendID, "Press \"R\" to retry", "", "Press any key to cancel"})
  674.    
  675.     rednet.send(sendID, "request " .. getSize(path) .. ">" .. name)
  676.    
  677.     repeat
  678.       event, id, message = os.pullEvent()
  679.      
  680.       if event == "key" then
  681.         if id == keys.r then
  682.           rednet.send(sendID, "request " .. getSize(path) .. ">" .. name)
  683.         else
  684.           closeSides()
  685.           return false
  686.         end
  687.       end
  688.     until event == "rednet_message" and id == sendID
  689.    
  690.     if message == "get" then
  691.       window({"Sending: " .. name, percent .. "%"})
  692.      
  693.       if #file <= 500 then
  694.         writeText(percent .. "%", nil, nil, x, y + 1)
  695.        
  696.         rednet.send(sendID, toPercent() .. " " .. file)
  697.        
  698.         repeat
  699.           event, id = os.pullEvent("rednet_message")
  700.         until id == sendID
  701.        
  702.         rednet.send(sendID, "sent")
  703.        
  704.         closeSides()
  705.        
  706.         window({"Successfully sent:", name, "", "Press any key to exit"})
  707.         os.pullEvent("key")
  708.         return true
  709.       else
  710.         while true do
  711.         if i ~= #file then
  712.           writeText(percent .. "%", nil, nil, x, y + 1)
  713.          
  714.           if #file <= i + 500 then
  715.             subfile = file:sub(i + 1)
  716.            
  717.             i = #file
  718.           else
  719.             subfile = file:sub(i + 1, i + 500)
  720.            
  721.             percent = math.floor(i / #file * 100)
  722.             i = i + 500
  723.           end
  724.          
  725.           rednet.send(sendID, toPercent() .. " " .. subfile)
  726.          
  727.           repeat
  728.             event, id = os.pullEvent("rednet_message")
  729.           until id == sendID
  730.         else
  731.           rednet.send(sendID, "sent")
  732.          
  733.           closeSides()
  734.          
  735.           window({"Successfully sent:", name, "", "Press any key to exit"})
  736.           os.pullEvent("key")
  737.           return true
  738.         end
  739.         end
  740.       end
  741.     elseif message == "refuse" then
  742.       closeSides()
  743.       window({"Recipient refused", "", "Press any key to exit"})
  744.       os.pullEvent("key")
  745.       return false
  746.     end
  747.   end
  748.  
  749.   running = true
  750.  
  751.   closeSides()
  752. end
  753.  
  754. --Getting function
  755.  
  756. local function get ()
  757.   if not waitForModem() then
  758.     return false
  759.   end
  760.  
  761.   local getName = "unknown"
  762.   local text = {"Waiting for request", "Sender ID: any", "", "Press any key to cancel"}
  763.   local event, id, message
  764.   local selection = 0
  765.   local percent = 0
  766.   local file = ""
  767.   local size = ""
  768.   local x, y = 1, 1
  769.   local w, h = term.getSize()
  770.  
  771.   w, h = w - 1, h - 1
  772.   x, y = w / 4 + 2, h / 4 + 2
  773.  
  774.   if sendID ~= 0 then
  775.     text[2] = "Sender ID: " .. sendID
  776.   end
  777.  
  778.   while running do
  779.     window(text)
  780.    
  781.     repeat
  782.       event, id, message = os.pullEvent()
  783.      
  784.       if event == "key" then
  785.         closeSides()
  786.         return false
  787.       end
  788.     until event == "rednet_message" and (id == sendID or sendID == 0)
  789.    
  790.     if sendID == 0 then
  791.       sendID = id
  792.     end
  793.    
  794.     if message:sub(1, 7) == "request" then
  795.       local p1 = message:find(">")
  796.      
  797.       if fs.getFreeSpace("/") < tonumber(message:sub(9, p1 - 1)) then
  798.         rednet.send(sendID, "refuse")
  799.         closeSides()
  800.         window({"File to big", "", "Press any key"})
  801.         os.pullEvent("key")
  802.         return false
  803.       end
  804.      
  805.       size = (tonumber(message:sub(9, p1 - 1)) / 1000) .. " kB"
  806.       getName = message:sub(p1 + 1)
  807.     end
  808.    
  809.     window({"Getting file from " .. sendID, "Name: " .. getName, "Size: " .. size})
  810.     term.setCursorPos(x, y + 4)
  811.     selection = selectionMenu({"Save", "Cancel"})
  812.    
  813.     if selection == 2 then
  814.       rednet.send(sendID, "refuse")
  815.       closeSides()
  816.       return false
  817.     else
  818.       window({"Enter save path:"})
  819.       term.setCursorPos(x, y + 1)
  820.       path = shell.resolve(read())
  821.       rednet.send(sendID, "get")
  822.     end
  823.    
  824.     window({"Getting: " .. getName, percent .. "%"})
  825.    
  826.     repeat
  827.       writeText(percent .. "%", nil, nil, x, y + 1)
  828.      
  829.       event, id, message = os.pullEvent("rednet_message")
  830.      
  831.       if id == sendID and message ~= "sent" then
  832.         percent = tonumber(message:sub(1, 3))
  833.        
  834.         file = file .. message:sub(5)
  835.        
  836.         rednet.send(sendID, "ok")
  837.       end
  838.     until id == sendID and message == "sent"
  839.    
  840.     closeSides()
  841.    
  842.     window({"Saving: " .. getName, "Path: " .. path .. "/" .. getName})
  843.     checkFolders(path)
  844.     writeAll(path .. "/" .. getName, file)
  845.     window({"Saved " .. getName, "Path: " .. path .. "/" .. getName, "", "Press any key to exit"})
  846.     os.pullEvent("key")
  847.     return true
  848.   end
  849.  
  850.   running = true
  851.  
  852.   closeSides()
  853. end
  854.  
  855. --Running program and File Manager
  856.  
  857. if sendb == true then
  858.   send()
  859. elseif getb == true then
  860.   get()
  861. else
  862.   local currentPath = "/"
  863.   local files = list(currentPath, "files")
  864.   local folders = list(currentPath, "folders")
  865.   local fileList = {}
  866.   local x, y = 2, 2
  867.   local w, h = term.getSize()
  868.   local selection = 0
  869.   local menu = false
  870.   local selected = 0
  871.  
  872.   local function combine ()
  873.     if #files == 0 then
  874.       return folders
  875.     end
  876.    
  877.     if #folders == 0 then
  878.       return files
  879.     end
  880.    
  881.     local all = folders
  882.    
  883.     for _, file in pairs(files) do
  884.       all[#all + 1] = file
  885.     end
  886.    
  887.     return all
  888.   end
  889.  
  890.   local function back (StringPath)
  891.     if StringPath == "/" then
  892.       return StringPath
  893.     end
  894.    
  895.     repeat
  896.       StringPath = string.sub(StringPath, 1, #StringPath - 1)
  897.     until string.sub(StringPath, #StringPath) == "/" or #StringPath <= 1
  898.    
  899.     return StringPath
  900.   end
  901.  
  902.   local function getFolder (StringPath)
  903.     local string = back(StringPath)
  904.    
  905.     return string.sub(StringPath, #string + 1)
  906.   end
  907.  
  908.   while running do
  909.     files = list(currentPath, "files")
  910.     folders = list(currentPath, "folders")
  911.     fileList = combine()
  912.    
  913.     table.insert(fileList, 1, "/")
  914.     fileList[#fileList + 1] = ""
  915.     fileList[#fileList + 1] = "Exit"
  916.    
  917.     if menu then
  918.       local x, y = 1, 1
  919.       local w, h = term.getSize()
  920.      
  921.       w, h = w - 1, h - 1
  922.       x, y = w / 4 + 2, h / 4 + 2
  923.      
  924.       drawFrame(true)
  925.       term.setCursorPos(x, y)
  926.       selection = selectionMenu({"Open", "Edit", "Send", "Get", "New Folder", "New File", "Delete", "Close modems", "Help", "", "Back"}, nil, math.floor(h / 2) - 1)
  927.      
  928.       if selection == 1 then
  929.         if selected then
  930.           if fs.isDir(currentPath .. selected) then
  931.             currentPath = currentPath .. selected
  932.             menu = false
  933.           else
  934.             shell.run(currentPath .. selected)
  935.             menu = false
  936.           end
  937.         else
  938.           window({"Choose a file first", "", "Press any key"})
  939.           os.pullEvent("key")
  940.           menu = false
  941.         end
  942.       elseif selection == 2 then
  943.         if selected then
  944.           if fs.isDir(currentPath .. selected) then
  945.             window({"Can't edit a folder", "", "Press any key"})
  946.             os.pullEvent("key")
  947.             menu = false
  948.           else
  949.             shell.run("edit", currentPath .. selected)
  950.             menu = false
  951.           end
  952.         else
  953.           window({"Choose a file first", "", "Press any key"})
  954.           os.pullEvent("key")
  955.           menu = false
  956.         end
  957.       elseif selection == 3 then
  958.         if selected then
  959.           path = currentPath .. selected
  960.           window({"Enter recipient ID:"})
  961.           term.setCursorPos(x, y + 1)
  962.           sendID = tonumber(read()) or 0
  963.           send()
  964.           path = ""
  965.           sendID = 0
  966.           menu = false
  967.         else
  968.           window({"Choose a file first", "", "Press any key"})
  969.           os.pullEvent("key")
  970.           menu = false
  971.         end
  972.       elseif selection == 4 then
  973.         window({"Enter sender ID:", "", "", "Leave it blank if you", "don't know sender id"})
  974.         term.setCursorPos(x, y + 1)
  975.         sendID = tonumber(read()) or 0
  976.         get()
  977.         sendID = 0
  978.         path = ""
  979.         menu = false
  980.       elseif selection == 5 then
  981.         window({"Create new folder:"})
  982.         term.setCursorPos(x, y + 1)
  983.         local name = read()
  984.        
  985.         if not fs.exists(currentPath .. name) then
  986.           fs.makeDir(currentPath .. name)
  987.           menu = false
  988.         else
  989.           window({"Couldn't create folder", "", "Press any key"})
  990.           os.pullEvent("key")
  991.           menu = false
  992.         end
  993.       elseif selection == 6 then
  994.         window({"Create new file:"})
  995.         term.setCursorPos(x, y + 1)
  996.         local name = read()
  997.        
  998.         if not fs.exists(currentPath .. name) then
  999.           shell.run("edit", currentPath .. name)
  1000.           menu = false
  1001.         else
  1002.           window({"Couldn't create file", "", "Press any key"})
  1003.           os.pullEvent("key")
  1004.           menu = false
  1005.         end
  1006.       elseif selection == 7 then
  1007.         if selected then
  1008.           window({"Delete " .. selected .. "?"})
  1009.           term.setCursorPos(x, y + 1)
  1010.           local selection = selectionMenu({"No", "Yes"})
  1011.          
  1012.           if selection == 2 then
  1013.             fs.delete(currentPath .. selected)
  1014.             window({"Deleted " .. selected, "", "Press any key"})
  1015.             os.pullEvent("key")
  1016.             menu = false
  1017.           end
  1018.         else
  1019.           window({"Choose a file first", "", "Press any key"})
  1020.           os.pullEvent("key")
  1021.           menu = false
  1022.         end
  1023.       elseif selection == 8 then
  1024.         closeSides()
  1025.         window({"All modems closed", "", "Press any key"})
  1026.         os.pullEvent("key")
  1027.       elseif selection == 9 then
  1028.         window({"Use mouse or arrow keys", "to navigate the browser.", "Press [M] or right mouse", "button for menu.", "", "Press any key"})
  1029.         os.pullEvent("key")
  1030.       elseif selection == 11 then
  1031.         menu = false
  1032.       end
  1033.     else
  1034.       drawFrame()
  1035.       writeText("RedFile " .. version .. " | Press [M] for menu | ID: " .. os.getComputerID(), nil, nil, x, y)
  1036.       writeText("Current path: " .. currentPath, nil, nil, x, y + 1)
  1037.       term.setCursorPos(x, y + 3)
  1038.       selection, menu = selectionMenu(fileList, keys.m, h - 5)
  1039.      
  1040.       if not menu then
  1041.         if selection == 1 then
  1042.           currentPath = back(currentPath)
  1043.         elseif selection == #fileList then
  1044.           running = false
  1045.         else
  1046.           selected = fileList[selection]
  1047.          
  1048.           if not fs.isDir(currentPath .. selected) then
  1049.             menu = true
  1050.           else
  1051.             currentPath = currentPath .. selected
  1052.           end
  1053.         end
  1054.       else
  1055.         if selection ~= 1 and selection ~= #fileList then
  1056.           selected = fileList[selection]
  1057.         else
  1058.           selected = nil
  1059.         end
  1060.       end
  1061.     end
  1062.   end
  1063. end
  1064.  
  1065. closeSides()
  1066.  
  1067. reset()
Advertisement
Add Comment
Please, Sign In to add comment