import math import os import sys import collections from datetime import datetime def spawnDaemon(fun): # do the UNIX double-fork magic, see Stevens' "Advanced # Programming in the UNIX Environment" for details (ISBN 0201563177) try: pid = os.fork() if pid > 0: # parent process, return and keep running return except OSError as e: print("fork #1 failed: {0} ({1})".format(e.errno,e.strerror),file=sys.stderr) sys.exit(1) os.setsid() # do second fork try: pid = os.fork() if pid > 0: # exit from second parent print("[{0}] server running".format(pid)) sys.exit(0) except OSError as e: print("fork #2 failed: {0} ({1})".format(e.errno,e.strerror),file=sys.stderr) sys.exit(1) fun() # all done os._exit(os.EX_OK) def splitHost(host,defaultPort=0): address,_,port=host.partition(":") if not port: port=defaultPort return (address,port) class Progress: def __init__(self,n,i0=0): self._n=n self._i0=i0 self._i=i0 self._last="" self._past=collections.deque() def p(self,i): i0=self._i0 n=self._n now=datetime.now() assert i0<=i1: self._past.append((now,i)) if res!=self._last or (now-self._past[0][0]).total_seconds()>5: eta=formatSeconds(self.eta(i)) self._print("{0} (ETA {1})".format(res,eta)) self._last=res while (now-self._past[0][0]).total_seconds()>5: self._past.popleft() def done(self): self._print("100%",end="\n") def eta(self,i2): t2=datetime.now() (t1,i1)=self._past[0] if i2==i1: return float("nan") return (self._n-i2)/(i2-i1)*(t2-t1).total_seconds() @staticmethod def _p(i,n,i0): _1=1 if n>=i0 else -1 return 100*(i+_1-i0)//(n-i0) def _print(self,s,end=""): print("\r"+" "*80,end="") print("\r"+s,end=end) def formatSeconds(secs): if math.isnan(secs): return "?" secs=round(secs) if secs<60: return "{0}s".format(secs) mins=secs//60 secs%=60 if mins<60: return "{0:02}:{1:02}".format(mins, secs) hours=mins//60 mins%=60 return "{0:02}:{1:02}:{2:02}".format(hours, mins, secs) if __name__=="__main__": import random import time progress=Progress(100) for i in range(1,100): progress.p(i) time.sleep(random.random()*2) progress.done()