Remove Jacob Lundqvist's xmpp/debug.py module. We have switched to builtin python logging.
This commit is contained in:
parent
a8cfd83c3e
commit
59b0216898
|
@ -1,394 +0,0 @@
|
|||
## debug.py
|
||||
##
|
||||
## Copyright (C) 2003 Jacob Lundqvist
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU Lesser General Public License as published
|
||||
## by the Free Software Foundation; either version 2, or (at your option)
|
||||
## any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU Lesser General Public License for more details.
|
||||
|
||||
'''
|
||||
Generic debug class
|
||||
|
||||
Other modules can always define extra debug flags for local usage, as long as
|
||||
they make sure they append them to debug_flags
|
||||
|
||||
Also its always a good thing to prefix local flags with something, to reduce risk
|
||||
of coliding flags. Nothing breaks if two flags would be identical, but it might
|
||||
activate unintended debugging.
|
||||
|
||||
flags can be numeric, but that makes analysing harder, on creation its
|
||||
not obvious what is activated, and when flag_show is given, output isnt
|
||||
really meaningfull.
|
||||
|
||||
This Debug class can either be initialized and used on app level, or used independantly
|
||||
by the individual classes.
|
||||
|
||||
For samples of usage, see samples subdir in distro source, and selftest
|
||||
in this code
|
||||
'''
|
||||
|
||||
_version_ = '1.4.0'
|
||||
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import time
|
||||
import os
|
||||
|
||||
if 'TERM' in os.environ:
|
||||
colors_enabled=True
|
||||
else:
|
||||
colors_enabled=False
|
||||
|
||||
color_none = chr(27) + "[0m"
|
||||
color_black = chr(27) + "[30m"
|
||||
color_red = chr(27) + "[31m"
|
||||
color_green = chr(27) + "[32m"
|
||||
color_brown = chr(27) + "[33m"
|
||||
color_blue = chr(27) + "[34m"
|
||||
color_magenta = chr(27) + "[35m"
|
||||
color_cyan = chr(27) + "[36m"
|
||||
color_light_gray = chr(27) + "[37m"
|
||||
color_dark_gray = chr(27) + "[30;1m"
|
||||
color_bright_red = chr(27) + "[31;1m"
|
||||
color_bright_green = chr(27) + "[32;1m"
|
||||
color_yellow = chr(27) + "[33;1m"
|
||||
color_bright_blue = chr(27) + "[34;1m"
|
||||
color_purple = chr(27) + "[35;1m"
|
||||
color_bright_cyan = chr(27) + "[36;1m"
|
||||
color_white = chr(27) + "[37;1m"
|
||||
|
||||
|
||||
# Define your flags in yor modules like this:
|
||||
#
|
||||
# from debug import *
|
||||
#
|
||||
# DBG_INIT = 'init' ; debug_flags.append( DBG_INIT )
|
||||
# DBG_CONNECTION = 'connection' ; debug_flags.append( DBG_CONNECTION )
|
||||
#
|
||||
# The reason for having a double statement wis so we can validate params
|
||||
# and catch all undefined debug flags
|
||||
#
|
||||
# This gives us control over all used flags, and makes it easier to allow
|
||||
# global debugging in your code, just do something like
|
||||
#
|
||||
# foo = Debug( debug_flags )
|
||||
#
|
||||
# group flags, that is a flag in it self containing multiple flags should be
|
||||
# defined without the debug_flags.append() sequence, since the parts are already
|
||||
# in the list, also they must of course be defined after the flags they depend on ;)
|
||||
# example:
|
||||
#
|
||||
# DBG_MULTI = [ DBG_INIT, DBG_CONNECTION ]
|
||||
#
|
||||
#
|
||||
#
|
||||
# NoDebug
|
||||
# -------
|
||||
# To speed code up, typically for product releases or such
|
||||
# use this class instead if you globaly want to disable debugging
|
||||
|
||||
|
||||
class NoDebug:
|
||||
def __init__( self, *args, **kwargs ):
|
||||
pass
|
||||
def show( self, *args, **kwargs):
|
||||
pass
|
||||
def is_active( self, flag ):
|
||||
pass
|
||||
def active_set( self, active_flags = None ):
|
||||
return 0
|
||||
|
||||
|
||||
LINE_FEED = '\n'
|
||||
|
||||
|
||||
class Debug:
|
||||
def __init__( self,
|
||||
#
|
||||
# active_flags are those that will trigger output
|
||||
#
|
||||
active_flags = None,
|
||||
#
|
||||
# Log file should be file object or file namne
|
||||
#
|
||||
log_file = sys.stderr,
|
||||
#
|
||||
# prefix and sufix can either be set globaly or per call.
|
||||
# personally I use this to color code debug statements
|
||||
# with prefix = chr(27) + '[34m'
|
||||
# sufix = chr(27) + '[37;1m\n'
|
||||
#
|
||||
prefix = 'DEBUG: ',
|
||||
sufix = '\n',
|
||||
#
|
||||
# If you want unix style timestamps,
|
||||
# 0 disables timestamps
|
||||
# 1 before prefix, good when prefix is a string
|
||||
# 2 after prefix, good when prefix is a color
|
||||
#
|
||||
time_stamp = 0,
|
||||
#
|
||||
# flag_show should normaly be of, but can be turned on to get a
|
||||
# good view of what flags are actually used for calls,
|
||||
# if it is not None, it should be a string
|
||||
# flags for current call will be displayed
|
||||
# with flag_show as separator
|
||||
# recomended values vould be '-' or ':', but any string goes
|
||||
#
|
||||
flag_show = None,
|
||||
#
|
||||
# If you dont want to validate flags on each call to
|
||||
# show(), set this to 0
|
||||
#
|
||||
validate_flags = 0,
|
||||
#
|
||||
# If you dont want the welcome message, set to 0
|
||||
# default is to show welcome if any flags are active
|
||||
welcome = -1
|
||||
):
|
||||
|
||||
self.debug_flags = []
|
||||
if welcome == -1:
|
||||
if active_flags and len(active_flags):
|
||||
welcome = 1
|
||||
else:
|
||||
welcome = 0
|
||||
|
||||
self._remove_dupe_flags()
|
||||
if log_file:
|
||||
if isinstance(log_file, str):
|
||||
try:
|
||||
self._fh = open(log_file,'w')
|
||||
except Exception:
|
||||
print 'ERROR: can open %s for writing'
|
||||
sys.exit(0)
|
||||
else: ## assume its a stream type object
|
||||
self._fh = log_file
|
||||
else:
|
||||
self._fh = sys.stdout
|
||||
|
||||
if time_stamp not in (0,1,2):
|
||||
raise Exception('Invalid time_stamp param "%s"' % str(time_stamp))
|
||||
self.prefix = prefix
|
||||
self.sufix = sufix
|
||||
self.time_stamp = time_stamp
|
||||
self.flag_show = None # must be initialised after possible welcome
|
||||
self.validate_flags = validate_flags
|
||||
|
||||
self.active_set( active_flags )
|
||||
if welcome:
|
||||
self.show('')
|
||||
caller = sys._getframe(1) # used to get name of caller
|
||||
try:
|
||||
mod_name= ":%s" % caller.f_locals['__name__']
|
||||
except Exception:
|
||||
mod_name = ""
|
||||
self.show('Debug created for %s%s' % (caller.f_code.co_filename,
|
||||
mod_name ))
|
||||
self.show(' flags defined: %s' % ','.join( self.active ))
|
||||
|
||||
if type(flag_show) in (str, type(None)):
|
||||
self.flag_show = flag_show
|
||||
else:
|
||||
raise Exception('Invalid type "%s" for flag_show!' % \
|
||||
type(flag_show))
|
||||
|
||||
def show( self, msg, flag = None, prefix = None, sufix = None,
|
||||
lf = 0 ):
|
||||
'''
|
||||
flag can be of folowing types:
|
||||
None - this msg will always be shown if any debugging is on
|
||||
flag - will be shown if flag is active
|
||||
(flag1,flag2,,,) - will be shown if any of the given flags
|
||||
are active
|
||||
|
||||
if prefix / sufix are not given, default ones from init will be used
|
||||
|
||||
lf = -1 means strip linefeed if pressent
|
||||
lf = 1 means add linefeed if not pressent
|
||||
'''
|
||||
|
||||
if self.validate_flags:
|
||||
self._validate_flag( flag )
|
||||
|
||||
if not self.is_active(flag):
|
||||
return
|
||||
if prefix:
|
||||
pre = prefix
|
||||
else:
|
||||
pre = self.prefix
|
||||
if sufix:
|
||||
suf = sufix
|
||||
else:
|
||||
suf = self.sufix
|
||||
|
||||
if self.time_stamp == 2:
|
||||
output = '%s%s ' % ( pre,
|
||||
time.strftime('%b %d %H:%M:%S',
|
||||
time.localtime(time.time() )),
|
||||
)
|
||||
elif self.time_stamp == 1:
|
||||
output = '%s %s' % ( time.strftime('%b %d %H:%M:%S',
|
||||
time.localtime(time.time() )),
|
||||
pre,
|
||||
)
|
||||
else:
|
||||
output = pre
|
||||
|
||||
if self.flag_show:
|
||||
if flag:
|
||||
output = '%s%s%s' % ( output, flag, self.flag_show )
|
||||
else:
|
||||
# this call uses the global default,
|
||||
# dont print "None", just show the separator
|
||||
output = '%s %s' % ( output, self.flag_show )
|
||||
|
||||
output = '%s%s%s' % ( output, msg, suf )
|
||||
if lf:
|
||||
# strip/add lf if needed
|
||||
last_char = output[-1]
|
||||
if lf == 1 and last_char != LINE_FEED:
|
||||
output = output + LINE_FEED
|
||||
elif lf == -1 and last_char == LINE_FEED:
|
||||
output = output[:-1]
|
||||
try:
|
||||
self._fh.write( output )
|
||||
except Exception:
|
||||
# unicode strikes again ;)
|
||||
s=u''
|
||||
for i in range(len(output)):
|
||||
if ord(output[i]) < 128:
|
||||
c = output[i]
|
||||
else:
|
||||
c = '?'
|
||||
s=s+c
|
||||
self._fh.write( '%s%s%s' % ( pre, s, suf ))
|
||||
self._fh.flush()
|
||||
|
||||
def active_set( self, active_flags = None ):
|
||||
"returns 1 if any flags where actually set, otherwise 0."
|
||||
r = 0
|
||||
ok_flags = []
|
||||
if not active_flags:
|
||||
#no debuging at all
|
||||
self.active = []
|
||||
elif isinstance(active_flags, (tuple, list)):
|
||||
flags = self._as_one_list( active_flags )
|
||||
for t in flags:
|
||||
if t not in self.debug_flags:
|
||||
print 'Invalid debugflag given', t
|
||||
ok_flags.append( t )
|
||||
|
||||
self.active = ok_flags
|
||||
r = 1
|
||||
else:
|
||||
# assume comma string
|
||||
try:
|
||||
flags = active_flags.split(',')
|
||||
except Exception:
|
||||
self.show( '***' )
|
||||
self.show( '*** Invalid debug param given: %s' % active_flags )
|
||||
self.show( '*** please correct your param!' )
|
||||
self.show( '*** due to this, full debuging is enabled' )
|
||||
self.active = self.debug_flags
|
||||
|
||||
for f in flags:
|
||||
s = f.strip()
|
||||
ok_flags.append( s )
|
||||
self.active = ok_flags
|
||||
|
||||
self._remove_dupe_flags()
|
||||
return r
|
||||
|
||||
def active_get( self ):
|
||||
"returns currently active flags."
|
||||
return self.active
|
||||
|
||||
|
||||
def _as_one_list( self, items ):
|
||||
''' init param might contain nested lists, typically from group flags.
|
||||
|
||||
This code organises lst and remves dupes
|
||||
'''
|
||||
if not isinstance(items, (list, tuple)):
|
||||
return [ items ]
|
||||
r = []
|
||||
for l in items:
|
||||
if isinstance(l, list):
|
||||
lst2 = self._as_one_list( l )
|
||||
for l2 in lst2:
|
||||
self._append_unique_str(r, l2 )
|
||||
elif l is None:
|
||||
continue
|
||||
else:
|
||||
self._append_unique_str(r, l )
|
||||
return r
|
||||
|
||||
|
||||
def _append_unique_str( self, lst, item ):
|
||||
'''filter out any dupes.'''
|
||||
if not isinstance(item, str):
|
||||
msg2 = '%s' % item
|
||||
raise Exception('Invalid item type "%s", should be string' % \
|
||||
type(item))
|
||||
if item not in lst:
|
||||
lst.append( item )
|
||||
return lst
|
||||
|
||||
|
||||
def _validate_flag( self, flags ):
|
||||
'verify that flag is defined.'
|
||||
if flags:
|
||||
for f in self._as_one_list( flags ):
|
||||
if not f in self.debug_flags:
|
||||
msg2 = '%s' % f
|
||||
raise Exception('Invalid debugflag "%s" given' % f)
|
||||
|
||||
def _remove_dupe_flags( self ):
|
||||
'''
|
||||
if multiple instances of Debug is used in same app,
|
||||
some flags might be created multiple time, filter out dupes
|
||||
'''
|
||||
unique_flags = []
|
||||
for f in self.debug_flags:
|
||||
if f not in unique_flags:
|
||||
unique_flags.append(f)
|
||||
self.debug_flags = unique_flags
|
||||
|
||||
colors={}
|
||||
def Show(self, flag, msg, prefix=''):
|
||||
msg=str(msg)
|
||||
msg=msg.replace('\r','\\r').replace('\n','\\n').replace('><','>\n <')
|
||||
if not colors_enabled: pass
|
||||
elif prefix in self.colors: msg=self.colors[prefix]+msg+color_none
|
||||
else: msg=color_none+msg
|
||||
if not colors_enabled: prefixcolor=''
|
||||
elif flag in self.colors: prefixcolor=self.colors[flag]
|
||||
else: prefixcolor=color_none
|
||||
|
||||
if prefix=='error':
|
||||
_exception = sys.exc_info()
|
||||
if _exception[0]:
|
||||
msg=msg+'\n'+''.join(traceback.format_exception(_exception[0], _exception[1], _exception[2])).rstrip()
|
||||
|
||||
prefix= self.prefix+prefixcolor+(flag+' '*12)[:12]+' '+(prefix+' '*6)[:6]
|
||||
self.show(msg, flag, prefix)
|
||||
|
||||
def is_active( self, flag ):
|
||||
if not self.active: return 0
|
||||
if not flag or ((flag in self.active) ^ (DBG_ALWAYS in self.active)) : return 1
|
||||
return 0
|
||||
|
||||
DBG_ALWAYS='always'
|
||||
|
||||
##Uncomment this to effectively disable all debugging and all debugging overhead.
|
||||
#Debug=NoDebug
|
||||
|
||||
# vim: se ts=3:
|
Loading…
Reference in New Issue