Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 301

Show
Ignore:
Timestamp:
06/13/05 02:45:05
Author:
fumanchu
Message:

Basic approach done. Several tests pass. Some filters need creative rewriting. applyFilters needs rewriting to inspect settings in lieu of calls.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/ooconf/cherrypy/_cpconfig.py

    r293 r301  
     1import os.path 
     2import ConfigParser 
     3 
     4cpg = None # delayed import 
    15import _cputil, cperror 
    2 import ConfigParser 
    36from lib import autoreload 
    47 
    5 cpg = None # delayed import 
    68 
    79defaultGlobal = { 
     
    2426    'session.storageFileDir': '', 
    2527     
    26     'sessionFilter.on': True, 
     28    'sessionFilter.on': False, 
    2729    'sessionFilter.timeout': 60, 
    2830    'sessionFilter.cleanUpDelay': 60, 
     
    3436    } 
    3537 
    36 def reset(): 
    37     configMap.clear() 
    38     configMap["/"] = defaultGlobal.copy() 
     38# This settings dict holds the settings metadata for all cpg objects. 
     39# Keys are objects in the cpg.root tree, and values are dicts. 
     40settings = {} 
    3941 
    40 configMap = {} 
    41 reset() 
    4242 
    4343def update(updateMap=None, file=None): 
    4444    if updateMap: 
    45         for section, valueMap in updateMap.items(): 
    46             s = configMap.get(section) 
    47             if not s: 
    48                 configMap[section] = valueMap 
    49             else: 
    50                 s.update(valueMap) 
     45        _update(updateMap) 
    5146    if file: 
    5247        if file not in autoreload.reloadFiles: 
    5348            autoreload.reloadFiles.append(file) 
    54         _load(file
     49        _update(config_from_file(file)
    5550 
    56 def get(key, defaultValue=None, returnSection=False, startPath = None): 
    57     # Look, ma, no Python function calls! Uber-fast. 
    58     # start path lest you overload the starting search path (needed by getAll) 
     51def _update(updateMap): 
     52    global cpg 
     53    if not cpg: 
     54        import cpg 
     55    import _cphttptools 
    5956     
     57    for section, valueMap in updateMap.iteritems(): 
     58        if section == 'global': 
     59            if cpg not in settings: 
     60                settings[cpg] = defaultGlobal.copy() 
     61            settings[cpg].update(valueMap) 
     62        else: 
     63            try: 
     64                obj, v = _cphttptools.mapPathToObject(section) 
     65            except cperror.NotFound: 
     66                continue 
     67            settings.setdefault(obj, {}).update(valueMap) 
     68 
     69 
     70def get(key, defaultValue=None): 
    6071    global cpg 
    6172    if not cpg: 
    6273        import cpg 
    6374     
    64     if startPath: 
    65         path = startPath 
    66     else: 
    67         try: 
    68             path = cpg.request.path 
    69         except AttributeError: 
    70             path = "/" 
    71      
    72     while True: 
    73         if path == "": 
    74             path = "/" 
    75         try: 
    76             result = configMap[path][key] 
    77         except KeyError: 
    78             if path != "/": 
    79                 i = path.rfind("/") 
    80                 if i < 0: 
    81                     result = defaultValue 
    82                 else: 
    83                     path = path[:i] 
    84                     continue 
    85             else: 
    86                 result = defaultValue 
    87         break 
    88      
    89     if returnSection: 
    90         return path 
    91     else: 
    92         return result 
    93          
    94 import os.path 
     75    try: 
     76        s = cpg.request.settings 
     77    except AttributeError: 
     78        # Config is being retrieved outside of a request. 
     79        # Return config for cpg ("global"). 
     80        if cpg not in settings: 
     81            settings[cpg] = defaultGlobal.copy() 
     82        s = settings[cpg] 
     83    return s.get(key, defaultValue) 
    9584 
    9685def getAll(key): 
     
    116105    return result 
    117106 
     107 
     108def collapsedSettings(objectTrail): 
     109    """Collapse all 'settings' attributes in objectTrail into a single dict.""" 
     110    if cpg not in settings: 
     111        settings[cpg] = defaultGlobal.copy() 
     112    result = settings[cpg].copy() 
     113    for obj in objectTrail: 
     114        s = settings.setdefault(obj, {}) 
     115        if s: 
     116            result.update(s) 
     117    return result 
     118 
     119 
    118120class CaseSensitiveConfigParser(ConfigParser.ConfigParser): 
    119121    """ Sub-class of ConfigParser that keeps the case of options and 
     
    134136            fp.close() 
    135137 
    136 def _load(configFile = None): 
     138def config_from_file(configFile = None): 
    137139    """ Convert an INI file to a dictionary """ 
    138140    _cpLogMessage = _cputil.getSpecialAttribute('_cpLogMessage') 
     
    148150 
    149151    # Load INI file into cpg.configMap 
     152    configMap = {} 
    150153    for section in configParser.sections(): 
    151154        if section not in configMap: 
     
    160163                raise cperror.WrongConfigValue, msg 
    161164            configMap[section][option] = value 
     165    return configMap 
    162166 
    163167def outputConfigMap(): 
  • branches/ooconf/cherrypy/_cpdefaults.py

    r275 r301  
    165165        pass 
    166166 
     167 
    167168_cpFilterList = [] 
    168169 
     
    170171from cherrypy.lib.filter import baseurlfilter, cachefilter, \ 
    171172    decodingfilter, encodingfilter, gzipfilter, logdebuginfofilter, \ 
    172     staticfilter, nsgmlsfilter, tidyfilter, \ 
    173     virtualhostfilter, xmlrpcfilter 
     173    nsgmlsfilter, tidyfilter, virtualhostfilter, xmlrpcfilter 
    174174 
    175175from cherrypy.lib.filter.sessionfilter import sessionfilter 
     
    191191    decodingfilter.DecodingFilter(), 
    192192    _sessionfilter, 
    193     staticfilter.StaticFilter(), 
    194193    _nsgmlsfilter, 
    195194    _tidyfilter, 
  • branches/ooconf/cherrypy/_cphttptools.py

    r294 r301  
    103103                    self.processRequestHeaders() 
    104104                     
     105                    main, virtualPathList = self.findMain() 
     106                     
    105107                    applyFilters('beforeRequestBody') 
    106108                    if cpg.request.processRequestBody: 
     
    109111                    applyFilters('beforeMain') 
    110112                    if cpg.response.body is None: 
    111                         main() 
     113                        body = main(*(virtualPathList + cpg.request.paramList), 
     114                                    **(cpg.request.paramMap)) 
     115                        cpg.response.body = iterable(body) 
    112116                     
    113117                    applyFilters('beforeFinalize') 
     
    172176        cpg.request.originalParamMap = cpg.request.paramMap 
    173177        cpg.request.originalParamList = cpg.request.paramList 
     178     
     179    def findMain(self): 
     180        path = cpg.request.path 
     181        # Remove leading and trailing slash 
     182        path = path.strip("/") 
     183        # Replace quoted chars (eg %20) from url 
     184        path = urllib.unquote(path) 
     185         
     186        try: 
     187            path = cpg.request.objectPath or cpg.request.path 
     188            return mapPathToObject(path) 
     189        except cperror.IndexRedirect, inst: 
     190            # For an IndexRedirect, we don't go through the regular 
     191            # mechanism: we return the redirect immediately 
     192            newUrl = urlparse.urljoin(cpg.request.base, inst.args[0]) 
     193            cpg.response.status = '302 Found' 
     194            cpg.response.headerMap['Location'] = newUrl 
     195            cpg.response.body = [] 
     196            finalize() 
     197            raise cperror.RequestHandled 
    174198     
    175199    def processRequestBody(self): 
     
    269293 
    270294# Response functions 
    271  
    272 def main(): 
    273     """Obtain and set cpg.response.body.""" 
    274     path = cpg.request.path 
    275     # Remove leading and trailing slash 
    276     path = path.strip("/") 
    277     # Replace quoted chars (eg %20) from url 
    278     path = urllib.unquote(path) 
    279      
    280     try: 
    281         path = cpg.request.objectPath or cpg.request.path 
    282         func, virtualPathList = mapPathToObject(path) 
    283         body = func(*(virtualPathList + cpg.request.paramList), 
    284                     **(cpg.request.paramMap)) 
    285         cpg.response.body = iterable(body) 
    286     except cperror.IndexRedirect, inst: 
    287         # For an IndexRedirect, we don't go through the regular 
    288         # mechanism: we return the redirect immediately 
    289         newUrl = urlparse.urljoin(cpg.request.base, inst.args[0]) 
    290         cpg.response.status = '302 Found' 
    291         cpg.response.headerMap['Location'] = newUrl 
    292         cpg.response.body = [] 
    293295 
    294296def iterable(body): 
     
    413415    # Also, a method has to have ".exposed = True" in order to be exposed 
    414416     
     417    originalPath = path 
    415418    # Remove leading and trailing slash 
    416419    path = path.strip("/") 
     
    465468     
    466469    if found: 
    467         if rpos == 0: 
    468             # If the original path had no trailing slash, do a redirect 
    469             if cpg.request.path[-1] != '/': 
    470                 newUrl = cpg.request.path + '/' 
    471                 if cpg.request.queryString: 
    472                     newUrl += cpg.request.queryString 
    473                 raise cperror.IndexRedirect(newUrl) 
    474          
    475         # Remove "root" item and join objectPathList to get objectPath 
    476         cpg.request.objectPath = '/' + '/'.join(objectPathList[1:]) 
     470        if hasattr(cpg, "request"): 
     471            if rpos == 0: 
     472                # If the original path had no trailing slash, do a redirect 
     473                if originalPath[-1] != '/': 
     474                    newUrl = originalPath + '/' 
     475                    if cpg.request.queryString: 
     476                        newUrl += cpg.request.queryString 
     477                    raise cperror.IndexRedirect(newUrl) 
     478             
     479            # Remove "root" item and join objectPathList to get objectPath 
     480            cpg.request.objectPath = '/' + '/'.join(objectPathList[1:]) 
     481             
     482            # Form the settings map for this thread/request 
     483            cpg.request.settings = cpg.config.collapsedSettings(objectTrail) 
     484        else: 
     485            # We are probably being called from _cpconfig.update. 
     486            if rpos == 0: 
     487                # The method found was an index method. We don't want that; 
     488                # we want to return the containing object. 
     489                candidate = objectTrail[-2] 
     490         
    477491        return candidate, virtualPathList 
    478492    else: 
  • branches/ooconf/cherrypy/_cputil.py

    r277 r301  
    3333 
    3434import time, thread, cpg, _cpdefaults, cperror 
     35import os, sys, mimetypes 
    3536 
    3637try: import zlib 
    3738except ImportError: pass 
     39 
    3840 
    3941class EmptyClass: 
     
    4143    pass 
    4244 
     45 
     46class StaticContent(object): 
     47     
     48    def default(self, *path): 
     49        filename = cpg.config.get('staticfile') 
     50        if not filename: 
     51            staticDir = cpg.config.get('staticdir') 
     52            filename = os.path.join(staticDir, *path) 
     53         
     54        # If filename is relative, make absolute using cpg.root's module. 
     55        if not os.path.isabs(filename): 
     56            root = os.path.dirname(sys.modules[cpg.root.__module__].__file__) 
     57            filename = os.path.join(root, filename) 
     58         
     59        # Serve filename 
     60        try: 
     61            stat = os.stat(filename) 
     62        except OSError: 
     63            raise cperror.NotFound(cpg.request.path) 
     64         
     65        modifTime = stat.st_mtime 
     66        strModifTime = time.strftime("%a, %d %b %Y %H:%M:%S GMT", 
     67                                     time.gmtime(modifTime)) 
     68        if cpg.request.headerMap.has_key('If-Modified-Since'): 
     69            # Check if if-modified-since date is the same as strModifTime 
     70            if cpg.request.headerMap['If-Modified-Since'] == strModifTime: 
     71                cpg.response.status = "304 Not Modified" 
     72                return 
     73        cpg.response.headerMap['Last-Modified'] = strModifTime 
     74         
     75        # Set Content-Length and use an iterable (file object) 
     76        #   this way CP won't load the whole file in memory 
     77        cpg.response.headerMap['Content-Length'] = stat[6] 
     78        body = open(filename, 'rb') 
     79         
     80        # Set content-type based on filename extension 
     81        i = filename.rfind('.') 
     82        if i != -1: 
     83            ext = filename[i:] 
     84        else: 
     85            ext = "" 
     86        contentType = mimetypes.types_map.get(ext, "text/plain") 
     87        cpg.response.headerMap['Content-Type'] = contentType 
     88        return body 
     89 
     90 
    4391def getSpecialAttribute(name): 
    44     """ Return the special function """ 
    45  
     92    """ Return the special attribute """ 
     93     
    4694    # First, we look in the right-most object if this special function is implemented. 
    4795    # If not, then we try the previous object and so on until we reach cpg.root 
     
    4997    # "_cpdefaults.py" module 
    5098     
    51  
    5299    moduleList = [_cpdefaults] 
    53100    root = getattr(cpg, 'root', None) 
     
    61108        if path: 
    62109            pathList = path.split('/')[1:] 
    63  
     110     
    64111            obj = cpg.root 
    65112            previousObj = None 
     
    72119                except AttributeError: 
    73120                    break 
    74  
     121     
    75122    moduleList.reverse() 
    76123    for module in moduleList: 
  • branches/ooconf/cherrypy/lib/filter/baseurlfilter.py

    r230 r301  
    4949         
    5050        if newBaseUrl.find("://") == -1: 
    51             # add http:// or https:// if needed         
     51            # add http:// or https:// if needed 
    5252            newBaseUrl = cpg.request.base[:cpg.request.base.find("://") + 3] + newBaseUrl 
    5353         
  • branches/ooconf/cherrypy/lib/filter/virtualhostfilter.py

    r293 r301  
    4646         
    4747        prefix = cpg.config.get('virtualHostFilter.prefix', '/') 
    48          
    49         # mapPath will set cpg.request.objectPath 
    50         _cphttptools.mapPathToObject(prefix + cpg.request.path) 
    51          
    52         #raise basefilter.InternalRedirect 
     48        cpg.request.path = prefix + cpg.request.path 
  • branches/ooconf/cherrypy/test/test.py

    r293 r301  
    163163                   'server.logToScreen': False, 
    164164                   'server.environment': "production", 
    165 ##                   'profiling.on': True, 
     165                   'profiling.on': True, 
    166166                   } 
    167167     
     
    173173        print "Running tests:", name 
    174174         
    175         cpg.config.update({'/': server_conf.copy()}) 
     175        cpg.config.update({'global': server_conf.copy()}) 
    176176        helper.startServer(server) 
    177177        for testmod in testList: 
    178178            # Must run each module in a separate suite, 
    179179            # because each module uses/overwrites cpg globals. 
    180             cpg.config.reset() 
    181             cpg.config.update({'/': server_conf.copy()}) 
     180            cpg.config.update({'global': server_conf.copy()}) 
    182181            suite = CPTestLoader.loadTestsFromName(testmod) 
    183182            CPTestRunner(verbosity=2).run(suite) 
  • branches/ooconf/cherrypy/test/test_baseurl_filter.py

    r267 r301  
    3737cpg.root = Root() 
    3838cpg.config.update({ 
     39    'global': { 
     40        'server.environment': 'production', 
     41        'server.logToScreen': False, 
     42    }, 
    3943    '/': { 
    40         'server.environment': 'production', 
    4144        'baseUrlFilter.on': True, 
    4245        'baseUrlFilter.baseUrl': 'http://www.mydomain.com' 
  • branches/ooconf/cherrypy/test/test_core.py

    r267 r301  
    121121 
    122122 
     123def dummy(): return 
     124 
     125cpg.root.foo = dummy 
     126cpg.root.foo.exposed = True 
     127cpg.root.foo.bar = lambda: [] 
     128cpg.root.foo.bar.exposed = True 
     129 
    123130cpg.config.update({ 
    124     '/': { 
     131    'global': { 
    125132        'server.logToScreen': False, 
    126133        'server.environment': 'production', 
     134    }, 
     135    '/': { 
    127136        'foo': 'this', 
    128137        'bar': 'that', 
     
    145154     
    146155    def testConfig(self): 
    147         from cherrypy import _cpconfig 
    148156        tests = [ 
    149157            ('/',        'nex', None   ), 
     
    158166        ] 
    159167        for path, key, expected in tests: 
    160             cpg.request.path = path 
    161             result = _cpconfig.get(key, None) 
     168            helper.request(path) 
     169            result = cpg.config.get(key, None) 
    162170            self.assertEqual(result, expected) 
    163171     
  • branches/ooconf/cherrypy/test/test_decodingencoding_filter.py

    r267 r301  
    3838cpg.root = Root() 
    3939cpg.config.update({ 
    40     '/': { 
     40    'global': { 
    4141        'server.logToScreen': False, 
    4242        'server.environment': 'production', 
     43    }, 
     44    '/': { 
    4345        'encodingFilter.on': True, 
    4446        'decodingFilter.on': True 
  • branches/ooconf/cherrypy/test/test_gzip_filter.py

    r267 r301  
    3737cpg.root = Root() 
    3838cpg.config.update({ 
    39     '/': { 
     39    'global': { 
    4040        'server.logToScreen': False, 
    4141        'server.environment': 'production', 
     42    }, 
     43    '/': { 
    4244        'gzipFilter.on': True, 
    4345    } 
  • branches/ooconf/cherrypy/test/test_logdebuginfo_filter.py

    r299 r301  
    3636cpg.root = Root() 
    3737cpg.config.update({ 
    38     '/': { 
     38    'global': { 
    3939        'session.storageType': 'ram', 
    4040        'session.timeout': 60, 
     
    4545        'server.logToScreen': False, 
    4646        'server.environment': 'production', 
     47    }, 
     48    '/': { 
    4749        'logDebugInfoFilter.on': True, 
    4850    } 
  • branches/ooconf/cherrypy/test/test_objectmapping.py

    r293 r301  
    9494cpg.root.dir1.dir2.dir3.dir4 = Dir4() 
    9595cpg.config.update({ 
     96    'global': { 
     97        'server.logToScreen': False, 
     98    }, 
    9699    '/': { 
    97         'server.logToScreen': False, 
    98100        'logDebugInfoFilter.on': False, 
    99101    } 
  • branches/ooconf/cherrypy/test/test_tutorials.py

    r293 r301  
    4242def load_tut_module(tutorialName): 
    4343    """Import or reload tutorial module as needed.""" 
    44     cpg.config.reset() 
     44    cpg.config.settings.clear() 
    4545    cpg.config.update({'/': server_conf.copy()}) 
    4646     
     
    144144    def test08Sessions(self): 
    145145        load_tut_module("tut08_sessions") 
     146        cpg.config.update({"/": {"sessionFilter.on": True}}) 
    146147         
    147148        helper.request('/') 
     
    168169    def test10SessionFilter(self): 
    169170        load_tut_module("tut10_sessionfilter") 
     171        cpg.config.update({"/": {"sessionFilter.on": True}}) 
    170172         
    171173        helper.request('/') 
  • branches/ooconf/cherrypy/test/test_virtualhost_filter.py

    r267 r301  
    3636cpg.root = Root() 
    3737cpg.config.update({ 
    38     '/': { 
     38    'global': { 
    3939        'server.logToScreen': False, 
    4040        'server.environment': 'production', 
     41    }, 
     42    '/': { 
    4143        'virtualHostFilter.on': True, 
    4244        'virtualHostFilter.prefix': '/index2', 
  • branches/ooconf/cherrypy/tutorial/tut08_sessions.py

    r267 r301  
    2929 
    3030cpg.root = HitCounter() 
    31  
     31cpg.config.update({'/': {'sessionFilter.on': True}}) 
    3232 
    3333if __name__ == '__main__': 
  • branches/ooconf/cherrypy/tutorial/tut10_sessionfilter.conf

    r299 r301  
    44server.environment = "production" 
    55 
     6sessionFilter.on=True 
    67# by default we get 
    7 # sessionFilter.on=True 
    88# sessionFilter.new='sessionMap' 
    99# sessionMap.storageType='ram' 

Hosted by WebFaction

Log in as guest/cpguest to create tickets