Advertisement
PandaDoddo72Rus

filemanager

Mar 31st, 2017
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.57 KB | None | 0 0
  1. local cmp = require('component')
  2. local event = require('event')
  3. local serialization = require('serialization')
  4. local gpu=cmp.gpu
  5. local term =require('term')
  6. local computer = require('computer')
  7. local filesystem=require('filesystem')
  8. local unicode = require('unicode')
  9. local keyboard = require("keyboard")
  10. local shell = require("shell")
  11. local object = require('object')
  12. ----
  13. local __name = 'server'
  14. local __timezone = 0
  15. local __correct = 0
  16.  
  17. local tz = __timezone + __correct
  18. local t_correction = tz * 3600
  19. ----
  20. local oldBack=gpu.getBackground()
  21. local oldFore=gpu.getForeground()
  22. local rX , rY = gpu.getResolution()
  23. ----
  24. function setOld()
  25.   gpu.setBackground(oldBack)
  26.   gpu.setForeground(oldFore)
  27. end
  28.  
  29. function getTime()
  30.   local file = io.open('/tmp/'..__name..'.dt','w')
  31.   file:write('')
  32.   file:close()
  33.   local lastmod = tonumber(string.sub(filesystem.lastModified('/tmp/'..__name..'.dt'),1,-4)) + t_correction
  34.   return lastmod
  35. end
  36.  
  37. local function getEvent(...)
  38.   args = {...}
  39.   evnt = nil
  40.   if type(args[1]) == 'number' then
  41.     time = args[1]
  42.   end  
  43.   evtrue = true
  44.   local function getRawEvent()
  45.     return {event.pull()}
  46.   end
  47.   while evtrue do
  48.    -- s , evnt = pcall(getRawEvent)
  49.   evnt = {event.pull(time)}
  50.   --  if s ~= false then
  51.     for i=1,#args do
  52.       if evnt[1] == args[i] and time == nil then
  53.         evtrue = false
  54.         break
  55.     elseif time ~= nil then  
  56.       evtrue = false
  57.         break
  58.       end
  59.     end
  60.   --end
  61.   end
  62.   return evnt
  63. end
  64. ----
  65. function getPath(arr)
  66.   local path = ''
  67.   for i=1,#arr do
  68.     path = path .. arr[i]
  69.   end
  70.   return path
  71. end
  72.  
  73. local function saveTbl(tbl, fl)
  74.   file = io.open(fl, 'w')
  75.   file:write(serialization.serialize(tbl))
  76.   file:close()
  77. end
  78.  
  79. local function loadTbl(fl)
  80.   file = io.open(fl, 'r')
  81.   if file == nil then
  82.     file = io.open(fl, 'w')
  83.     file:write('{}')
  84.     return {} else
  85.     return serialization.unserialize(file:read('*a'))
  86.   end
  87.   file:close()
  88. end
  89.  
  90. ex = loadTbl('.expansion')
  91.  
  92. function getFiles(path)
  93.   arr={{},{}} arr2 = {}
  94.   for val,val2 in filesystem.list(path) do if val~= nil then if filesystem.isDirectory(val) then arr[1][#arr[1]+1] = val else arr[2][#arr[2]+1] = val end end end
  95.   for i=1,#arr do
  96.     for j=1,#arr[i] do
  97.     arr2[#arr2+1]=arr[i][j]
  98.   end
  99.   end
  100.   return arr2
  101. end
  102.  
  103. function rec(path)
  104.   local colors = {'0x0AA00','0xF06306','0xAA0000'}
  105.   if filesystem.isDirectory(path) then
  106.     str = {'',0xFFFFFF}
  107.   else
  108.     N = filesystem.size(path)
  109.     if unicode.len(tostring(N)) <= 3 then
  110.       str = {tostring(N)..'  B',colors[1]}
  111.     elseif unicode.len(tostring(N)) <= 5 then
  112.       str = {tostring(round(N / 1024 , 2)) .. ' KB',colors[2]}
  113.     else
  114.       str = {tostring(round(N / 1024 / 1024,2)) .. ' MB',colors[3]}
  115.     end
  116.   end
  117.   return str
  118. end
  119.  
  120. function round(num, decimalPlaces)
  121.     local mult = 10 ^ (decimalPlaces or 0)
  122.     return math.floor(num * mult + 0.5) / mult
  123. end
  124.  
  125. function getColorFile(str,n,o)
  126.   local out = o
  127.   for i=1,#ex do
  128.     if unicode.sub(str,unicode.len(str)-unicode.len(ex[i][1])+1,unicode.len(str)) == ex[i][1] then
  129.     out = ex[i][n]
  130.   end
  131.   end
  132.   return out
  133. end
  134.  
  135. function finder(arr,str)
  136.   local out = {false}
  137.   for i = 1,#arr do
  138.     if arr[i] == str then
  139.     out = {true,i}
  140.     break
  141.   end
  142.   end
  143.   return out
  144. end
  145.  
  146. function drawOneLine(arr,i,n)
  147.   fi = finder(selected,arr[i])
  148.   if fi[1] then
  149.     drawOneSegClick(arr,active_position,0x007DFF,1)
  150.   else
  151.     drawOneSegClick(arr,i,0xFFFFFF,n)
  152.   end
  153. end
  154.  
  155. function drawOneSegClick(arr,i,color,n)
  156.   cf = rec(getPath(paths)..arr[i])
  157.   l = rX - math.ceil(rX/4) - 2 - unicode.len(cf[1])
  158.   gpu.setBackground(color)
  159.   gpu.fill(k+1,1+n,l,1,' ')
  160.   gpu.setForeground(getColorFile(arr[i],2,0))
  161.   object.text(math.ceil(rX/4)+1,1+n,l,1,tostring(arr[i]),'first','')
  162.   gpu.setForeground(tonumber(cf[2]))
  163.   gpu.set(rX-2- unicode.len(tostring(cf[1])),1+n,tostring(cf[1]))
  164. end
  165.  
  166. function drawClick(arr)
  167.   if oldSelected == nil then oldSelected = selected end
  168.   for i=active_position,rY-2+active_position-1 do
  169.     for j=1,#oldSelected do
  170.       if oldSelected[j] == arr[i] and oldSelected[j] ~= selected[j] then
  171.       n = i - active_position + 1
  172.       drawOneSegClick(arr,i,0xFFFFFF,n)
  173.     break
  174.     end
  175.     end
  176.   end
  177.   for i=active_position,rY-2+active_position-1 do
  178.     for j=1,#selected do
  179.       if selected[j] == arr[i] then
  180.       n = i - active_position + 1
  181.     drawOneSegClick(arr,i,0x007DFF,n)
  182.     break
  183.     end
  184.     end    
  185.   end
  186.   oldSelected = selected
  187. end
  188.  
  189. function reDrawFiles(arr,p)
  190.   if lastP == nil then lastP = 1 end
  191.   if p == -1 and rY < #arr and lastP ~= rY-2+active_position-1 then
  192.     gpu.copy(k+1,3,rX-k-2-1,rY-1-1,0,-1)
  193.     drawOneLine(arr,rY-2+active_position-1,rY-1-1)  
  194.     lastP = rY-2+active_position-1
  195.   elseif p == 1 and rY < #arr and lastP ~= active_position then
  196.     gpu.copy(k+1,2,rX-k-2-1,rY-2-1,0,1)
  197.     drawOneLine(arr,active_position,1)
  198.     lastP = active_position
  199.   end
  200. end
  201.  
  202. function drawFiles(arr)
  203.   object.square(k+1,2,rX-k-2,rY-2,' ',0xffffff,0xFFFFFF)
  204.   n = 0
  205.   for i=active_position,rY-2+active_position-1 do
  206.     if arr[i] ~= nil then
  207.       n = n+1
  208.     drawOneLine(arr,i,n)
  209.       drawOneSegClick(arr,i,0xFFFFFF,n)
  210.     end
  211.   end
  212. end
  213.  
  214. function drawDiskScroll()
  215.   object.drawBoard('disk',disks,disk_position)
  216.   object.drawScroll('disk_scroll',disk_position,#disks,math.ceil(rY / 4)-2)
  217. end
  218.  
  219. function reDrawTextBox()
  220.   gpu.setForeground(0xffffff)
  221.   gpu.setBackground(0)
  222.   object.delObject('textBox','FirstBox')
  223.   object.add('textBox',1,2,k-2,3,getPath(paths),1,0x999999,0xffffff,0xFFDD00,0,0xffffff,0,'FirstBox')
  224.   object.drawObject('textBox','FirstBox')
  225. end
  226.  
  227. function cathClickMenu(x,y)
  228.   local answear = false
  229.   if oldPos and clickMenuArr ~= nil then
  230.     if x >= oldPos[1] and x <= oldPos[1]+oldPos[3] and y >= oldPos[2] and y <= oldPos[2] + oldPos[4] then
  231.       local pos = y-oldPos[2]
  232.       if pos > 0 then
  233.         if clickMenuArr[pos][2] ~= nil then
  234.           local func = clickMenuArr[pos][2]
  235.           func()
  236.           answear = true
  237.         end
  238.       end
  239.     end
  240.     --reDrawAllFiles()
  241.     f = getFiles(getPath(paths))
  242.     selected = {}
  243.     drawFiles(f)
  244.   end
  245.   oldPos = nil
  246.   clickMenuArr = nil
  247.   return answear
  248. end
  249.  
  250. function createClickMenu(x,y,w,h,arr)
  251.   if x + w > rX-2 then x = rX - w - 2 end
  252.   if y + h > rY-1 and y - h > 0 then y = y - h elseif y + h > rY-1 then y = rY - h end
  253.   local function drawClickMenu(arr)
  254.     gpu.setForeground(0)
  255.     for i=1,#arr do
  256.       if math.fmod(i,2) == 0 then
  257.         gpu.setBackground(0xdcdcdc)
  258.       else
  259.         gpu.setBackground(0xcdcdcd)
  260.       end
  261.       gpu.fill(x,y+i,w,1,' ')
  262.       gpu.set(x,y+i,arr[i][1])
  263.     end
  264.   end
  265.   if arr ~= nil then
  266.     clickMenuArr = arr
  267.   oldPos = {x,y,w,h}
  268.   end
  269.   drawClickMenu(arr)
  270.   setOld()
  271. end
  272.  
  273. function mainDraw(path)
  274.   object.init()
  275.   rX , rY = gpu.getResolution()
  276. ex = loadTbl('.expansion')
  277.   selected = {}
  278.   k = math.ceil(rX/4)
  279.   active_position = 1
  280.   object.square(1,1,rX,1,' ',0xffffff,0x222222)
  281.   object.add('button',rX-3+1,1,3,1,'[X]',1,0xffffff,0xFF0000,'Выход')
  282.   object.add('button',2,1,3,1,' < ',1,0xffffff,0x0000FF,'Назад')
  283.   object.add('scroll',k+1,2,rX-k,rY-1,' ',0xFFFFFF,0xAAAAAA,0xffffff,0x505050,'FirstScroll',rX-1,2,2,rY-2,'vertical')
  284.   object.drawAllObject()
  285.   object.square(1,2,k,rY-1,' ',0xffffff,0xAAAAAA)
  286.   object.square(k+1,2,rX-k,rY-1,' ',0xffffff,0xFFFFFF)
  287.   f = getFiles(path)
  288.   drawFiles(f)
  289.   object.square(1,rY,rX,1,' ',0xffffff,0x222222)
  290.   setOld()
  291.   reDrawTextBox()
  292.   object.add('board',1,5,k-2,math.ceil(rY / 4),0xffffff,0x505050,0xffffff,123123,true,1,'disk')
  293.   object.add('scroll',1,5,k,math.ceil(rY / 4)-2,' ',0xFFFFFF,0xAAAAAA,0xffffff,0x505050,'disk_scroll',k-1,2,2,math.ceil(rY / 4),'vertical')
  294.   drawDiskScroll()
  295. end
  296.  
  297. function getMyDisks(mode)
  298. local disks={}
  299. local fromAddress = filesystem.get(os.getenv("_")).address
  300. local candidates = {}
  301. for address in cmp.list("filesystem", true) do
  302.   local dev = cmp.proxy(address)
  303.   if --[[not dev.isReadOnly() and]] dev.address ~= computer.tmpAddress() then
  304.     table.insert(candidates, dev)
  305.   end
  306. end
  307. if mode==2 then
  308. for i = 1, #candidates do
  309.   local label = candidates[i].getLabel()
  310.   if label and label ~= 'raid' then
  311.     label = label
  312.   else
  313.     label = candidates[i].address
  314.   end
  315.   disks[#disks+1]={label,candidates[i].address}
  316.   end
  317.   return disks
  318. elseif mode == 1 then
  319. for i = 1, #candidates do
  320.   local label = candidates[i].getLabel()
  321.   if label and label ~= 'raid' then
  322.     label = label
  323.   else
  324.     label = candidates[i].address
  325.   end
  326.   disks[#disks+1]=label
  327.   end
  328.   return disks
  329.   end
  330. end
  331.  
  332. function startDisk()
  333.   local disks=getMyDisks(2)
  334.   arrMyDiskAddress=filesystem.get(os.getenv("_"))
  335.   for i=1,#disks do
  336.   if arrMyDiskAddress.address:sub(1,8) == disks[i][1]:sub(1,8) or arrMyDiskAddress.getLabel():sub(1,8) == disks[i][1]:sub(1,8) then
  337.     posDisk=i
  338.     break
  339.   end
  340.   end
  341.   return 'mnt/'..tostring(arrMyDiskAddress.address:sub(1,3))..'/' , posDisk
  342. end
  343.  
  344. object.init()
  345. --
  346. pa , disk_position = startDisk()
  347. disks = getMyDisks(1)
  348. dsk = getMyDisks(2)
  349. paths = {'mnt/',unicode.sub(dsk[disk_position][2],1,3)..'/'}
  350. path = getPath(paths)
  351. --
  352. mainDraw('..')
  353. --
  354. fileBuffer = {}
  355. function reDrawAllFiles()
  356.   active_position = 1
  357.   dsk = getMyDisks(2)
  358.   paths = {'mnt/',unicode.sub(dsk[disk_position][2],1,3)..'/'}
  359.   reDrawTextBox()
  360.   f = getFiles(getPath(paths))
  361.   selected = {}
  362.   drawFiles(f)
  363. end
  364.  
  365. function inBuffer()
  366.   local arr = {}
  367.   for i=1,#selected do
  368.     arr[#arr+1]=tostring(getPath(paths)..tostring(selected[i]))
  369.   end
  370.   return arr
  371. end
  372.  
  373. function paste()
  374.   if fileBuffer[1] ~= nil and fileBuffer[1] == 'cut' then
  375.     for i=1,#fileBuffer[2] do
  376.       local p = filesystem.segments(fileBuffer[2][i])
  377.       shell.execute('cp '..fileBuffer[2][i]..' '..getPath(paths)..p[#p])
  378.       shell.execute('del '..fileBuffer[2][i])
  379.     end
  380.   fileBuffer = {}
  381.   elseif fileBuffer[1] ~= nil then  
  382.     for i=1,#fileBuffer[2] do
  383.       local p = filesystem.segments(fileBuffer[2][i])
  384.       shell.execute('cp '..fileBuffer[2][i]..' '..getPath(paths)..p[#p])
  385.     end
  386.   end
  387. end
  388.  
  389. function op()
  390.    if filesystem.isDirectory(getPath(paths)..selected[1]) then
  391.      paths[#paths+1] = selected[1]
  392.      f = getFiles(getPath(paths))
  393.      drawFiles(f)
  394.      reDrawTextBox()
  395.      active_position = 1
  396.      shiftSelected = nil
  397.    else
  398.      setOld()
  399.      term.clear()      
  400.      shell.execute(getColorFile(selected[1],3,'')..' '..getPath(paths)..selected[1])
  401.      event.pull()
  402.      mainDraw(getPath(paths))
  403.    end
  404. end
  405.  
  406. function clock()
  407.   gpu.setBackground(0x222222)
  408.   gpu.setForeground(0xffffff)
  409.   local time = os.date('%H:%M:%S',getTime())
  410.   gpu.set(rX-unicode.len(time)-1,rY,time)
  411. end
  412.  
  413. function edit()
  414.   setOld()
  415.   shell.execute('edit '..getPath(paths)..selected[1])
  416.   mainDraw(getPath(paths))
  417. end
  418.  
  419. while true do
  420.   e = getEvent(0,'touch','scroll','component_added','component_removed','key_up')
  421.   if e[1] ~= nil then  
  422.     if e[1] ~= 'component_added' and e[1] ~= 'component_removed' and e[1] ~= 'key_up' and e[1] ~= 'key_down' then
  423.       arr=object.getPressedObject(e[3],e[4])
  424.     end
  425.     if arr ~= false and arr[1] == 'button' then
  426.       if arr[2] == 'Выход' then
  427.         setOld()
  428.         term.clear()
  429.         os.exit()
  430.       elseif arr ~= false and arr[2] == 'Назад' then
  431.         if #paths > 1 then
  432.         table.remove(paths)
  433.           f = getFiles(getPath(paths))
  434.           active_position = 1
  435.           selected = {}
  436.           drawFiles(f)
  437.           reDrawTextBox()
  438.         end
  439.       end
  440.     elseif arr ~= false and arr[1] == 'textBox' and e[1] == 'touch' and arr[2] == 'FirstBox' then
  441.       npa = object.textBox('FirstBox',false,'*')
  442.       if filesystem.exists(npa) then
  443.         paths = {}
  444.         for val,val2 in pairs(filesystem.segments(npa)) do
  445.           paths[#paths+1] = val2..'/'
  446.         end
  447.         reDrawTextBox()
  448.         f = getFiles(getPath(paths))
  449.         drawFiles(f)
  450.       end
  451.     elseif arr ~= false and arr[1] == 'scroll' and e[1] == 'scroll' then
  452.       if arr~= false and arr[2]=='FirstScroll' then
  453.         active_position = active_position -e[5]
  454.         if active_position > #f-rY+3 then active_position = #f-rY+3 end
  455.         if active_position < 1  then active_position = 1 end
  456.         object.drawScroll('FirstScroll',active_position,#f,rY-2)
  457.         reDrawFiles(f,e[5])
  458.       elseif arr ~=false and arr[2]=='disk_scroll' then
  459.         disk_position = disk_position -e[5]
  460.         if disk_position > #disks then disk_position = #disks end
  461.         if disk_position < 1  then disk_position = 1 end
  462.         drawDiskScroll()
  463.         shiftSelected = nil
  464.         reDrawAllFiles()
  465.       end
  466.     elseif e[1] == 'key_up' then
  467.       if e[4] == 46 and keyboard.isAltDown() then
  468.         fileBuffer = {'copy',inBuffer()}
  469.       elseif e[4] == 47 and keyboard.isControlDown() then
  470.         paste()
  471.         f = getFiles(getPath(paths))
  472.         selected = {}
  473.         drawFiles(f)
  474.       elseif e[4] == 45 and keyboard.isControlDown() then
  475.         fileBuffer = {'cut',inBuffer()}
  476.       elseif e[4] == 30 and keyboard.isControlDown() then
  477.         selected=f
  478.         drawClick(f)
  479.       elseif e[4] == 211 then
  480.         for i=1,#selected do
  481.           shell.execute('rm '..getPath(paths)..selected[i])
  482.         end
  483.         selected = {}
  484.         active_position = 1
  485.         f = getFiles(getPath(paths))
  486.         drawFiles(f)
  487.       end
  488.     elseif e[1] == 'component_added' or e[1] == 'component_removed'  and e[3] == 'filesystem' then
  489.       dsks = getMyDisks(1)
  490.       if tostring(unicode.sub(e[2],1,3)..'/') == paths[2] and e[1] == 'component_removed' then
  491.         disk_position = 1
  492.         drawDiskScroll()
  493.         reDrawAllFiles()
  494.       elseif #disks > #dsks then
  495.         if disk_position > #dsks and disks[disk_position] == '' then  
  496.      
  497.         end
  498.       end
  499.       disks = getMyDisks(1)
  500.       drawDiskScroll()
  501.       shiftSelected = nil
  502.     elseif arr ~= false and e[1] == 'touch' and arr[2] == 'FirstScroll'  then
  503.     if cathClickMenu(e[3],e[4]) then
  504.      -- break
  505.    --adad end
  506.     else
  507.       if keyboard.isControlDown() and e[5] == 0 then
  508.         fi = finder(selected,f[active_position+(e[4]-2)])
  509.         if fi[1] == false then
  510.           selected[#selected+1] = f[active_position+(e[4]-2)]
  511.           drawClick(f)
  512.         end
  513.       elseif arr ~= false and keyboard.isControlDown() == false and keyboard.isShiftDown() == false then
  514.         selected = {f[active_position+(e[4]-2)]}
  515.         shiftSelected = active_position+(e[4]-2)
  516.         drawClick(f)
  517.       elseif arr~= false and keyboard.isShiftDown() then
  518.         if shiftSelected ~= nil then
  519.           local function addSelected(j,k)
  520.             selected = {}
  521.             for i=j,k do
  522.               selected[#selected+1] = f[i]
  523.             end
  524.             drawClick(f)
  525.             return selected
  526.           end
  527.           if shiftSelected > active_position+(e[4]-2) then
  528.             selected = addSelected(active_position+(e[4]-2),shiftSelected)
  529.           elseif shiftSelected < active_position+(e[4]-2) then
  530.             selected = addSelected(shiftSelected,active_position+(e[4]-2))
  531.           end
  532.         end
  533.       end
  534.       fi = finder(selected,f[active_position+(e[4]-2)])
  535.       if fi[1] and #selected == 1 and selected[#selected] == lastClick then
  536.         if filesystem.isDirectory(getPath(paths)..selected[1]) and e[5] == 0 then
  537.           op()
  538.         elseif e[5] == 0 and filesystem.isDirectory(getPath(paths)..selected[1]) == false then
  539.           setOld()
  540.           term.clear()      
  541.           shell.execute(getColorFile(selected[1],3,'')..' '..getPath(paths)..selected[1])
  542.           event.pull()
  543.           mainDraw(getPath(paths))
  544.         end
  545.       elseif e[5] == 1 and selected[1] ~= nil and filesystem.isDirectory(getPath(paths)..selected[1]) == false then
  546.         createClickMenu(e[3],e[4],20,12,{{'Открыть',op},{'Открыть с помощью...'},{'Редактировать',edit},{'--------------------'},{'Переименовать'},{'Копировать'},{'Вырезать'},{'Удалить'},{'Создать...'},{'--------------------'},{'Свойства'}})
  547.       elseif e[5] == 1 and selected[1] ~= nil and filesystem.isDirectory(getPath(paths)..selected[1]) == true then
  548.         createClickMenu(e[3],e[4],20,12,{{'Открыть',op},{'--------------------'},{'Переименовать'},{'Копировать'},{'Вырезать'},{'Удалить'},{'Создать...'},{'--------------------'},{'Свойства'}})
  549.       end
  550.       lastClick = f[active_position+(e[4]-2)]
  551.     end
  552.   end
  553.   else
  554.     clock()
  555.   end
  556. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement