среда, 15 августа 2012 г.

python http multi-task client with retry-timer



from blessings import Terminal
import thread
from time import strftime,time,sleep
from twisted.internet import reactor
from twisted.internet.defer import Deferred, DeferredList
from twisted.internet.protocol import Protocol
from twisted.web.client import Agent, HTTPConnectionPool
from twisted.web.http_headers import Headers
from twisted.internet.error import AlreadyCalled, AlreadyCancelled

class BeginningPrinter(Protocol):
    def __init__(self,handler):
        self.handler=handler
    def dataReceived(self, received):
        self.handler(received)
    def connectionLost(self, reason):
        pass

class Site():
    def __init__(self,url,rest,wait,pool,md5=None,ind=None,name=None):
        self.url=url
        self.rest=rest
        self.wait=wait
        self.pool=pool
        self.md5=md5
        self.ind=ind if ind else 0
        self.name=name if name else self.url
        self.last_ask=0
        self.last_received=0
        self.agent = Agent(reactor, pool=pool)
        self.deferred=None
        self.delayedCall=None
    def __request(self):
        self.deferred = self.agent.request(
            'GET',
            self.url,
            Headers({'User-Agent': ['Mozilla/5.0']})
        )
        self.last_ask=time()
    def again(self):
        print strftime('%X'),'again'
        try:
            self.deferred.cancel()
        except (AlreadyCalled, AlreadyCancelled) :
            pass
        try:
            self.delayedCall.reset(self.wait)
        except (AlreadyCalled, AlreadyCancelled) :
            self.delayedCall = reactor.callLater(self.wait, self.timeIsOff)

        self.__request()
        self.deferred.addCallback(self.gotRequest)
    def timeIsOff(self):
        print strftime('%X'),'time is off'
        self.again()
    def handleReceived(self, received):
        print strftime('%X'),'received: ',received
    def gotRequest(self, response):
        print strftime('%X'),'gotRequest'
        self.last_received=time()
        self.again()
        print 'Response code:', response.code
        response.deliverBody(BeginningPrinter(self.handleReceived))
    def startLive(self):
        print strftime('%X'),'startLive'
        self.__request()
        self.deferred.addCallback(self.gotRequest)
        self.delayedCall = reactor.callLater(self.wait, self.timeIsOff)
    def norm_time(self,t):
        now=time()
        seconds=int(now-t) if now>t else int(t-now)
        m, s = divmod(seconds, 60)
        h, m = divmod(m, 60)
        return "%d:%02d:%02d" % (h, m, s) if h!=0 else "%d:%02d" % (m, s) if m!=0 else "%ds" % (s)
    def report(self):
        return {'name':self.name,
                'wait':self.wait,
                'last_ask':self.norm_time(self.last_ask),
                'last_received':self.norm_time(self.last_received),
                'when_next':self.norm_time(self.delayedCall.getTime())}
pool = HTTPConnectionPool(reactor)
site1 = Site(url='http://wool/cgi-bin/wait.cgi',rest=3,wait=4,pool=pool)
site1.startLive()


t = Terminal()

def live_report(*a):
    while True:
        print t.green_on_black,
        print site1.report(),
        print t.normal,
        sleep(2)
thread.start_new(live_report,(0,))
reactor.run()

Комментариев нет:

Отправить комментарий