5bitesofcookies

Sapphari 1.0 executable

Jun 12th, 2014
965
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.29 KB | None | 0 0
  1.  --Copyright 2014 Jackson McNeill
  2.  --You may edit this program without my permission, as long as copyright info is not altered in any way, but you must ask for and receive Jackson McNeill's permission to distrubute ANY version(s) of this program.
  3.  
  4.  if OneOS then
  5.   if shell.getRunningProgram() == "startup" then
  6.     --to make sure they're not running this in shell
  7.     --because if they are it'll crash.
  8.     OneOS.ToolBarColour = colours.lightGrey
  9.   end
  10. end
  11. --load redirect
  12. if not redirect then
  13.   os.loadAPI(shell.resolve(string.sub(shell.getRunningProgram(),1,#shell.getRunningProgram()-8)).."/redirect")
  14. end
  15. if not sapphUtils then
  16.   os.loadAPI(shell.resolve(string.sub(shell.getRunningProgram(),1,#shell.getRunningProgram()-8)).."/sapphUtils")
  17. end
  18. --Credits:
  19.  
  20. --Developers:
  21.  
  22. --Hithere
  23.  
  24.  
  25. --APIs
  26. --Redirect by GopherAtl
  27.  
  28. --Special thanks to:
  29.  
  30. --GopheralAtl For making Redirect, and being a very nice person. He's made stuff
  31. --for me personally before!
  32. --Sublime Text 2(yes I edit outside of the game)
  33. --For being the best text editor yet
  34.  
  35.  
  36.  
  37. --------------------------------------------------
  38.   sapphariVersionString = "1.0"
  39.   sapphariVersionNumber = 1
  40.  
  41.   sapphariSites = {}
  42.   sapphariBlacklist = {}
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.     --Note that this will be okay if the user
  53.     --has a script called pastebin
  54.     --because it runs it directly from rom
  55. shell.run("rom/programs/http/pastebin run Jg8D7mLi")
  56. --setting a new homepage:
  57. --I would REALLY prefer you keep the default one so you can get
  58. --updates on news and all that stuff and see cool new stuff
  59. --and sapphari updates, but I'm not going to try to stop you from
  60. --changing it. Uncomment out the line below and set it to the PasteID
  61.  
  62. --sapphariSites["home"] = "insertpagehere"
  63.  
  64. local sapphInt = {}
  65.  
  66. --for some reason there's a ton of debug sleeps in this version. Since the program is sandboxed, this is an okay solution(there's no sleeps in Sapphari)
  67. sSleep=sleep
  68. function sleep() end
  69.  
  70. function sapphInt.redrawUI()
  71.   term.setBackgroundColor(colors.white)
  72.   term.setTextColor(colors.black)
  73.   term.clear()
  74.   --it's funny how often when GUI coding,
  75.   --ever since advanced computers you
  76.   --don't need to set the cursor pos as much.
  77.   --Kinda nice to clear in one line.
  78.   --But you do have to set background and
  79.   --text colors. Sadface.
  80.   local termX, termY = term.getSize()
  81.   for i=1,2 do
  82.     paintutils.drawLine(1,i,termX,i,colors.lightGray)
  83.   end
  84.   paintutils.drawLine(2,1,termX/3,1,colors.white)
  85.   term.setBackgroundColor(colors.green)
  86.   term.setCursorPos(termX/3+2,1)
  87.   term.write("Refresh")
  88.   --now it's the right length.
  89.   term.setBackgroundColor(colors.lightGray)
  90.   term.setCursorPos(2,2)
  91.   term.write"Bookmarks | Tabs | Remove"
  92. end
  93. --this function will get the data for a site,
  94. --however, will not run it.
  95. function sapphInt.getSiteStr(pasteID)
  96.   if type(pasteID) =="string" then
  97.     local responce = http.get("http://pastebin.com/raw.php?i="..pasteID)
  98.     if responce then
  99.       return responce
  100.     end
  101.   end
  102. end
  103. function sapphInt.getSite(paste)
  104.   responce = sapphInt.getSiteStr(paste)
  105.   if responce then
  106.     return loadstring(responce.readAll())
  107.   else
  108.     return false
  109.   end
  110. end
  111. function sapphInt.handleMenu(typeClick, clickX, clickY,tabs,tabNames,bookmarks)
  112.   --handle the user   clicking the menu
  113.   local termX,termY=term.getSize()
  114.   if typeClick == 1 then
  115.     --okay, it's a left click, passes first one'
  116.     if clickX>1 then --okay, in somewhere special
  117.       if clickX<termX/3+1 and clickY==1 then
  118.         --okay, the user wants to change the url.
  119.         term.setCursorPos(2,1)
  120.         term.setBackgroundColor(colors.white)
  121.         return "newsite",sapphInt.read(2,1,termX/3)
  122.         --we will return the input
  123.       elseif clickX<13 and clickY==2 then --bookmarks button
  124.       local otherReturn = sapphInt.dropDownMenu(bookmarks,2,2)
  125.       if otherReturn ==1 then --new bookmark
  126.         return "bookmark",otherReturn
  127.       else
  128.         local newPlace = bookmarks[otherReturn]
  129.         return "newsite",newPlace --this will go to the bookmark!
  130.       end
  131.       elseif clickX>13 and clickX<18 and clickY==2 then -- tab button
  132.         --tabs button
  133.         --print"Tabz"
  134.         --insert the add a tab option
  135.         local otherReturn = sapphInt.dropDownMenu(tabNames,12,2)
  136.         return "tab",otherReturn
  137.       elseif clickX>20 and clickX<27 and clickY==2 then -- remove button
  138.         local stuffRemovable = {}
  139.         stuffRemovable[2] = "Bookmark" stuffRemovable[1] = "Tab" --cool people do it backwards
  140.         local result = sapphInt.dropDownMenu(stuffRemovable, 21,2)
  141.         if result==1 then --if it's a tab we know it's this one
  142.           return "removeTab"
  143.         elseif result ==0 then
  144.           return"nothing"
  145.         else
  146.           local result = sapphInt.dropDownMenu(bookmarks,21,2) --select the book mark removed
  147.           if result ==1 then
  148.             return "nothing"
  149.           elseif result==0 then
  150.             return"nothing"
  151.           else
  152.             table.remove(bookmarks,result)
  153.             local bookMarksWrite = fs.open(shell.resolve(string.sub(shell.getRunningProgram(),1,#shell.getRunningProgram()-8)).."/sapphBookmarks","w")
  154.             bookMarksWrite.writeLine(textutils.serialize(bookmarks))
  155.             bookMarksWrite.close()
  156.             return "rBook", bookmarks
  157.           end
  158.         end
  159.       end
  160.     end
  161.     if clickX>termX/3+1 then
  162.       if clickX<termX/3+8 then
  163.         --need to refresh page nao
  164.         return "newsite",currentSite
  165.       end
  166.     end
  167.   end
  168. end
  169. function sapphInt.decodeHumanReadableURL(HRURL)
  170.   --this is where we attempt to decode a
  171.   --human readable url. If fails, will tell
  172.   --calling function to attempt to use the
  173.   --plain url instead.
  174.   if sapphariSites[HRURL] then
  175.     --this must be an HRURL, so we'll give them'
  176.     --the pasteID
  177.     currentSite = sapphariSites[HRURL]
  178.     return sapphariSites[HRURL]
  179.   else
  180.     currentSite = HRURL
  181.     return HRURL
  182.     --this must be a PasteID then
  183.   end
  184. end
  185. --this is a really crappy function we don;t
  186. --want sites using. It's only for very
  187. --very basic textboxes and you can;t
  188. --use the arrow keys nor can you make
  189. --it multiline. Maybe someday I'll fix it up.'
  190. function sapphInt.read(startx, starty, endx)
  191.   term.setCursorBlink(true)
  192.   local textThing = ""
  193.   local textThingPrint=""
  194.   while true do
  195.     evt, text = os.pullEvent()
  196.     if evt == "key" then
  197.       if text==14 then
  198.         textThingPrint=string.sub(textThingPrint,1,#textThingPrint-1)
  199.         term.setCursorPos(7,7)
  200.         textThing=string.sub(textThing,1,#textThing-1)
  201.         local textThingAdd=string.sub(textThing,#textThing-#textThingPrint,#textThing-#textThingPrint)
  202.         textThingPrint = textThingAdd..textThingPrint
  203.       elseif text==28 then
  204.         term.setCursorBlink(false)
  205.         return textThing
  206.       end
  207.     elseif evt == "char" then
  208.       textThing=textThing..text
  209.       textThingPrint=textThingPrint..text
  210.     end
  211.     term.setCursorPos(startx,starty)
  212.     --format the string to fit the box
  213.     --patch for deleting under max text box
  214.     --length:
  215.     if #textThingPrint ==(endx-startx) then
  216.       textThingPrint = string.sub(textThingPrint,2,#textThingPrint)
  217.     end
  218.     local whitespacez = ""
  219.     for i=1,endx-startx do
  220.       --change that string VV for cool custom stuffz. Only one character, though!
  221.       whitespacez = whitespacez.." "
  222.     end
  223.     term.setCursorPos(startx,starty)
  224.     term.write(whitespacez)
  225.     --reset cursor
  226.     term.setCursorPos(startx,starty)
  227.     term.write(textThingPrint)
  228.     term.setCursorBlink(true)
  229.   end
  230. end
  231. --this must get  the pasteid, not the human
  232. --redable url
  233. function sapphInt.handleWebsite(url)
  234.   local rurl = sapphInt.decodeHumanReadableURL(url)
  235.   local site = sapphInt.getSite(rurl)
  236.   --we make a timer to refresh it
  237.   os.startTimer(0)
  238.   if site then
  239.     return coroutine.create(site)
  240.    else
  241.     return nil
  242.   end
  243. end
  244. function sapphInt.dropDownMenu(contents, x, y)
  245.   term.setTextColor(colors.black)
  246.   --YAY! GUI CODING! - Said Nobody, Ever
  247.   --find the longest variable in the table
  248.   local termX,termY=term.getSize()
  249.   term.setBackgroundColor(colors.white)
  250.  
  251.   --to refresh the menu for the first time
  252.   os.startTimer(0)
  253.    scrollDown = 0
  254.   longestvar = #contents[1]
  255.   for i=1,#contents do
  256.     if #contents[i] > longestvar then
  257.       longestvar = #contents[i]
  258.     end
  259.   end
  260.   while true do
  261.   local evt,keypress,mousex,mousey=os.pullEvent()
  262.     if evt == "key" and termY-y<#contents then
  263.       if keypress == 200 and scrollDown<0 then
  264.         scrollDown=scrollDown+1
  265.       elseif keypress == 208 and (scrollDown*-1)+termY-y<#contents then
  266.         scrollDown=scrollDown-1
  267.       end
  268.     elseif evt=="mouse_click" then
  269.      if mousex>x-1 and mousex<x+longestvar+1 then
  270.        --okay, the xpos is right. What about the
  271.        --ypos?
  272.        if mousey>y-1 and mousey<y+#contents+1 then
  273.          --we need to find the one clicked and minus
  274.          --it by the scroll variable.
  275.          return (mousey-y)-scrollDown
  276.        end
  277.      end
  278.     end
  279.     term.setBackgroundColor(colors.white)
  280.     if #contents<termY-y then
  281.       whiteSpaces = #contents
  282.     else
  283.       whiteSpaces=termY-y
  284.     end
  285.     local whitespace=""
  286.     for i=1,longestvar do
  287.       whitespace=whitespace.." "
  288.     end
  289.     for i=1,whiteSpaces do
  290.       term.setCursorPos(x,i+y)
  291.       print(whitespace)
  292.     end
  293.     term.setCursorPos(x-1,y)
  294.     contents[0] = ""
  295.     for i=1,whiteSpaces do
  296.       setX,setY=term.getCursorPos()
  297.       term.setCursorPos(x,setY+1)
  298.       term.write(contents[i-scrollDown])
  299.     end
  300.  
  301.   end
  302.   whiteSpaces = nil
  303. end
  304. function sapphInt.handleSapphari()
  305.   --fix os.pullEvent
  306.   sapphInt["timesHomed"]=19
  307.   oldPullEvent=os.pullEventRaw
  308.   os.pullEvent=os.pullEventRaw
  309.   local openSites = {}
  310.   local runningSite = 1
  311.   local siteNames = {}
  312.   local redirectBuffers = {}
  313.   local bookMarksRead = fs.open(shell.resolve(string.sub(shell.getRunningProgram(),1,#shell.getRunningProgram()-8)).."/sapphBookmarks","r")
  314.   local bookMarkers = bookMarksRead.readAll()
  315.   bookMarksRead.close()
  316.   local bookMarkers = textutils.unserialize(bookMarkers)
  317.   termX,termY=term.getSize()
  318.   siteNames[1] = "home"
  319.   --a table for open sites.
  320.   --Only the foucused site is ran
  321.   openSites[1] = sapphInt.handleWebsite("home")
  322.   termX,termY=term.getSize()
  323.   redirectBuffers[1] = redirect.createRedirectBuffer(termX,termY-2,colors.black,colors.white,true)
  324.   local normalTerm = term.current()
  325.   sapphInt.redrawUI()
  326.   while true do -- so that they can get to a new site on the event the site dies
  327.     local events = {os.pullEventRaw()}
  328.     if events[1] == "mouse_click" and events[4] <3 then
  329.       local sitesPassed = siteNames
  330.       table.insert(sitesPassed,1,"Add Tab")
  331.       local what, returned = sapphInt.handleMenu(events[2],events[3],events[4],openSites,sitesPassed,bookMarkers)
  332.       table.remove(sitesPassed,1)
  333.       sitesPassed=nil
  334.       if what == "newsite" and returned then
  335.         sapphInt["timesHomed"]=0
  336.         local tempSite = sapphInt.handleWebsite(returned)
  337.         if tempSite then
  338.           openSites[runningSite] = tempSite -- kill the current site and replace it
  339.           siteNames[runningSite] = returned
  340.         end
  341.       elseif what =="tab" then
  342.         sapphInt["timesHomed"]=0
  343.         if returned == 1 then
  344.           --make a new tab
  345.           runningSite = #openSites+1
  346.           openSites[#openSites+1] = sapphInt.handleWebsite("home")
  347.           siteNames[runningSite] = "home"
  348.           redirectBuffers[runningSite] = redirect.createRedirectBuffer(termX,termY-2,colors.black,colors.white,true)
  349.         elseif returned >1 then-- they're switching tabs. the greater than thing
  350.           --ensures it doesn't do this when they're just closing the menu.
  351.           runningSite = returned-1
  352.         end
  353.       elseif what == "bookmark" then
  354.         if returned ==1 then -- safety feature, though already done for us
  355.           bookMarkers[#bookMarkers+1] = siteNames[runningSite]
  356.           local bookMarksWrite = fs.open(shell.resolve(string.sub(shell.getRunningProgram(),1,#shell.getRunningProgram()-8)).."/sapphBookmarks","w")
  357.           bookMarksWrite.writeLine(textutils.serialize(bookMarkers))
  358.           bookMarksWrite.close()
  359.         end
  360.       elseif what == "rBook" then
  361.         bookMarkers = returned
  362.       elseif what =="removeTab" then--it wants us to remove the current tab.
  363.         if #openSites>1 then
  364.           table.remove(openSites,runningSite) -- we'll just remove the tab and it'll be fine
  365.           table.remove(siteNames,runningSite)
  366.         else--they probably want to exit
  367.           break--kills the loop, the function ends, cleanup is ran, then sapphari's coroutine dies and shell is resumed
  368.         end
  369.       end
  370.     elseif events[1] == "terminate" then
  371.       term.setCursorPos(5,5) --good spot, won't get in the way.
  372.       print"Are you trying to kill Sapphari?(\"yes\" to kill, anything else to go to homepage)"
  373.       if read() == "yes" then
  374.         error"User opted to kill Sapphari."
  375.       end
  376.       openSites[runningSite] = sapphInt.handleWebsite("home")
  377.     end
  378.     if openSites[runningSite] then
  379.       if coroutine.status(openSites[runningSite]) == "suspended" then else
  380.         sapphInt["timesHomed"]=sapphInt["timesHomed"]+1
  381.         sapphInt.redrawUI()
  382.         if runningSite ==1 then
  383.           openSites[runningSite] = sapphInt.handleWebsite("home")
  384.        else
  385.           openSites[runningSite] = nil --let this site die
  386.          runningSite = 1 --switch their tab  
  387.         end
  388.       end
  389.       if okay ==false then
  390.         sapphInt["timesHomed"]=sapphInt["timesHomed"]+1
  391.         okay=nil
  392.         theError=secondThing --so they can go into lua and see it
  393.         secondThing=nil
  394.         openSites[runningSite] = sapphInt.handleWebsite("home")
  395.         siteNames[runningSite] = "home"
  396.         sapphInt.redrawUI()
  397.       end
  398.     else
  399.       sapphInt.redrawUI()
  400.       if runningSite ==1 then
  401.         sapphInt["timesHomed"]=sapphInt["timesHomed"]+1
  402.         openSites[runningSite] = sapphInt.handleWebsite("home")
  403.       else
  404.         openSites[runningSite] = nil --let this site die
  405.         runningSite = 1 --switch their tab  
  406.       end
  407.     end
  408.     if openSites[runningSite] then
  409.       if coroutine.status(openSites[runningSite]) == "suspended" and events[1] == secondThing or coroutine.status(openSites[runningSite]) == "suspended" and not secondThing or coroutine.status(openSites[runningSite]) == "suspended" and secondThing=="download" then
  410.       term.redirect(redirectBuffers[runningSite])
  411.       --os.pullEvent = sapphInt.newPullEvent
  412.       if events[1] == "mouse_click" then
  413.         events[4] = events[4]-2
  414.       end
  415.       --sapphInt.fsSecurity(true)--make sure they don't get into fs
  416.       term.redirect(redirectBuffers[runningSite])
  417.       okay, secondThing, downloadID,downloadSpot = coroutine.resume(openSites[runningSite], unpack(events))
  418.       --sapphInt.fsSecurity()--no vars means it undoes the fs stuff
  419.       term.redirect(normalTerm)
  420.        --now we want to print the buffer on the screen
  421.        --This means that Sapphari is double-buffered.
  422.       local termX,termY=term.getSize()
  423.       redirectBuffers[runningSite].blit(1,1,1,3,termX,termY)
  424.       end
  425.     end
  426.     if secondThing == "download" then--they wanted to download something.
  427.       local dll = sapphInt.getSiteStr(downloadID)
  428.       dl=dll.readAll()
  429.       dll.close()
  430.       if dl and fs.exists(downloadSpot)==false then
  431.         local writeIt = sapphInt.fsStuff.open(downloadSpot,"w")
  432.         writeIt.write(dl)
  433.         writeIt.close()
  434.       end
  435.       secondThing=nil
  436.     end
  437.     if sapphInt["timesHomed"]>19 then--if going to home has happened 20 times or above
  438.       error"Sapphari went to home 20 times in arrow, assuming something is wrong."
  439.     end
  440.   end
  441. end
  442. ---------------------------------------------------
  443. function sapphInt.cleanup()
  444.   --so we don't leave crap floating arround.
  445.   --sometimes this gets left for some reason
  446.   --also we must reset pullEvent
  447.   openSites =nil --global variable cleanup
  448.   sapphUtils = nil
  449.   runningSite = nil
  450.   currentSite = nil
  451.   whiteSpaces = nil
  452.   whitespacez = nil
  453.   whitespace = nil
  454.   os.pullEvent=oldPullEvent
  455.   term.setCursorPos(1,1)
  456.   term.setBackgroundColor(colors.black)
  457.   term.setTextColor(colors.yellow)
  458.   term.clear()
  459.   print(os.version())
  460. end
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467. sapphInt.handleSapphari()
  468. sapphInt.cleanup()
  469. sleep=sSleep
Advertisement
Add Comment
Please, Sign In to add comment