On Thursday 06 December 2001 15:40, Geoffrey Talvola wrote:
> At 03:34 PM 12/6/01 -0800, Tavis Rudd wrote:
> >The keyword 'class' might be a bit misleading as we're not
> > promissing 1-to-1 mappings to actual classes, but that's no big
> > deal either. In fact, we can use anything that supports
> > __getatrr__ and __setattr__ for the settings containers: modules,
> > classes, objects, etc. This is much cleaner than dictionaries!
>
> I agree, I definitely prefer regular Python assignments over
> dictionaries. But it would be nice to allow both, if only to ease
> the transition.
I've attached a copy of the old .webkit_config_annotated file
translated to the proposed format. It seems to work with all
versions of Python, not just 2.1 and up. This file contains all the
settings and is more complicated than the average user will need so
I've also attached an example of what typical config might look like.
The SettingsContainer baseclass is used to make sure that settings
that are in fact meant to be classes aren't handled as
SettingsContainers. In practice a shorter name might be better.
Finally, I've attached some simple functions that can be used to get
settings out of the SettingsContainers recursively and turn them into
dictionaries.
> I'm not sure I agree that it should search for the config file at
> all. Explicit is better than implicit, and in this case I think
> it's better to know exactly where your config settings are coming
> from, by specifying it right on the command line. You can always
> use a bash or .bat wrapper to avoid having to retype it every time.
Hmm, I agree, although it should be able to detect a webware_config
module or package sitting in the dir that the script is called from.
Ok, now back to that PSP stuff ;)
Tavis
from Webware.Utils.SettingsManager import SettingsContainer
True = 1
False = 0
##################################################
## WEBKIT SETTINGS
# base classes to inherit settings from
class _ErrorHandling(SettingsContainer):
"""These settings are inherited by the AppServer and all the Applications below."""
printErrorsToConsole = True
userErrorMsg = "The site is having technical difficulties with this page. " \
"The problem has been logged and will be fixed as soon as " \
"possible. Sorry!"
logErrors = False
errorLogFilename = 'Errors.csv'
saveErrorMsgs = False
errorMsgsDir = 'ErrorMsgs'
HTTP404ErrorMsg = """Content-type: text/html\n\n
<html>
<body text="black" bgcolor="white">
<h1>404 Error</h1>
<p>
<h2>Page Not Available On This Server</h2>
<p>
The page you requested, <b>%s</b>, was not found on this server.
<hr>
Webware Application Server
</body></html>
"""
emailErrors = False
errorEmailServer = 'mail.-.com'
errorEmailTo = '[EMAIL PROTECTED]'
errorEmailFrom = '[EMAIL PROTECTED]'
errorEmailSubject = 'A Webware Error Occurred'
errorEmailExtraHeaders = {}
class _ApplicationDefaults(_ErrorHandling):
"""Default settings that are inherited by all the applications running in
the AppServer. """
servletRootPath = '' # There is no default for this one.
# the 'python:' prefix means 'parse as a Python literal'
directoryFiles = ['index','Main', 'default']
extensionsToIgnore = ['.pyc','.pyo','.py~', '.bak', '.tmpl', '.py_bak']
useCascadingExtensions = True
# When dropping the extensions from filenames in requests the existing Webware
# will raise an exception if there are multiple files with different extensions
# for the requested basename. This version allows you to specify a list of
# extensions to cascade through and use the first one found. If you list .html
# before .py in your list of extensions and a request can map to 'file.html' or
# 'file.py', 'file.html' will be returned rather than raising an exception.
extensionCascadeOrder = [ '.html', '.py','.psp', '.tmpl']
# If you specify a list of extensions, only files with those extensions will be
served.
extensionsToServeFilter = None
cacheStaticFiles = True # should static files be cached in memory
updateStaticFiles = True # should static files be monitored for file updates
usePrivateSessions = True # use separate SessIDToken & session pool for each
Application
sessionIdToken = '_WEBWARE_SID_' # the default when 'usePrivateSessions' is False
sessionTimeout = 60 #min
sessionStore = 'Dynamic' # File, or Memory
class WebKit(SettingsContainer):
"""These are the settings All settings at the top-level are used by
the 'MultiPortServer'."""
workingDir = '.'
recordPID = True # Record the Process ID?
PIDFile = 'webware.pid' # Path is relative to 'workingDir' above
recordRunSettings = True # Record extended info. on the current process
runSettingsFile = 'webware_run_settings.txt' # related to the previous setting
startupNotice = ''
enableCOM = False # This provides the same functionality as ComKit.
class Services(SettingsContainer):
"""Each service is bound to separate port.
"""
class MonitorService(SettingsContainer):
"""Monitors the AppServer from a separate process and restarts it if
it fails."""
on = False # should it be run? - overridden by commandline -m
flag
checkInterval = 10 # secs
autoRestartTimeout = 0 # min - this might be buggy
delayBeforeRestart = 5 # secs
delayAfterRestart = 4 # secs
logOnSuccess = False # should successful monitor checks be logged
class AdminServer(SettingsContainer):
"""An adminstration service that runs alongside the AppServer in the main
process. Currently, it sole function is to provide status updates to the
MonitorService. It is implemented as a subclass of the AppServer class so
it has
great potential for extended admin facilities in the future."""
hostName = 'localhost'
port = 8085
allowRemoteShutdown = False
class HTTPServer(_ErrorHandling):
"""The builtin HTTPServer
"""
serverString = 'WebKit HTTP Server'
hostName = 'localhost'
port = 8087
threads = 10
class AppServer(_ErrorHandling):
"""The main AppServer.
"""
hostName = 'localhost'
port = 8086
threads = 10 # How many threads in pool that processed
requests
usePoll = False # Use poll() system call for dispatching
instead of select()
eventCheckInterval = 100 # sys.setEventCheckInterval()
pollTimeout = 2 # How long to block for during each poll() or
select() call
listenQueueLimit = 1024 # Max number of connections queued to be
accepted
connQueueLimit = 150 # Max number of connections accepted and queued
for processing
class Applications(SettingsContainer):
class MyApp(_ApplicationDefaults):
servletRootPath = '/home/tavis/Webware/MyApp'
class MyOtherApp(_ApplicationDefaults):
servletRootPath = '/home/tavis/Webware/MyOtherApp'
DEFAULT_APP = MyApp # same as the default 'context'
from Webware.Utils.SettingsManager import SettingsContainer
True = 1
False = 0
##################################################
## WEBKIT SETTINGS
class WebKit(SettingsContainer):
class Services(SettingsContainer):
class AppServer(SettingsContainer):
hostName = 'localhost'
port = 8086
class Applications(SettingsContainer):
class MyApp(SettingsContainer):
servletRootPath = '/home/tavis/Webware/MyApp'
class MyOtherApp(SettingsContainer):
servletRootPath = '/home/tavis/Webware/MyOtherApp'
DEFAULT_APP = MyApp # same as the default 'context'
from Webware.Utils.SettingsManager import SettingsContainer
from types import ClassType, ModuleType, InstanceType
def isContainer(thing):
return type(thing) == ModuleType or (
type(thing) == ClassType and issubclass(thing, SettingsContainer)
)
def getAllAttrs(container):
attrs = container.__dict__.copy()
for base in container.__bases__:
for k, v in base.__dict__.items():
if not attrs.has_key(k):
attrs[k] = v
return attrs
def extractSettings(container):
S = {}
if type(container) == ModuleType:
attrs = vars(container)
else:
attrs = getAllAttrs(container)
for k, v in attrs.items():
if k.startswith('__'):
continue
if isContainer(v):
S[k] = extractSettings(v)
else:
S[k] = v
return S