ZNZNCOOP

Midday Navigator

May 26th, 2015
359
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --------------------------------------------------
  2. --  Midday Navigator. Браузер для сети OpenNet  --
  3. --             Автор: Zer0Galaxy                --
  4. --------------------------------------------------
  5. gpu  = require("component").gpu
  6. kbd  = require("component").keyboard
  7. computer=require("computer")
  8. fs   = require("filesystem")
  9. text = require("text")
  10. term = require("term")
  11. wlen = require("unicode").wlen
  12. event= require("event")
  13. on = require("opennet")
  14.  
  15. local cursorX, cursorY = 1, 1
  16. local ShiftX = 0
  17. local ShiftY = 0
  18. local Left,Top = 1, 3
  19. local WinW, WinH = gpu.getResolution()
  20. WinH=WinH-Top+1
  21. local Caption="Midday Navigator 1.0"
  22. local Site=""
  23. local txColour = 0xFFFFFF
  24. local bgColour = 0x000000
  25. local tagColour = 0x0080FF
  26. local History = {}
  27. local object={}
  28.  
  29. function winhead()
  30.   gpu.setForeground(0xFFFFFF)
  31.   gpu.setBackground(0x0000FF)
  32.   gpu.fill(1,1, WinW,1, " ")  gpu.set(2,1, Caption)
  33.   gpu.setBackground(0x00FF00) gpu.set(WinW-8,1, " S ")
  34.   gpu.setBackground(0x0080FF) gpu.set(WinW-5,1, " < ")
  35.   gpu.setBackground(0xFF0000) gpu.set(WinW-2,1, " X ")
  36.   gpu.setForeground(0x000000)
  37.   gpu.setBackground(0xFFFFFF)
  38.   gpu.fill(1,2, WinW,1, " ")
  39.   gpu.set(2,2, Site)
  40.   gpu.setForeground(txColour)
  41.   gpu.setBackground(bgColour)  
  42. end
  43.  
  44. function winwrite(value)
  45.   value = text.detab(tostring(value))
  46.   if wlen(value) == 0 then
  47.     return
  48.   end
  49.   local line, nl
  50.   repeat
  51.     if cursorY > WinH then return end
  52.     line, value, nl = text.wrap(value, WinW - (cursorX - 2), WinW)
  53.     if cursorY>=1 then gpu.set(cursorX+Left-1-ShiftX, cursorY+Top-1, line) end
  54.     cursorX = cursorX + wlen(line)
  55.     if nl or (cursorX > WinW) then
  56.       cursorX = 1
  57.       cursorY = cursorY + 1
  58.     end
  59.   until not value
  60. end
  61.  
  62. function winclear()
  63.   object={}
  64.   gpu.fill(Left, Top, WinW, WinH, " ")
  65.   cursorX, cursorY = 1, 1
  66. end
  67.  
  68. tags={}
  69. tags['html']=function(arg)
  70.   if arg.caption then Caption=arg.caption winhead() end
  71.   local param=tonumber(arg.color)
  72.   if param then txColour = param gpu.setForeground(param) end
  73.   param=tonumber(arg.bgcolor)
  74.   if param then bgColour = param gpu.setBackground(param) winclear() end
  75. end
  76. tags['font']=function(arg)
  77.   local param=tonumber(arg.color)
  78.   if param then gpu.setForeground(param) end
  79.   param=tonumber(arg.bgcolor)
  80.   if param then gpu.setBackground(param) end
  81. end
  82. tags['/font']=function()
  83.     gpu.setForeground( txColour )
  84.     gpu.setBackground( bgColour )
  85. end
  86. tags['cr']=function()
  87. --  if cursorX>1 then
  88.     cursorY=cursorY+1
  89.     cursorX=1
  90. --  end
  91. end
  92. tags['---']=function()
  93.   if cursorX>1 then cursorY=cursorY+1 cursorX=1 end
  94.   winwrite(string.rep('─',WinW))
  95. end
  96. tags['===']=function()
  97.   if cursorX>1 then cursorY=cursorY+1 cursorX=1 end
  98.   winwrite(string.rep('═',WinW))
  99. end
  100.  
  101. local function line_check(obj,x,y)
  102.   if y>=obj.y1 and y<=obj.y2 then
  103.     if (x>=obj.x1 or y>obj.y1) and (x<=obj.x2 or y<obj.y2) then return true end
  104.   end
  105. end
  106. local function bar_check(obj,x,y)
  107.   return y>=obj.y1 and y<=obj.y2 and x>=obj.x1 and x<=obj.x2
  108. end
  109. local function ref_work(obj) load(obj.ref) end
  110. tags['a']=function(arg)
  111.   if arg.ref then
  112.     table.insert(object, {check=line_check,
  113.     x1=cursorX+Left-1-ShiftX, y1=cursorY+Top-1,
  114.     work=ref_work, ref = arg.ref,
  115.     col=gpu.getForeground()})
  116.   end
  117.   local color=tonumber(arg.color) or tagColour
  118.   gpu.setForeground(color)
  119. end
  120. tags['/a']=function()
  121.   local ref=object[#object]
  122.   if ref and not ref.x2 then
  123.     gpu.setForeground(ref.col or txColour)
  124.     ref.x2, ref.y2 = cursorX+Left-2-ShiftX, cursorY+Top-1
  125.   end
  126. end
  127.  
  128. function tagWork(tag)
  129.   local name=tag:match('%S+')
  130.   if tags[name] then
  131.     local params={}
  132.     for k,v in tag:gmatch('(%w+)=([^%s"]+)') do params[k]=v end
  133.     for k,v in tag:gmatch('(%w+)="([^"]+)"') do params[k]=v end
  134.     tags[name](params)
  135.   else
  136.     winwrite( '<'..tag..'>' )
  137.   end
  138. end
  139.  
  140. function winline(line)
  141.   if line then
  142.     cursorY=line.Y-ShiftY
  143.     cursorX=line.X
  144.     local sLine=line.text
  145.     while string.len(sLine) > 0 do
  146.       local p1,p2
  147.       p1=sLine:find("<")
  148.       if p1 then p2=sLine:find(">",p1) end
  149.       if p2 then
  150.         winwrite(sLine:sub(1,p1-1))
  151.         tagWork(sLine:sub(p1+1,p2-1))
  152.         sLine=sLine:sub(p2+1)
  153.       else
  154.         winwrite(sLine)
  155.         sLine=""
  156.       end
  157.     end
  158.     if cursorY <= WinH then return true end
  159.   end
  160. end
  161.  
  162. function htmltext()
  163.   winclear()
  164.   local line=1
  165.   for i=#lines,1,-1 do
  166.     if lines[i].Y<=ShiftY then line=i break end
  167.   end
  168.   while winline(lines[line]) do
  169.     line=line+1
  170.     if lines[line] then lines[line].Y=ShiftY+cursorY lines[line].X=cursorX end
  171.   end
  172. end
  173. function codetext()
  174.   winclear()
  175.   for i=1,WinH do
  176.     if lines[i+ShiftY] then gpu.set(1-ShiftX,i+Top-1,lines[i+ShiftY].text)
  177.     else break end
  178.   end
  179. end
  180. wintext=htmltext
  181.  
  182. function winshift(shX,shY)
  183.   ShiftX=ShiftX+shX
  184.   ShiftY=ShiftY+shY
  185.   if ShiftX<0 then ShiftX=0 end
  186.   if ShiftY<0 then ShiftY=0 end
  187.   wintext()
  188. end
  189.  
  190. function load(sPath)
  191.   if sPath=='' or sPath==nil or sPath=="\n" then winhead() return end
  192.   if sPath:sub(-1)=="\n" then sPath=sPath:sub(1,-2) end
  193.   lines={}
  194.   ShiftX=0
  195.   ShiftY=0
  196.   Caption="Midday Navigator 1.0"
  197.   txColour = 0xFFFFFF
  198.   bgColour = 0x000000
  199.   if sPath:sub(1,1)=="." then
  200.     while sPath:sub(1,1)=="." do
  201.       Site=Site:match("(.+)/.*") or Site
  202.       sPath=sPath:sub(2)
  203.     end
  204.     Site=Site..sPath
  205.   else
  206.     Site=sPath
  207.   end
  208.   local host,doc=Site:match('(.-)/(.*)')
  209.   if not host then host=Site doc=nil end
  210.   if host=="" then
  211.     local file=io.open(Site,"r")
  212.     if file then
  213.       for line in file:lines() do
  214.         lines[#lines+1]={X=1,Y=math.huge,text=line}
  215.       end
  216.       file:close()
  217.     else
  218.       lines[1]={X=5,Y=1,text="<html>Файл <font color=0xFF0000>"..Site.."</font> не найден"}
  219.     end
  220.   else
  221.     local MyIP,err=on.getIP()
  222.     if MyIP then
  223.       on.send(host,"get",doc)
  224.       local adr,com,text
  225.       repeat
  226.         adr,com,text=on.receive(3)
  227.       until com=="get" or not com
  228.       if com=="get" then
  229.         text=tostring(text)
  230.         local line=1
  231.         while #text>0 do
  232.           local p=text:find("\n")
  233.           if p then
  234.             lines[line],text={X=1,Y=math.huge,text=text:sub(1,p-1)}, text:sub(p+1)
  235.           else
  236.             lines[line],text={X=1,Y=math.huge,text=text}, ""
  237.           end
  238.           line=line+1
  239.         end
  240.       else
  241.         if adr then
  242.           lines[1]={X=1,Y=math.huge,text="Ответ от узла "..tostring(adr)}
  243.           lines[2]={X=1,Y=math.huge,text=tostring(text)}
  244.         else
  245.           lines[1]={X=1,Y=math.huge,text="Таймаут ожидания"}
  246.         end
  247.       end
  248.     else
  249.       lines[1]={X=5,Y=1,text="<html>Ошибка подключения к сети OpenNet: <font color=0xFF0000>"..err.."</font>"}
  250.     end
  251.   end
  252.   wintext=codetext
  253.   if lines[1] then
  254.     lines[1].Y=1
  255.     if string.find(lines[1].text,"<%s*html.*>") then wintext=htmltext end
  256.   end
  257.   if History[#History]~=Site then table.insert( History, Site ) end
  258.   winhead()
  259.   wintext()
  260. end
  261.  
  262. local work=true
  263. function read()
  264.   gpu.setForeground( 0x000000 )
  265.   gpu.setBackground( 0xFFFFFF )
  266.   term.setCursor( 1, 2 )
  267.   term.clearLine()
  268.   term.setCursor( 2, 2 )
  269.   load(term.read(History,false))
  270. end
  271. function save()
  272.   if kbd then
  273.     gpu.setForeground( 0x000000 )
  274.     gpu.setBackground( 0xFFFFFF )
  275.     term.setCursor( 1, 2 ) term.clearLine()
  276.     term.setCursor( 2, 2 )
  277.     term.write("Safe as: ")
  278.     computer.pushSignal("key_down",kbd.address,0,200)
  279.     local Name=term.read({"/download/"..Site:match("[^/]*$")},false):sub(1,-2)
  280.     if Name~="" then
  281.       if not fs.exists("download") then fs.makeDirectory("download") end
  282.       local file=io.open(Name,"w")
  283.       if file then
  284.         for i=1,#lines-1 do file:write(lines[i].text.."\n") end
  285.         file:write(lines[#lines].text)
  286.         file:close()
  287.       else
  288.         term.clearLine()
  289.         term.setCursor( 2, 2 )
  290.         term.write("File "..Name.." can't be saved")
  291.         computer.beep()
  292.         os.sleep(2)
  293.       end
  294.     end
  295.     winhead()
  296.   end
  297. end
  298. function back()
  299.   if #History>1 then
  300.     History[#History]=nil
  301.     load(History[#History])
  302.   end
  303. end
  304. function quit()
  305.   gpu.setForeground( 0xFFFFFF )
  306.   gpu.setBackground( 0x000000 )
  307.   term.clear()
  308.   work=false
  309. end
  310.  
  311. do
  312.   local param=...
  313.   if param then load(param) else winhead() read() end
  314. end
  315. local Sh=false
  316. while work do
  317.   local ev, _, X, Y, S=event.pull()
  318.   if ev=="scroll" and Y>=Top then
  319.     if Sh then winshift(-5*S,0)
  320.     else winshift(0,-3*S) end
  321.   end
  322.   if ev=="key_down" then
  323.     if Y==208 then winshift(0,3) end
  324.     if Y==200 then winshift(0,-3) end
  325.     if Y==203 then winshift(-5,0) end
  326.     if Y==205 then winshift(5,0) end
  327.     if Y==29 then Sh=true end
  328.     if Y==15 then read() end
  329.     if Sh and Y==31 then save() end
  330.     if Y==14 then back() end
  331.     if Sh and Y==17 then quit() end
  332.   end
  333.   if ev=="key_up" and Y==29 then Sh=false end
  334.   if ev=="touch" and S==0 then
  335.     if Y==1 then
  336.       if X>=WinW-8 and X<=WinW-6 then save() end
  337.       if X>=WinW-5 and X<=WinW-3 then back() end
  338.       if X>=WinW-2 then quit() end
  339.     elseif Y==2 then read()
  340.     else
  341.       for i=1,#object do
  342.         if object[i]:check(X,Y) then object[i]:work() break end
  343.       end
  344.     end
  345.   end
  346. end
RAW Paste Data