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

Changeset 1118

Show
Ignore:
Timestamp:
06/03/06 14:01:40
Author:
fumanchu
Message:

A little hook/tool refactoring. Moved HookMap? from tools module to _cprequest, and consolidated toolmap and tool setup into a new Request.tool_up method.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/_cprequest.py

    r1109 r1118  
    77 
    88import cherrypy 
    9 from cherrypy import _cputil, _cpcgifs, tools 
    10 from cherrypy.lib import cptools, httptools, profiler 
     9from cherrypy import _cputil, _cpcgifs 
     10from cherrypy.lib import httptools, profiler 
     11 
     12 
     13class HookMap(object): 
     14     
     15    def __init__(self, points=None, failsafe=None): 
     16        points = points or [] 
     17        self.callbacks = dict([(point, []) for point in points]) 
     18        self.failsafe = failsafe or [] 
     19     
     20    def attach(self, point, callback, conf=None): 
     21        if not conf: 
     22            # No point adding a wrapper if there's no conf 
     23            self.callbacks[point].append(callback) 
     24        else: 
     25            def wrapper(): 
     26                callback(**conf) 
     27            self.callbacks[point].append(wrapper) 
     28     
     29    def run(self, point, *args, **kwargs): 
     30        """Execute all registered callbacks for the given point.""" 
     31        failsafe = point in self.failsafe 
     32        for callback in self.callbacks[point]: 
     33            # Some hookpoints guarantee all callbacks are run even if 
     34            # others at the same hookpoint fail. We will still log the 
     35            # failure, but proceed on to the next callback. The only way 
     36            # to stop all processing from one of these callbacks is 
     37            # to raise SystemExit and stop the whole server. So, trap 
     38            # your own errors in these callbacks! 
     39            if failsafe: 
     40                try: 
     41                    callback(*args, **kwargs) 
     42                except (KeyboardInterrupt, SystemExit): 
     43                    raise 
     44                except: 
     45                    cherrypy.log(traceback=True) 
     46            else: 
     47                callback(*args, **kwargs) 
    1148 
    1249 
     
    3572               'on_end_resource', 'on_end_request', 
    3673               'before_error_response', 'after_error_response'] 
    37         self.hooks = tools.HookMap(pts) 
     74        self.hooks = HookMap(pts) 
    3875        self.hooks.failsafe = ['on_start_resource', 'on_end_resource', 
    3976                               'on_end_request'] 
     
    126163            try: 
    127164                self.get_resource(path_info) 
    128                 self.hooks.setup() 
     165                self.tool_up() 
    129166                self.hooks.run('on_start_resource') 
    130167                 
     
    221258     
    222259    def get_resource(self, path): 
     260        """Find and call a dispatcher (which sets self.handler and .config).""" 
    223261        dispatch = _cputil.dispatch 
    224262        # First, see if there is a custom dispatch at this URI. Custom 
     
    250288        # dispatch() should set self.handler and self.config 
    251289        dispatch(path) 
    252          
     290     
     291    def tool_up(self): 
     292        """Populate self.toolmap and set up each tool.""" 
    253293        # Get all 'tools.*' config entries as a {toolname: {k: v}} dict. 
    254294        self.toolmap = {} 
     
    260300                bucket = self.toolmap.setdefault(toolname, {}) 
    261301                bucket[".".join(atoms)] = v 
     302         
     303        # Run tool.setup(conf) for each tool in the new toolmap. 
     304        for toolname, conf in self.toolmap.iteritems(): 
     305            if conf.get("on", False): 
     306                tool = getattr(cherrypy.tools, toolname) 
     307                tool.setup() 
    262308     
    263309    def _get_browser_url(self): 
     
    331377 
    332378 
     379def fileGenerator(input, chunkSize=65536): 
     380    """Yield the given input (a file object) in chunks (default 64k).""" 
     381    chunk = input.read(chunkSize) 
     382    while chunk: 
     383        yield chunk 
     384        chunk = input.read(chunkSize) 
     385    input.close() 
     386 
     387 
    333388class Body(object): 
    334389    """The body of the HTTP response (the response entity).""" 
     
    344399        # Convert the given value to an iterable object. 
    345400        if isinstance(value, types.FileType): 
    346             value = cptools.fileGenerator(value) 
     401            value = fileGenerator(value) 
    347402        elif isinstance(value, types.GeneratorType): 
    348403            value = flattener(value) 
  • trunk/cherrypy/lib/cptools.py

    r1117 r1118  
    5656    def __getattr__(self, key): 
    5757        return self.items[key] 
    58  
    59  
    60 def fileGenerator(input, chunkSize=65536): 
    61     """Yield the given input (a file object) in chunks (default 64k).""" 
    62     chunk = input.read(chunkSize) 
    63     while chunk: 
    64         yield chunk 
    65         chunk = input.read(chunkSize) 
    66     input.close() 
    6758 
    6859 
  • trunk/cherrypy/tools.py

    r1117 r1118  
    1616    CherryPy hooks: "hooks" are points in the CherryPy request-handling 
    1717        process which may hand off control to registered callbacks. The 
    18         Request object possesses a "hooks" attribute (a tools.HookMap) 
     18        Request object possesses a "hooks" attribute (a HookMap) 
    1919        for manipulating this. If a tool exposes a "setup" callable, 
    2020        it will be called once per Request (if the feature is enabled 
     
    2929 
    3030 
    31 class HookMap(object): 
    32      
    33     def __init__(self, points=None, failsafe=None): 
    34         points = points or [] 
    35         self.callbacks = dict([(point, []) for point in points]) 
    36         self.failsafe = failsafe or [] 
    37      
    38     def attach(self, point, callback, conf=None): 
    39         if not conf: 
    40             # No point adding a wrapper if there's no conf 
    41             self.callbacks[point].append(callback) 
    42         else: 
    43             def wrapper(): 
    44                 callback(**conf) 
    45             self.callbacks[point].append(wrapper) 
    46      
    47     def setup(self): 
    48         """Run tool.setup(conf) for each tool specified in current config.""" 
    49         g = globals() 
    50         for toolname, conf in cherrypy.request.toolmap.iteritems(): 
    51             if conf.get("on", False): 
    52                 tool = g[toolname] 
    53                 tool.setup() 
    54      
    55     def run(self, point, *args, **kwargs): 
    56         """Execute all registered callbacks for the given point.""" 
    57         failsafe = point in self.failsafe 
    58         for callback in self.callbacks[point]: 
    59             # Some hookpoints guarantee all callbacks are run even if 
    60             # others at the same hookpoint fail. We will still log the 
    61             # failure, but proceed on to the next callback. The only way 
    62             # to stop all processing from one of these callbacks is 
    63             # to raise SystemExit and stop the whole server. So, trap 
    64             # your own errors in these callbacks! 
    65             if failsafe: 
    66                 try: 
    67                     callback(*args, **kwargs) 
    68                 except (KeyboardInterrupt, SystemExit): 
    69                     raise 
    70                 except: 
    71                     cherrypy.log(traceback=True) 
    72             else: 
    73                 callback(*args, **kwargs) 
    7431 
    7532 

Hosted by WebFaction

Log in as guest/cpguest to create tickets