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

Reply via email to