Files @ e6f9a4843e49
Branch filter:

Location: Morevna/src/util.py

Laman
configurable log path
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<=i<n or n<i<=i0, (i0,i,n)
		percentage=Progress._p(i,n,i0)
		res="{0}%".format(percentage)
		if len(self._past)==0 or (now-self._past[-1][0]).total_seconds()>1:
			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()