class TableController(StandardController):
	_filename = 'psp/table.psp'

	def __init__(self, req, name, title=None, dbOrder=True,
		showHeaders=True,className='standardTable',emptyMessage='No Data Found',extraFooter=None,extraFooterClass='',enableExport=False):
		StandardController.__init__(self,req,createContent=False)

		self.name = name
		self._headers = []
		self._snames = []
		self._rows = []
		self.dbOrder = dbOrder
		self._sortCalced = False
		self.title = self.escape(title)
		self.hasFooter = False
		self.showHeaders = showHeaders
		self.className = className
		self._emptyMessage = emptyMessage
		self.extraFooter = extraFooter
		self.extraFooterClass = extraFooterClass
		self.formatTable = True
		self.enableExport = enableExport

	def calcSorting(self):
		if self._sortCalced: return
		self._sortCalced = True
		
		lastSum = False
		self._headers.reverse()
		for col in self._headers:
			if col.flagSum:
				lastSum = True
				self.hasFooter = True
			elif lastSum:
				col.flagTotal = True
				lastSum = False
		self._headers.reverse()

		sortColName = self.getField(self.name+'Sort')
		sortOrder = self.getField(self.name+'SortOrder')
		if sortOrder != 'desc' and sortOrder != 'asc': sortOrder = None

		self.dbSortable = False
		self.sortColIdx = None
		for i in range(len(self._headers)):
			col = self._headers[i]
			col.idx = i
			if sortColName and col.flagSorted and sortColName != col.sname:
				# there can only be one sorted column
				col.flagSorted = False
			if col.flagSorted or sortColName == col.sname:
				# the sort column found
				self.sortColIdx = i
				sortColName = col.sname
				col.flagSorted = True
				if sortOrder == 'desc':
					col.flagSortDesc = True
				elif sortOrder == 'asc':
					col.flagSortDesc = False
				sortOrder = col.getSortOrder()

				if self.dbOrder and (col.flagDbOrder == None or col.flagDbOrder):
					self.dbSortable = True

		self.sortColName = sortColName
		self.sortOrder = sortOrder

	def createContent(self):
		self.calcSorting()
		if self._headers:
			self._headers[0].isFirst = True
			self._headers[-1].isLast = True

		if self.sortColIdx != None and not self.dbSortable:
			rev = False
			if self.sortOrder == 'desc': rev = True
			self.sortRows(self.sortColIdx,rev)

		formatTable = StringToBool(self.getField('formatTable'),none=self.formatTable)
		if formatTable: self.formatIndex = 0
		else: self.formatIndex = 1
		fields = self.getAllFields()
		fields['exportTable'] = self.name
		self.exportURL = escape(urlencode(fields))

	def sortRows(self,col,rev):

		k = lambda x: x[col][1]
		def c(a, b):
			if a == b: return 0
			elif a == None: return -1
			elif b == None: return 1
			else: return cmp(a,b)
		self._rows.sort(c,key=k,reverse=rev)

	def getContent(self,shadowdrop=True):
		if shadowdrop: return self.shadowdrop(self.getContent(shadowdrop=False))
		self.createContent()
		return StandardController.getContent(self)

	def addHeader(self,header):
		assert(isinstance(header,TableHeader))
		assert(header.sname not in self._snames)

		header.parent = self
		self._headers.append(header)
		self._snames.append(header.sname)
	
	def addRow(self,*arg,**keywords):
		#for key in keywords: assert(key in self._snames)

		row = []
		for hcol in self._headers:
			row.append(hcol.preProcess(keywords.get(hcol.sname,None)))
		row.append( keywords.get('oddevenclass', '') )
		row.append( keywords.get('rowclass', '') )
		self._rows.append(row)

	def getOrderBy(self):
		self.calcSorting()
		if self.dbSortable:
			return '%s %s' % ( self.sortColName, self.sortOrder )
		return None
	
	def setEmptyMessage(self,emptyMessage):
		self._emptyMessage = emptyMessage
	
	def getName(self):
		return self.name
	
	def setExportable(self,enable=True):
		self.enableExport = enable class TH(TableHeader): pass class PropTableController(StandardController):
	_filename = 'psp/propTable.psp'

	def __init__(self, req, title):
		StandardController.__init__(self,req,createContent=False)

		self.title = self.escape(title)
		self._rows = []
	
	def addRow(self,row):
		assert(isinstance(row,TR))
		self._rows.append(row)

	def getContent(self,shadowdrop=True):
		if shadowdrop: return self.shadowdrop(self.getContent(shadowdrop=False))
		return StandardController.getContent(self) class TR(TableRow): pass class II(InputItem):
	pass class BytesToText:
	__fixed = False
	__showUnit = True
	__base = 1024
	__units = ['Y','Z','E','P','T','G','M','K','']
	__digits = None
	def __init__(self,value,fixed=None,showUnit=None,base=None,digits=None):
		try:
			value = int(value)

			if fixed == None: fixed = self.__fixed
			if showUnit == None: showUnit = self.__showUnit
			if base == None: base = self.__base
			if digits == None: digits = self.__digits
			if base not in (1024,1000): showUnit = False
			if not showUnit and not fixed: fixed = True
			unit = copy.deepcopy(self.__units)

			if fixed or fixed == '':
				if digits == None: digits = 0
				if fixed in unit:
					while unit[-1] != fixed:
						value /= float(base)
						unit.pop()
			else:
				if digits == None: digits = 2
				value = float(value)/float(base)
				unit.pop()
				while value >= 1000:
					value /= float(base)
					unit.pop()

			self.__value = ('%%1.%df' % digits) % value

			if showUnit:
				unit = unit.pop()
				if base == 1024 and unit: base = 'i'
				else: base = ''
				self.__value += ' %s%sB' % (unit,base)
		except:
			self.__value = 'NaN'
	def __str__(self):
		return self.__value
	def __repr__(self):
		return self.__value
	
	def setFixed(cls,fixed): cls.__fixed = fixed
	setFixed = classmethod(setFixed)
	def getFixed(cls): return cls.__fixed
	getFixed = classmethod(getFixed)

	def setShowUnit(cls,on=True): cls.__showUnit = on
	setShowUnit = classmethod(setShowUnit)
	def getShowUnit(cls): return cls.__showUnit
	getShowUnit = classmethod(getShowUnit)

	def setBase(cls,base=1024):
		try: cls.__base = int(base)
		except: cls.__base = 1024
	setBase = classmethod(setBase)
	def getBase(cls): return cls.__base
	getBase = classmethod(getBase)

	def setPrecision(cls,digits):
		try: cls.__digits = max(0,min(66,int(digits)))
		except: cls.__digits = None
	setPrecision = classmethod(setPrecision)
	def getPrecision(cls): return cls.__digits
	getPrecision = classmethod(getPrecision) class DefaultDict(dict):
		"""Dictionary with a default value for unknown keys."""
		def __init__(self, default):
				self.default = default

		def __getitem__(self, key):
				if key in self: 
						return self.get(key)
				else:
						## Need copy in case self.default is something like []
						return self.setdefault(key, copy.deepcopy(self.default))

		def __copy__(self):
				copy = DefaultDict(self.default)
				copy.update(self)
				return copy def getPluralMap(items):
	m = {}
	if len(items) == 1:
		return singularMap
	else:
		return pluralMap def getDeltaString(timedelta):
	return str(timedelta).split(',')[0] class NullLogger:
class XMLLogger(NullLogger):
		class PsudoStream:
class Logger(NullLogger):
class FileLogger(Logger):
class BytesToText:
class DefaultDict(dict):
	def _reset(self): pass
	def _close(self): pass
	def start(self,text='',reset=False): pass
	def format(self, delta):
	def end(self,text=None,close=False): pass
	def show(self,text=None,prefix=None): pass
	def flush(self): pass
def testXML():
	def __init__(self,filename):
	def _getCurrentAction(self,pop=False,close=False):
	def start(self,text=None,reset=False):
	def end(self,text=None,close=False):
	def show(self,text=None,prefix=None):
	def _getTimeString(self,ts=None):
	def flush(self):
			def __init__(self,file):
			def write(self,data):
			def read(self,length): return self.file.read(length)
			def close(self): self.file.close()
			def seek(self,pos,whence=0): self.file.seek(pos,whence)
	def _update(self,file):
	def _getAttribute(self,text,attribute):
	def __init__(self):
	def _reset(self):
	def start(self, text,reset=False):
	def end(self, text = '',close=False):
	def show(self, text, prefix = '*'):
	def output(self, message):
	def flush(self):
	def __init__(self,filename):
	def _open(self):
	def output(self,message):
	def _reset(self):
	def _close(self):
def StringToBool(string,default=False,empty=False,none=False,true=True,false=False):
	def __init__(self,value,fixed=None,showUnit=None,base=None,digits=None):
	def __str__(self):
	def __repr__(self):
	def setFixed(cls,fixed): cls.__fixed = fixed
	def getFixed(cls): return cls.__fixed
	def setShowUnit(cls,on=True): cls.__showUnit = on
	def getShowUnit(cls): return cls.__showUnit
	def setBase(cls,base=1024):
	def getBase(cls): return cls.__base
	def setPrecision(cls,digits):
	def getPrecision(cls): return cls.__digits
def timestamp(datetime):
def day():
		def __init__(self, default):
		def __getitem__(self, key):
		def __copy__(self):
def generateHash(key):
def dayOfWeek(date):
def getPluralMap(items):
def getDeltaString(timedelta):
def getCurrentUser():
def getCurrentGroup():
def main():
from core.tableControllers import TableController,TH,PropTableController,TR
from core.inputControllers import II
from core.utils import BytesToText,DefaultDict,getPluralMap,getDeltaString
from core import utils
from statmonControllers import StatmonController
from urllib import urlencode
from cgi import escape
from math import log10
		from __init__ import __version__
		from statmonControllers import decodeGraph, encodeGraph
		from grapher import fromRRDTime
import model
import grapher
import datetime
import time
import re
import copy
import os





class NodeListController(StatmonController):
	_title = 'Domains & Nodes'
	_filename = 'psp/nodelist.psp'
	_selectedDomains = None
	_selectedNodes = None
	def createContent(self):
		domainfilter = self.processInput(self.standardInputs['domain'])
		nodefilter = self.processInput(self.standardInputs['node'])
		#start, end = self.getStartEnd('graphstart','graphend')

		#params = self.params
		#params['domainfilter'] = domainfilter
		#params['nodefilter'] = nodefilter
		#params['graphstart'] = start
		#params['graphend'] = end
		#params['imagewidth'] = '409' # ca 41 em

		# TODO: ehrm.. something
		contacts = map( lambda x: (x['contact'],'%s (%d)' % (x['contact'],x['count'])), model.getAnzaContacts() )

		contactfilter = self.processInput(II('contact','Contact',II.DROPDOWN,options=contacts,allowBlank=True,blankVal=''))