1
0
Fork 0

- add logging to the test class

git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/gnuviech.info/gnuviechadmin/trunk@86 a67ec6bc-e5d5-0310-a910-815c51eb3124
This commit is contained in:
Jan Dittberner 2004-12-26 15:50:53 +00:00
parent dc0da570ab
commit b9ec217d1e
6 changed files with 681 additions and 51 deletions

View File

@ -4,6 +4,7 @@
"""
import os
from log4py import Logger, FileAppender, LOGLEVEL_DEBUG
class GNVPrefs:
"""This class has static variables for the settings of the GNUViech
@ -28,40 +29,53 @@ class GNVPrefs:
WEBHOMEDIR = HOMEDIR+"/www/"
WEBLOGDIR = WEBHOMEDIR+"logs/"
WEBSTATSDIR = WEBHOMEDIR+"stats/"
LOGDIR = BASEPREFIX+"/var/log"
LOGFILE = LOGDIR+"/gnvadm.log"
# load custom settings
execfile("gvadm.preferences")
def __init__(self):
self.setupDirs()
def __repr__(self):
items = dir(self)
items.sort()
return "gnuviech.GNVPrefs\n\t" + "\n\t".join(["%s = %s" %
(item, getattr(self, item)) for item in items if getattr(self, item).__class__ in (str, int, list, dict)]) + "\n"
def setupDirs(self):
"""Setup the directories and files required for proper operation of the
GNUViech administration tool."""
for directory in (self.BASEPREFIX,
self.BASEPREFIX+"/etc",
self.BASEPREFIX+"/var",
self.GVADMDIR,
self.EXIMCONFDIR,
self.VIRTUALDOMDIR,
self.HOMEDIR,
self.POPHOMEDIR,
self.WEBHOMEDIR,
self.WEBLOGDIR,
self.WEBSTATSDIR,
self.LOGDIR):
if (not os.access(directory, os.R_OK & os.X_OK)):
print "making %s." % directory
os.mkdir(directory)
for required in (self.BASEPREFIX+"/etc/passwd",
self.BASEPREFIX+"/etc/shadow",
self.EXIMCONFDIR+"eximpasswords"):
if (not os.access(required, os.R_OK)):
print "creating %s." % required
file = open(required, "w")
file.close()
def getLogger(self, instance):
logger = Logger().get_instance(instance)
logger.remove_all_targets()
logger.add_target(FileAppender(self.LOGFILE))
logger.set_loglevel(LOGLEVEL_DEBUG)
return logger
class NoAdmDirError(Exception):
"""This exception is raised if the admin directory does'nt exist."""
pass
def setupDirs():
"""Setup the directories and files required for proper operation of the
GNUViech administration tool."""
for directory in (GNVPrefs.BASEPREFIX,
GNVPrefs.BASEPREFIX+"/etc",
GNVPrefs.GVADMDIR,
GNVPrefs.EXIMCONFDIR,
GNVPrefs.VIRTUALDOMDIR,
GNVPrefs.HOMEDIR,
GNVPrefs.POPHOMEDIR,
GNVPrefs.WEBHOMEDIR,
GNVPrefs.WEBLOGDIR,
GNVPrefs.WEBSTATSDIR):
if (not os.access(directory, os.R_OK & os.X_OK)):
print "making %s." % directory
os.mkdir(directory)
for required in (GNVPrefs.BASEPREFIX+"/etc/passwd",
GNVPrefs.BASEPREFIX+"/etc/shadow",
GNVPrefs.EXIMCONFDIR+"eximpasswords"):
if (not os.access(required, os.R_OK)):
print "creating %s." % required
file = open(required, "w")
file.close()

View File

@ -3,18 +3,18 @@
(c) 2004 Jan Dittberner <jan@gnuviech.info>
"""
from random import Random
import random, re
from gnuviech import GNVPrefs
def generatePassword():
r = Random()
devrnd = open("/dev/random", "r")
r.seed(ord(devrnd.read(1)))
devrnd.close()
return "".join([chr(char) for char in
r.sample(GNVPrefs.PWDCHARS,
r.randint(GNVPrefs.PWDMINLENGTH,
GNVPrefs.PWDMAXLENGTH))])
random.sample(GNVPrefs.PWDCHARS,
random.randint(GNVPrefs.PWDMINLENGTH,
GNVPrefs.PWDMAXLENGTH))])
# regex für email check
# p = re.compile(u"^([a-zA-Z0-9_\-.]+)@([a-zA-Z0-9\-]+(\.|[a-zA-Z0-9\-]+)*\.[a-z]{2,5})$")
def checkEmail(email):
"""Returns a match object if the given email address is syntactically
correct otherwise it returns None"""
# regex for email check
p = re.compile(r'^([a-zA-Z0-9_\-.]+)@([a-zA-Z0-9\-]+(\.|[a-zA-Z0-9\-]+)*\.[a-z]{2,5})$')
return p.search(email)

View File

@ -8,3 +8,5 @@ POPHOMEDIR = HOMEDIR+"/mail/"
WEBHOMEDIR = HOMEDIR+"/www/"
WEBLOGDIR = WEBHOMEDIR+"logs/"
WEBSTATSDIR = WEBHOMEDIR+"stats/"
LOGDIR = BASEPREFIX+"/var/log"
LOGFILE = LOGDIR+"/gnvadm.log"

6
backend/log4py.conf Normal file
View File

@ -0,0 +1,6 @@
[Default]
Ansi: false
LogLevel: Normal
[Test]
LogLevel: Debug

593
backend/log4py.py Normal file
View File

@ -0,0 +1,593 @@
"""
Python logging module - Version 1.3
Loglevels:
LOGLEVEL_NONE, LOGLEVEL_ERROR, LOGLEVEL_NORMAL, LOGLEVEL_VERBOSE, LOGLEVEL_DEBUG
Format-Parameters:
%C -- The name of the current class.
%D -- Program duration since program start.
%d -- Program duration for the last step (last output).
%F -- The name of the current function.
%f -- Current filename
%L -- Log type (Error, Warning, Debug or Info)
%M -- The actual message.
%N -- The current line number.
%T -- Current time (human readable).
%t -- Current time (machine readable)
%U -- Current fully qualified module/file.
%u -- Current module/file.
%x -- NDC (nested diagnostic contexts).
Pre-defined Formats:
FMT_SHORT -- %M
FMT_MEDIUM -- [ %C.%F ] %D: %M
FMT_LONG -- %T %L %C [%F] %x%M
FMT_DEBUG -- %T [%D (%d)] %L %C [%F (%N)] %x%M
"""
# Logging levels
LOGLEVEL_NONE = 1 << 0
LOGLEVEL_ERROR = 1 << 1
LOGLEVEL_NORMAL = 1 << 2
LOGLEVEL_VERBOSE = 1 << 3
LOGLEVEL_DEBUG = 1 << 4
# Pre-defined format strings
FMT_SHORT = "%M"
FMT_MEDIUM = "[ %C.%F ] %D: %M"
FMT_LONG = "%T %L %C [%F] %x%M"
FMT_DEBUG = "%T [%D (%d)] %L %C [%F (%N)] %x%M"
# Special logging targets
TARGET_MYSQL = "MySQL"
TARGET_POSTGRES = "Postgres"
TARGET_SYSLOG = "Syslog"
TARGET_SYS_STDOUT = "sys.stdout"
TARGET_SYS_STDERR = "sys.stderr"
TARGET_SYS_STDOUT_ALIAS = "stdout"
TARGET_SYS_STDERR_ALIAS = "stderr"
SPECIAL_TARGETS = [ TARGET_MYSQL, TARGET_POSTGRES, TARGET_SYSLOG, TARGET_SYS_STDOUT, TARGET_SYS_STDERR, TARGET_SYS_STDOUT_ALIAS, TARGET_SYS_STDERR_ALIAS ]
# Configuration files
CONFIGURATION_FILES = {}
CONFIGURATION_FILES[1] = "log4py.conf" # local directory
CONFIGURATION_FILES[2] = "$HOME/.log4py.conf" # hidden file in the home directory
CONFIGURATION_FILES[3] = "/etc/log4py.conf" # system wide file
# Constants for the FileAppender
ROTATE_NONE = 0
ROTATE_DAILY = 1
ROTATE_WEEKLY = 2
ROTATE_MONTHLY = 3
# The following constants are of internal interest only
# Message constants (used for ansi colors and for logtype %L)
MSG_DEBUG = 1 << 0
MSG_WARN = 1 << 1
MSG_ERROR = 1 << 2
MSG_INFO = 1 << 3
# Boolean constants
TRUE = "TRUE"
FALSE = "FALSE"
# Color constants
BLACK = 30
RED = 31
GREEN = 32
YELLOW = 33
BLUE = 34
PURPLE = 35
AQUA = 36
WHITE = 37
LOG_MSG = { MSG_DEBUG: "DEBUG", MSG_WARN: "WARNING", MSG_ERROR: "ERROR", MSG_INFO: "INFO"}
LOG_COLORS = { MSG_DEBUG: [WHITE, BLACK, FALSE], MSG_WARN: [WHITE, BLACK, FALSE], MSG_ERROR: [WHITE, BLACK, TRUE], MSG_INFO: [WHITE, BLACK, FALSE]}
LOG_LEVELS = { "DEBUG": LOGLEVEL_DEBUG, "VERBOSE": LOGLEVEL_VERBOSE, "NORMAL": LOGLEVEL_NORMAL, "NONE": LOGLEVEL_NONE, "ERROR": LOGLEVEL_ERROR }
SECTION_DEFAULT = "Default"
from time import time, strftime, localtime
from types import StringType, ClassType, InstanceType, FileType, TupleType
from string import zfill, atoi, lower, upper, join, replace, split, strip
from re import sub
from ConfigParser import ConfigParser, NoOptionError
from os import stat, rename
import sys
import traceback
import os
import copy
import socket
import locale
if (os.name == "posix"):
import syslog
try:
import MySQLdb
mysql_available = TRUE
except:
mysql_available = FALSE
def get_homedirectory():
if (sys.platform == "win32"):
if (os.environ.has_key("USERPROFILE")):
return os.environ["USERPROFILE"]
else:
return "C:\\"
else:
if (os.environ.has_key("HOME")):
return os.environ["HOME"]
else:
# No home directory set
return ""
# This is the main class for the logging module
class Logger:
cache = {}
instance = None
configfiles = []
hostname = socket.gethostname()
def __init__(self, useconfigfiles = TRUE, customconfigfiles = None):
""" **(private)** Class initalization & customization. """
if (customconfigfiles):
if (type(customconfigfiles) == StringType):
customconfigfiles = [customconfigfiles]
Logger.configfiles = customconfigfiles
if (not Logger.instance):
self.__Logger_setdefaults()
if (useconfigfiles == TRUE):
self.__Logger_appendconfigfiles(Logger.configfiles)
# read the default options
self.__Logger_parse_options()
self.__Logger_timeinit = time()
self.__Logger_timelaststep = self.__Logger_timeinit
Logger.instance = self
if (useconfigfiles == TRUE):
# read and pre-cache settings for named classids
self.__Logger_cache_options()
def get_root(self):
""" Provides a way to change the base logger object's properties. """
return Logger.instance
def get_instance(self, classid = "Main", use_cache = TRUE):
""" Either get the cached logger instance or create a new one
Note that this is safe, even if you have your target set to sys.stdout
or sys.stderr
"""
cache = Logger.cache
if (type(classid) == ClassType):
classid = classid.__name__
elif (type(classid) == InstanceType):
classid = classid.__class__.__name__
# classid has to be lowercase, because the ConfigParser returns sections lowercase
classid = lower(classid)
if ((cache.has_key(classid)) and (use_cache == TRUE)):
cat = Logger.cache[classid]
else:
instance = Logger.instance
# test for targets which won't deep copy
targets = instance.__Logger_targets
deepcopyable = TRUE
for i in range(len(targets)):
if (type(targets[i]) == FileType):
deepcopyable = FALSE
if (deepcopyable == FALSE):
# swap the non-copyable target out for a moment
del instance.__Logger_targets
cat = copy.deepcopy(instance)
instance.__Logger_targets = targets
cat.__Logger_targets = targets
else:
cat = copy.deepcopy(instance)
cat.__Logger_classname = classid
# new categories have their own private Nested Diagnostic Contexts
self.__Logger_ndc = []
self.__Logger_classid = classid
cat.debug("Class %s instantiated" % classid)
if (use_cache == TRUE):
cache[classid] = cat
return cat
# Log-target handling (add, remove, set, remove_all)
def add_target(self, target, *args):
""" Add a target to the logger targets. """
if (not target in self.__Logger_targets):
if (target == TARGET_MYSQL):
if (mysql_available == TRUE):
# Required parameters: dbhost, dbname, dbuser, dbpass, dbtable
try:
self.__Logger_mysql_connection = MySQLdb.connect(host=args[0], db=args[1], user=args[2], passwd=args[3])
self.__Logger_mysql_cursor = self.__Logger_mysql_connection.cursor()
self.__Logger_mysql_tablename = args[4]
self.__Logger_targets.append(target)
except MySQLdb.OperationalError, detail:
self.error("MySQL connection failed: %s" % detail)
else:
self.error("MySQL target not added - Python-mysql not available")
else:
if (type(target) == StringType):
if (target not in SPECIAL_TARGETS):
# This is a filename
target = FileAppender(target, self.__Logger_rotation)
if ((target == TARGET_SYSLOG) and (os.name != "posix")):
self.warn("TARGET_SYSLOG is not available on non-posix platforms!")
else:
self.__Logger_targets.append(target)
def remove_target(self, target):
""" Remove a target from the logger targets. """
if (target in self.__Logger_targets):
if (target == TARGET_MYSQL):
self.__Logger_mysql_connection.close()
self.__Logger_targets.remove(target)
def set_target(self, target):
""" Set a single target. """
if (type(target) == StringType):
if (target not in SPECIAL_TARGETS):
# File target
target = FileAppender(target, self.__Logger_rotation)
self.__Logger_targets = [ target ]
def remove_all_targets(self):
""" Remove all targets from the logger targets. """
self.__Logger_targets=[]
def get_targets(self):
""" Returns all defined targets. """
return self.__Logger_targets
# Methods to set properties
def set_loglevel(self, loglevel):
""" Set the loglevel for the current instance. """
self.__Logger_loglevel = loglevel
def set_formatstring(self, formatstring):
""" Set a format string. """
self.__Logger_formatstring = formatstring
def set_use_ansi_codes(self, useansicodes):
""" Use ansi codes for output to the console (TRUE or FALSE). """
self.__Logger_useansicodes = useansicodes
def set_time_format(self, timeformat):
""" Set the time format (default: loaded from the system locale). """
self.__Logger_timeformat = timeformat
def set_rotation(self, rotation):
""" Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY """
self.__Logger_rotation = rotation
for i in range(len(self.__Logger_targets)):
target = self.__Logger_targets[i]
if (isinstance(target, FileAppender)):
target.set_rotation(rotation)
# Method to get properties
def get_loglevel(self):
""" Returns the current loglevel. """
return self.__Logger_loglevel
def get_formatstring(self):
""" Returns the current format string. """
return self.__Logger_formatstring
def get_use_ansi_codes(self):
""" Returns, wether ansi codes are being used or not. """
return self.__Logger_useansicodes
def get_time_format(self):
""" Returns the current time format. """
return self.__Logger_timeformat
def get_rotation(self):
""" Returns the current rotation setting. """
return self.__Logger_rotation
# Methods to push and pop trace messages for nested contexts
def push(self, message):
""" Add a trace message. """
self.__Logger_ndc.append(message)
def pop(self):
""" Remove the topmost trace message. """
ct = len(self.__Logger_ndc)
if (ct):
del(self.__Logger_ndc[ct-1])
def clear_ndc(self):
""" Clears all NDC messages. """
self.__Logger_ndc = []
# Methods to actually print messages
def debug(self, *messages):
""" Write a debug message. """
if (self.__Logger_loglevel >= LOGLEVEL_DEBUG):
message = self.__Logger_collate_messages(messages)
self.__Logger_showmessage(message, MSG_DEBUG)
def warn(self, *messages):
""" Write a warning message. """
if (self.__Logger_loglevel >= LOGLEVEL_VERBOSE):
message = self.__Logger_collate_messages(messages)
self.__Logger_showmessage(message, MSG_WARN)
def error(self, *messages):
""" Write a error message. """
if (self.__Logger_loglevel >= LOGLEVEL_ERROR):
message = self.__Logger_collate_messages(messages)
self.__Logger_showmessage(message, MSG_ERROR)
def info(self, *messages):
""" Write a info message. """
if (self.__Logger_loglevel >= LOGLEVEL_NORMAL):
message = self.__Logger_collate_messages(messages)
self.__Logger_showmessage(message, MSG_INFO)
# Private methods of the Logger class - you never have to use those directly
def __Logger_collate_messages(self, messages):
""" **(private)** Create a single string from a number of messages. """
return strip(reduce(lambda x, y: "%s%s" % (x, y), messages))
def __Logger_tracestack(self):
""" **(private)** Analyze traceback stack and set linenumber and functionname. """
stack = traceback.extract_stack()
self.__Logger_module = stack[-4][0]
self.__Logger_linenumber = stack[-4][1]
self.__Logger_functionname = stack[-4][2]
self.__Logger_filename = stack[-4][0]
if (self.__Logger_functionname == "?"):
self.__Logger_functionname = "Main"
def __Logger_setdefaults(self):
""" **(private)** Set default values for internal variables. """
locale.setlocale(locale.LC_ALL)
self.__Logger_classid = None
self.__Logger_targets = [ TARGET_SYS_STDOUT ] # default target = sys.stdout
self.__Logger_formatstring = FMT_LONG
self.__Logger_loglevel = LOGLEVEL_NORMAL
self.__Logger_rotation = ROTATE_NONE
self.__Logger_useansicodes = FALSE
self.__Logger_functionname = ""
self.__Logger_filename = ""
self.__Logger_linenumber = -1
try:
self.__Logger_timeformat = "%s %s" % (locale.nl_langinfo(locale.D_FMT), locale.nl_langinfo(locale.T_FMT))
except (AttributeError):
self.__Logger_timeformat = "%d.%m.%Y %H:%M:%S"
self.__Logger_classname = None
self.__Logger_configfilename = ""
self.__Logger_module = ""
self.__Logger_ndc = [] # ndc = Nested Diagnostic Context
def __Logger_find_config(self):
""" **(private)** Search for configuration files. """
if (not self.__Logger_configfilename):
priorities = CONFIGURATION_FILES.keys()
priorities.sort()
configfilename = ""
for i in range(len(priorities)):
filename = CONFIGURATION_FILES[priorities[i]]
home_directory = get_homedirectory()
if (os.sep == "\\"):
home_directory = replace(home_directory, "\\", "\\\\")
filename = sub("\$HOME", home_directory, filename)
if (os.path.exists(filename)):
configfilename = filename
break
self.__Logger_configfilename = configfilename
return self.__Logger_configfilename
def __Logger_parse_options(self, section = SECTION_DEFAULT):
""" **(private)** Parse main options from config file. """
configfilename = self.__Logger_find_config()
if (configfilename != ""):
parser = ConfigParser()
parser.read(configfilename)
self.__Logger_set_instance_options(parser, section, self)
return TRUE
def __Logger_set_instance_options(self, parser, section, instance):
""" **(private)** Set the options for a given instance from the parser section """
for i in range(len(parser.options(section))):
option = lower(parser.options(section)[i])
value = parser.get(section, option)
if (option == "format"):
instance.set_formatstring(value)
elif (option == "timeformat"):
instance.set_time_format(value)
elif (option == "ansi"):
instance.set_use_ansi_codes(upper(value))
elif (option == "loglevel"):
instance.set_loglevel(LOG_LEVELS[upper(value)])
elif (option == "target"):
splitted = split(value, ",")
instance.remove_all_targets()
for i in range(len(splitted)):
instance.add_target(strip(splitted[i]))
def __Logger_cache_options(self):
""" **(private)** Read and cache debug levels for categories from config file. """
configfilename = self.__Logger_find_config()
if (configfilename != ""):
parser = ConfigParser()
parser.read(configfilename)
for i in range(len(parser.sections())):
section = parser.sections()[i]
if (section != SECTION_DEFAULT):
instance = self.get_instance(section)
self.__Logger_set_instance_options(parser, section, instance)
return TRUE
def __Logger_appendconfigfiles(self, filenames):
""" **(private)** Append a filename to the list of configuration files. """
filenames.reverse()
for i in range(len(filenames)):
keys = CONFIGURATION_FILES.keys()
CONFIGURATION_FILES[min(keys) - 1] = filenames[i]
def __Logger_get_ndc(self):
""" **(private)** Returns the NDC (nested diagnostic context) joined with single-spaces. """
if (len(self.__Logger_ndc)):
return join(self.__Logger_ndc)
else:
return ""
def __Logger_showmessage(self, message, messagesource):
""" **(private)** Writes a message to all targets set. """
if (isinstance(message, Exception)):
(exc_type, exc_value, tb) = sys.exc_info()
exception_summary = traceback.format_exception(exc_type, exc_value, tb)
message = 'Exception caught:\n'
for line in exception_summary:
message = "%s%s" % (message, line)
currenttime = time()
self.__Logger_tracestack()
timedifference = "%.3f" % (currenttime - self.__Logger_timeinit)
timedifflaststep = "%.3f" % (currenttime - self.__Logger_timelaststep)
self.__Logger_timelaststep = currenttime
milliseconds = int(round((currenttime - long(currenttime)) * 1000))
timeformat = sub("%S", "%S." + (zfill(milliseconds, 3)), self.__Logger_timeformat)
currentformattedtime = strftime(timeformat, localtime(currenttime))
line = self.__Logger_formatstring
line = sub("%C", str(self.__Logger_classname), line)
line = sub("%D", timedifference, line)
line = sub("%d", timedifflaststep, line)
line = sub("%F", self.__Logger_functionname, line)
line = sub("%f", self.__Logger_filename, line)
line = sub("%U", self.__Logger_module, line)
line = sub("%u", os.path.split(self.__Logger_module)[-1], line)
ndc = self.__Logger_get_ndc()
if (ndc != ""):
line = sub("%x", "%s - " % ndc, line)
else:
line = sub("%x", "", line)
message = replace(message, "\\", "\\\\")
if (self.__Logger_useansicodes == TRUE):
line = sub("%L", self.__Logger_ansi(LOG_MSG[messagesource], messagesource), line)
line = sub("%M", self.__Logger_ansi(message, messagesource), line)
else:
line = sub("%L", LOG_MSG[messagesource], line)
line = sub("%M", message, line)
line = sub("%N", str(self.__Logger_linenumber), line)
line = sub("%T", currentformattedtime, line)
line = sub("%t", `currenttime`, line)
for i in range(len(self.__Logger_targets)):
target = self.__Logger_targets[i]
if (target == TARGET_MYSQL):
sqltime = strftime("'%Y-%m-%d', '%H:%M:%S'", localtime(currenttime))
sqlStatement = "INSERT INTO %s (host, facility, level, date, time, program, msg) VALUES ('%s', '%s', '%s', %s, '%s', '%s')" % (self.__Logger_mysql_tablename, self.hostname, self.__Logger_functionname, LOG_MSG[messagesource], sqltime, str(self.__Logger_classname), sub("'", "`", message + " " + ndc))
self.__Logger_mysql_cursor.execute(sqlStatement)
elif (target == TARGET_SYSLOG):
# We don't need time and stuff here
syslog.syslog(message)
elif (isinstance(target, FileAppender)):
target.writeline(line)
elif (target == sys.stdout) or (lower(target) == TARGET_SYS_STDOUT) or (lower(target) == TARGET_SYS_STDOUT_ALIAS):
sys.stdout.write("%s\n" % line)
elif (target == sys.stderr) or (lower(target) == TARGET_SYS_STDERR) or (lower(target) == TARGET_SYS_STDERR_ALIAS):
sys.stderr.write("%s\n" % line)
else:
target.write("%s\n" % line)
def __Logger_ansi(self, text, messagesource):
""" **(private)** Converts plain text to ansi text. """
bold = LOG_COLORS[messagesource][2]
fg = str(LOG_COLORS[messagesource][0])
bg = LOG_COLORS[messagesource][1]
if (bold == TRUE):
fg = "%s;1" % fg
bg = bg + 10
text = "\033[%d;%sm%s\033[0m" % (bg, fg, text)
return text
class FileAppender:
def __init__(self, filename, rotation = ROTATE_NONE):
""" **(private)** Class initalization & customization. """
self.__FileAppender_filename = sub("\$HOME", get_homedirectory(), filename)
self.__FileAppender_filename = os.path.expanduser(self.__FileAppender_filename)
self.__FileAppender_filename = os.path.expandvars(self.__FileAppender_filename)
self.__FileAppender_rotation = rotation
def __FileAppender_rotate(self, modification_time):
""" **(private)** Check, wether the file has to be rotated yet or not. """
if (self.__FileAppender_rotation == ROTATE_DAILY):
strftime_mask = "%Y%j"
elif (self.__FileAppender_rotation == ROTATE_WEEKLY):
strftime_mask = "%Y%W"
elif (self.__FileAppender_rotation == ROTATE_MONTHLY):
strftime_mask = "%Y%m"
return (strftime(strftime_mask, localtime(time())) != strftime(strftime_mask, localtime(modification_time)))
def __FileAppender_date_string(self, modification_time):
""" **(private)** Returns a new filename for the rotated file with the appropriate time included. """
if (self.__FileAppender_rotation == ROTATE_DAILY):
return strftime("%Y-%m-%d", localtime(modification_time))
elif (self.__FileAppender_rotation == ROTATE_WEEKLY):
return strftime("%Y-Week %W", localtime(modification_time))
elif (self.__FileAppender_rotation == ROTATE_MONTHLY):
return strftime("%Y-Month %m", localtime(modification_time))
def get_rotation(self):
""" Returns the current rotation setting. """
return self.__FileAppender_rotation
def set_rotation(self, rotation):
""" Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY """
self.__FileAppender_rotation = rotation
def write(self, text):
""" Write some text to the file appender. """
if ((os.path.exists(self.__FileAppender_filename)) and (self.__FileAppender_rotation != ROTATE_NONE)):
statinfo = stat(self.__FileAppender_filename)
if (self.__FileAppender_rotate(statinfo[8])):
splitted = os.path.splitext(self.__FileAppender_filename)
target_file = "%s-%s%s" % (splitted[0], self.__FileAppender_date_string(statinfo[8]), splitted[1])
rename(self.__FileAppender_filename, target_file)
file = open(self.__FileAppender_filename, "a")
file.write(text)
file.close()
def writeline(self, text):
""" Write some text including newline to the file appender. """
self.write("%s\n" % text)

View File

@ -1,20 +1,35 @@
import gnuviech
import gnuviech, sys
import gnuviech.tools
if __name__ == "__main__":
print gnuviech.GNVPrefs()
minlen = 0
avglen = 0
maxlen = 0
pwds = 20
for i in range(pwds):
pwd = gnuviech.tools.generatePassword()
print "%02d: %s (%d)" % (i, pwd, len(pwd))
if (minlen == 0) or (len(pwd) < minlen): minlen = len(pwd)
if (len(pwd) > maxlen): maxlen = len(pwd)
avglen += len(pwd)
avglen = avglen/pwds
print """average password length: %d
class Test:
def __init__(self, prefs):
self.logger = prefs.getLogger(self)
self.prefs = prefs
def doTest(self):
self.logger.debug(str(prefs))
minlen = 0
avglen = 0
maxlen = 0
pwds = 20
for i in range(pwds):
pwd = gnuviech.tools.generatePassword()
self.logger.debug("%02d: %s (%d)" % (i, pwd, len(pwd)))
if (minlen == 0) or (len(pwd) < minlen): minlen = len(pwd)
if (len(pwd) > maxlen): maxlen = len(pwd)
avglen += len(pwd)
avglen = avglen/pwds
self.logger.debug("""average password length: %d
minimum password length: %d
maximum password length: %d""" % (avglen, minlen, maxlen)
maximum password length: %d""" % (avglen, minlen, maxlen))
for address in ('jan@dittberner.info', 'jan', 'jan@gnuelf#test.de',
'd.arnstadt@gmx.net'):
if gnuviech.tools.checkEmail(address):
self.logger.debug("%s is a valid email address." % address)
else:
self.logger.debug("%s is an invalid email address." % address)
if __name__ == "__main__":
prefs = gnuviech.GNVPrefs()
Test(prefs).doTest()