#!/usr/bin/python
import sys, os, time, socket;
from threading import Thread;
import thread

class Serve(Thread):
	def __init__(self, clientsocket, address, io):
		self.socket=clientsocket;
		self.address=address;
		self.io=io;


	def run(self):
		self.socket.send(io.output())
		self.socket.close()
	

class iffoo(Thread):
	interfaces=[]
	sleepvalue=2
	netdev="/proc/net/dev"
	ifconfig="/sbin/ifconfig"
	infos={}
	running=0

	def __init__(self, argv, serv):
		Thread.__init__(self)
		self.running=1
		if len(argv)==1:
			self.readNetDevs([])
		else:
			self.readNetDevs(argv[1:])
		for iface in self.interfaces:
			self.infos[iface]={}
			self.infos[iface]['rxlast']=float(self.getRX(iface))
			self.infos[iface]['txlast']=float(self.getTX(iface))
			self.infos[iface]['rxstart']=self.infos[iface]['rxlast']
			self.infos[iface]['txstart']=self.infos[iface]['txlast']
			self.infos[iface]['rxrate']=float(0)
			self.infos[iface]['txrate']=float(0)
			self.infos[iface]['rxact']=float(0)
			self.infos[iface]['txact']=float(0)
		thread.start_new_thread(self.calc, ())
		if serv==1:
			thread.start_new_thread(self.listen, ())
		
	def listen(self):
		try:
			serversocket = socket.socket(
			socket.AF_INET, socket.SOCK_STREAM)
			serversocket.bind((socket.gethostname(), 8888))
			serversocket.listen(1)
		except:
			print "can't bind to %s on port %i" % (socket.gethostname(), 8888)
			self.running=0
			sys.exit(0)
		while 1:
			(clientsocket, address) = serversocket.accept()
			ct = Serve(clientsocket, address, self)
			ct.run()
	
	def run(self):
		while 1:
			self.calc()
	

	def findDev(self, device):
		fp=open(self.netdev);
		for line in fp.readlines():
			if line.strip().startswith(device.strip()):
				return line.strip();
		return 0 

	def format(self, mystring):
		bytes=float(mystring)
		e=' '
		if bytes>999999999.0:
			bytes=bytes/1024/1024/1024
			e='G'	
		elif bytes>999999.0:
			bytes=bytes/1024/1024
			e='M'
		elif bytes>999.0:
			bytes=bytes/1024
			e='K'
		else:
			e=' '
		return [ bytes,  e] 

	def empty(self, element):
		if element=="":
			return 0
		return 1

	def getRX(self, device):
		info=self.findDev(device)
		informations=info.split(":");
		bytes=informations[1]
		rx=filter(self.empty, bytes.split(" "))
		return rx[0]

	def getTX(self,device):
		info=self.findDev(device)
		informations=info.split(":");
		bytes=informations[1]
		tx=filter(self.empty, bytes.split(" "))
		return tx[8]

	def isUp(self, iface):
		fp=os.popen(self.ifconfig);
		for line in fp.readlines():
			if line.startswith(iface.strip()):
				return 1
		return 0

	def readNetDevs(self, devlist):
		if len(devlist)==0:
			devs=open(self.netdev);
			for line in devs.readlines():
				iface=line.split(":")
				if len(iface)==2:
					if (self.isUp(iface[0])==1):
						self.interfaces.append(iface[0])
			devs.close()
		else:
			for iface in devlist:
				if (self.isUp(iface)==1):
					self.interfaces.append(iface)

	def getIP(self, iface):
		command="%s %s" % (self.ifconfig, iface)
		fp=os.popen(command)
		line=fp.readlines()
		try:
			return socket.inet_ntoa(socket.inet_aton(line[1].strip().split(" ")[1].split(":")[1]))
		except: 
			return "No IP set"

	def clear(self):
		os.system("clear")


	def calc(self):
		while 1:
			if self.running!=1:
				sys.exit(0)
			for iface in self.infos:
				self.infos[iface]['rxact']=float(self.getRX(iface))
				self.infos[iface]['txact']=float(self.getTX(iface))
				self.infos[iface]['rxrate']=(self.infos[iface]['rxact']-self.infos[iface]['rxlast'])/self.sleepvalue
				self.infos[iface]['txrate']=(self.infos[iface]['txact']-self.infos[iface]['txlast'])/self.sleepvalue
				self.infos[iface]['rxlast']=self.infos[iface]['rxact']
				self.infos[iface]['txlast']=self.infos[iface]['txact']
			time.sleep(self.sleepvalue)


	def output(self):
		list=[]
		for iface in self.infos:
			list.append(iface+ ": "+ io.getIP(iface)+"\n")
			info="\ttx: %07.2f %cByte/s\n" % (self.format(self.infos[iface]['txrate'])[0], self.format(self.infos[iface]['txrate'])[1])
			list.append(info)
			info="\trx: %07.2f %cByte/s\n" % (self.format(self.infos[iface]['rxrate'])[0], self.format(self.infos[iface]['rxrate'])[1])
			list.append(info)
			info="\tSummary:\n\t\tSince iffoo start Up: %07.2f %cByte Down: %07.2f %cByte\n" % (self.format(self.infos[iface]['rxact']-(self.infos[iface]['rxstart']))[0], self.format(self.infos[iface]['rxact']-self.infos[iface]['rxstart'])[1], self.format(io.infos[iface]['txact']-(self.infos[iface]['txstart']))[0], self.format(self.infos[iface]['txact']-self.infos[iface]['txstart'])[1])
			list.append(info)
			info="\t\tSince Uptime: Up: %07.2f %cByte Down: %07.2f %cByte\n" % (self.format(self.infos[iface]['rxact'])[0], self.format(self.infos[iface]['rxact'])[1], self.format(self.infos[iface]['txact'])[0], self.format(self.infos[iface]['txact'])[1])
			list.append(info)
		return ''.join(list)


if __name__ == "__main__":
	if (len(sys.argv)>=2) and sys.argv[1]=="-s":
		pid=os.fork()
		try:
			if pid>0:
				sys.exit(0)
			print "forkering()"
			io=iffoo(sys.argv[1:], 1)
			while 1:
				time.sleep(io.sleepvalue)
		except OSError:
			print "no forksens allowed"
			sys.exit(0);
	else:
		io=iffoo(sys.argv, 0)
		while 1:
			print io.output();
			time.sleep(io.sleepvalue)
			io.clear()
