Python1320

Http query queue thingy

Jul 21st, 2011
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.73 KB | None | 0 0
  1.  
  2. local Tag="hdata"
  3.  
  4.  
  5. local setmetatable=setmetatable
  6.  
  7.  
  8. local class do -- http://lua-users.org/wiki/SimpleLuaClasses
  9.     -- class.lua
  10.     -- Compatible with Lua 5.1 (not 5.0).
  11.     class = function(base, init)
  12.        local c = {}    -- a new class instance
  13.        if not init and type(base) == 'function' then
  14.           init = base
  15.           base = nil
  16.        elseif type(base) == 'table' then
  17.         -- our new class is a shallow copy of the base class!
  18.           for i,v in pairs(base) do
  19.              c[i] = v
  20.           end
  21.           c._base = base
  22.        end
  23.        -- the class will be the metatable for all its objects,
  24.        -- and they will look up their methods in it.
  25.        c.__index = c
  26.  
  27.        -- expose a constructor which can be called by <classname>(<args>)
  28.        local mt = {}
  29.        mt.__call = function(class_tbl, ...)
  30.        local obj = {}
  31.        setmetatable(obj,c)
  32.        if init then
  33.           init(obj,...)
  34.        else
  35.           -- make sure that any stuff from the base class is initialized!
  36.           if base and base.init then
  37.           base.init(obj, ...)
  38.           end
  39.        end
  40.        return obj
  41.        end
  42.        c.init = init
  43.        c.is_a = function(self, klass)
  44.           local m = getmetatable(self)
  45.           while m do
  46.              if m == klass then return true end
  47.              m = m._base
  48.           end
  49.           return false
  50.        end
  51.        setmetatable(c, mt)
  52.        return c
  53.     end
  54. end -- http://lua-users.org/wiki/SimpleLuaClasses
  55.  
  56. --TEST
  57. local _class = class(function(a,name)
  58.    a.name = name
  59. end)
  60. --_class.__newindex=function(a,b,c) print("asserttest","newindex",type(a),type(b),type(c)) rawset(a,b,c) end
  61. _class.__tostring=function(s)return s.name end
  62. local name="test"
  63. local _=_class(name)
  64. assert(tostring(_)==name)
  65. _.testkey="testvalue"
  66. _=nil
  67. --ETEST
  68.  
  69.  
  70. local insert=table.insert
  71. local remove=table.remove
  72. local Empty=table.Empty
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80. -------------------------------------------------------------
  81.  
  82.  
  83.  
  84. local FIFO do -- STACK IMPLEMENTATION
  85.     FIFO=class()
  86.     function FIFO:__tostring() return "< Stack "..tostring(self:len()).." >" end
  87.  
  88.     -- Pop
  89.     function FIFO:pop()
  90.         return remove( self , self.lilo and #self or 1 )
  91.     end
  92.  
  93.     -- push
  94.     function FIFO.push(a,b)
  95.         insert( a , b )
  96.         return a
  97.     end
  98.  
  99.     function FIFO:len()
  100.         return #self
  101.     end
  102.  
  103.     function FIFO:length()
  104.         return #self
  105.     end
  106.  
  107.     function FIFO:clear()
  108.         return Empty( self )
  109.     end
  110.    
  111. end -- STACK IMPLEMENTATION
  112.  
  113. --TEST
  114. local _=FIFO()
  115. assert(_:push("a")==_)
  116. assert(_:push("b")==_)
  117. assert(_:pop()=="a")
  118. print("asserttest",_)
  119. assert(_:pop()=="b")
  120. assert(!_:pop())
  121.  
  122. _=nil
  123. --ETEST
  124.  
  125. local thinks do -- THINK IMPLEMENTATION
  126.     thinks=class()
  127.     meta.name="Think Queue"
  128.  
  129.     function thinks:__tostring() return "< ".."Thinks".." - "..table.Count(self).." thinks >" end
  130.    
  131.     function thinks:Add(obj,thinkfunc)
  132.         self[obj]=thinkfunc or true
  133.         if not hook:GetTable().Think[Tag] then
  134.             print("Adding think")
  135.             hook.Add('Think',Tag,function() self:Think() end)
  136.         end
  137.     end
  138.     function thinks:Remove(obj)
  139.         if self[obj] then
  140.             self[obj]=nil
  141.             return true
  142.         end
  143.         return false
  144.     end
  145.  
  146.     function thinks:Think()
  147.         local done=true
  148.         for obj,thinkfunc in pairs(self) do
  149.             done=false
  150.             local bOk, strReturn = pcall( thinkfunc,obj )
  151.             if !bOk then
  152.                 ErrorNoHalt( "Think failure:"+strReturn )
  153.             end
  154.         end
  155.         if done then
  156.             print("Removing thinking")
  157.             hook.Remove('Think',Tag)
  158.         end
  159.     end
  160.  
  161. end -- THINK IMPLEMENTATION
  162.  
  163. --TEST
  164. local _=thinks()
  165. local boo=false
  166. _:Add("!",function() boo=true _:Remove("!") end)
  167. _:Add("_",function() end)
  168. _:Think()_:Think()_:Think()_:Think()_:Think()
  169. assert(boo==true)
  170. print("asserttest",_)
  171. assert(_:Remove("_")==true)
  172. print("asserttest",_)
  173. _:Think()
  174. --ETEST
  175.  
  176. local thinks=thinks()
  177.  
  178.  
  179. local HTTPQueryObject do -- HTTP QUERY OBJECT HELPERS
  180.     HTTPQueryObject=class()
  181.    
  182.  
  183.     function HTTPQueryObject:__tostring()  
  184.         return "< ".."HTTPQueryObject".." - Timeout "..tostring(self:GetTimeout() or 0).." - Started "..tostring(self:GetStarted()).." >"
  185.     end
  186.  
  187.     AccessorFunc(HTTPQueryObject,"__headers","Header",FORCE_STRING)
  188.     AccessorFunc(HTTPQueryObject,"__callback","Callback")
  189.     AccessorFunc(HTTPQueryObject,"__timeout","Timeout",FORCE_NUMBER)
  190.     AccessorFunc(HTTPQueryObject,"__started","Started",FORCE_BOOL)
  191.        
  192.  
  193. end -- HTTP QUERY OBJECT HELPERS
  194.  
  195.  
  196.  
  197. --TEST
  198. local _=HTTPQueryObject()
  199. _:SetStarted(true)
  200. assert(_:GetStarted()==true)
  201. print("asserttest",_)
  202. assert(tostring(_)!="")
  203. _=nil
  204. --ETEST
  205.  
  206.  
  207.  
  208.  
  209. local queryqueue do -- QUERY QUEUE IMPLEMENTATION
  210.    
  211.     queryqueue  = class(function( tbl, host )
  212.         local http = tbl:GetHTTPGet()
  213.         assert(http:Finished()==false)
  214.         tbl:__sethost(host or "http://gmod.iriz.org:20090")
  215.         tbl.stack=FIFO()
  216.         return tbl
  217.     end)
  218.    
  219.     function queryqueue:__tostring()   
  220.         return "< ".."Query Object".." >"
  221.     end
  222.            
  223.  
  224.     function queryqueue:GetProcess()
  225.         return self.__proc
  226.     end
  227.     function queryqueue:SetProcess(proc)
  228.         self.__proc = proc
  229.     end
  230.    
  231.     function queryqueue:GetHTTPGet(new)
  232.         if new or not self.__HTTPGet then
  233.             self.__HTTPGet=HTTPGet()
  234.         end
  235.         return self.__HTTPGet
  236.     end
  237.    
  238.     -- not finished if not even started!!
  239.     function queryqueue:HTTPIsFinished()
  240.         return self:GetHTTPGet():Finished()
  241.     end
  242.    
  243.     function queryqueue:GetCurrentData()
  244.             local buf = self:GetHTTPGet():GetBuffer()
  245.             local len = self:GetHTTPGet():DownloadSize()
  246.  
  247.             return buf,len
  248.     end
  249.    
  250.     function queryqueue:Download(host,header)  
  251.         if header and header:len() > 0 then -- hack
  252.             header="Accept: */*\n"..header
  253.         else
  254.             header = ""
  255.         end
  256.        
  257.         self:GetHTTPGet():Download(host,header)
  258.        
  259.     end
  260.    
  261.     function queryqueue:Process(proc)
  262.        
  263.         local started = proc:GetStarted()
  264.         if not started then
  265.             proc:SetStarted(true)
  266.             self:GetHTTPGet(true) -- We need to reset it :\
  267.             print("Started processing new",proc,"to",self:gethost())
  268.            
  269.             --proc:GetTimeout()
  270.            
  271.             self:Download( self:gethost(), proc:GetHeader())
  272.         end
  273.        
  274.        
  275.         if proc:GetStarted() and self:HTTPIsFinished() then
  276.             local proc = self:GetProcess()
  277.             self:SetProcess( nil )
  278.            
  279.             local callback = proc:GetCallback()
  280.             if not callback then
  281.                 print("processed",proc,"without callbacks?")
  282.                 return
  283.             end
  284.            
  285.             local buf,len=self:GetCurrentData()
  286.            
  287.             local ok, ret = pcall( callback, buf, len )
  288.             if not ok then
  289.                 ErrorNoHalt( meta.name.." callback error: "+ret+"\n" )
  290.             end
  291.  
  292.         end
  293.        
  294.     end
  295.  
  296.     function queryqueue:Think()
  297.         local proc=self:GetProcess()
  298.         if proc then
  299.             self:Process(proc)
  300.             return
  301.         end
  302.         if self:GetProcess() then return end
  303.         local newdata=self.stack:pop()
  304.         if newdata then
  305.             --print("grabbing new process",newdata)
  306.             self:SetProcess( newdata )
  307.             return
  308.         end
  309.         print("stopped thinking",self)
  310.         thinks:Remove(self)
  311.     end
  312.  
  313.     function queryqueue:Wake()
  314.         if self.stack:len() > 0 then
  315.             print("waking up")
  316.             thinks:Add(self,self.Think)
  317.         end
  318.     end
  319.  
  320.     function queryqueue:query(header,callback,timeout)
  321.        
  322.         local proc = HTTPQueryObject()
  323.        
  324.         if header then
  325.             proc:SetHeader(header)
  326.         end
  327.         if callback then
  328.             proc:SetCallback(callback)
  329.         end
  330.         if timeout then
  331.             proc:SetTimeout(timeout)
  332.         end
  333.            
  334.         self.stack:push(proc)
  335.         self:Wake()
  336.     end
  337.     function queryqueue:gethost()
  338.         return self.def_host
  339.     end
  340.     function queryqueue:__sethost(host)
  341.         self.def_host = host
  342.     end
  343.    
  344.     function queryqueue:GetQueueLength()
  345.         return self.stack:len()
  346.     end
  347.  
  348. end -- QUERY QUEUE IMPLEMENTATION
  349.  
  350.  
  351.  
  352. --TEST
  353. local host="http://iriz.org"
  354. _G._=queryqueue(host)
  355. local _=_G._
  356. assert(_:HTTPIsFinished()==false)
  357. _:query(nil,function(a,b)print("callback:",a:len()) assert(a:len()>0) end,0)
  358. _:query(nil,function(a,b)print("callback:",a:len()) assert(a:len()>0) end,0)
  359. _:query(nil,function(a,b)print("callback:",a:len()) assert(a:len()>0) end,0)
  360. assert(_:GetQueueLength()==3)
  361. print("host:",_:gethost())
  362. assert(_:gethost()==host)
  363.  
  364. do return end
  365. --ETEST
  366.  
  367. local hyperdata do -- HYPERDATA IMPLEMENTATION
  368.  
  369.     local meta  = { name = "Hyperdata" ,__index={},__call = function(self) return self.__init and self:__init() end}
  370.     hyperdata   = setmetatable({},meta)
  371.  
  372.         function meta:__tostring() 
  373.             return "< "..meta.name.." - "..tostring(self:gethost()).." >"
  374.         end
  375.            
  376.     local object=meta.__index
  377.  
  378.     -- "export"
  379.     _G[Tag]=hyperdata
  380.  
  381.         function object:gethost()
  382.             return self.httpqueue:gethost()
  383.         end
  384.  
  385.         function object:test(callback)
  386.             http.Get(self:gethost(),"",function(_,b)
  387.                 callback(b>0)
  388.             end)
  389.         end
  390.  
  391.         function object:GetQueryQueue()
  392.             return self.httpqueue
  393.         end
  394.        
  395.         function object:__init(host)
  396.             local tbl=setmetatable({},meta)
  397.             tbl.httpqueue=queryqueue(host or "http://gmod.iriz.org:20090") or "HURR??"
  398.             tbl.derp="herp"
  399.             print(tbl.httpqueue)
  400.            
  401.             print("New",self)
  402.             return tbl
  403.         end
  404.  
  405. end -- HYPERDATA IMPLEMENTATION
  406.  
  407.  
  408. _G.asd=hyperdata()
  409.  
  410. print("created",_G.asd)
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419. do return end
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428. local a=hdata()
  429. print(a)
  430. a:test(function(...)print("res",...)end)
  431.  
  432.  
  433. do return end
  434.  
  435. def_host="http://gmod.iriz.org:20090"
  436.  
  437.  
  438. function Create(host)
  439.     local data={}
  440.     data.host=host or def_host
  441.     return data
  442. end
  443.  
  444. function Request(data,req,values,callback)
  445.     local payload="Accept: */*\n"
  446.     payload=payload.."type: "..req
  447.     if values then
  448.         for k,v in pairs(values) do
  449.             local str="\n"..k..": "..v
  450.             payload=payload..str
  451.         end
  452.     end
  453.     http.Get(data.host,payload,function(resp,b)
  454.         -- empty response, server error?
  455.         if b==0 then
  456.             callback(false)
  457.             return
  458.         end
  459.         local pos=resp:find("\n",1,true)
  460.         if not pos then
  461.             print("resp fail")
  462.             callback(false,resp)
  463.             return
  464.         end
  465.         local hyperdata=resp:sub(1,pos-1)
  466.         local resp_data=resp:sub(pos+1,-1)
  467.        
  468.         local hyperdata_resp=hyperdata:match("H%: (.*)")
  469.        
  470.         print("hyperdata response: ",hyperdata_resp)
  471.        
  472.         if !hyperdata_resp then
  473.             print("hyperdata transfer fail. Received:",resp)
  474.             callback(false,resp)
  475.             return
  476.         end
  477.        
  478.         callback(resp_data)
  479.     end)
  480. end
  481. local dat=Create()
Advertisement
Add Comment
Please, Sign In to add comment