0001"""REST decorators"""
0002import logging
0003
0004from decorator import decorator
0005
0006import pylons
0007from pylons.controllers.util import abort
0008
0009__all__ = ['dispatch_on', 'restrict']
0010
0011log = logging.getLogger(__name__)
0012
0013def restrict(*methods):
0014 """Restricts access to the function depending on HTTP method
0015
0016 Example:
0017
0018 .. code-block:: Python
0019
0020 from pylons.decorators import rest
0021
0022 class SomeController(BaseController):
0023
0024 @rest.restrict('GET')
0025 def comment(self, id):
0026 """
0027 def check_methods(func, *args, **kwargs):
0028 """Wrapper for restrict"""
0029 if pylons.request.method not in methods:
0030 log.debug("Method not allowed by restrict")
0031 abort(405, headers=[('Allow', ','.join(methods))])
0032 return func(*args, **kwargs)
0033 return decorator(check_methods)
0034
0035def dispatch_on(**method_map):
0036 """Dispatches to alternate controller methods based on HTTP method
0037
0038 Multiple keyword arguments should be passed, with the keyword corresponding
0039 to the HTTP method to dispatch on (DELETE, POST, GET, etc.) and the
0040 value being the function to call. The value should be a string indicating
0041 the name of the function to dispatch to.
0042
0043 Example:
0044
0045 .. code-block:: Python
0046
0047 from pylons.decorators import rest
0048
0049 class SomeController(BaseController):
0050
0051 @rest.dispatch_on(POST='create_comment')
0052 def comment(self):
0053 # Do something with the comment
0054
0055 def create_comment(self, id):
0056 # Do something if its a post to comment
0057 """
0058 def dispatcher(func, self, *args, **kwargs):
0059 """Wrapper for dispatch_on"""
0060 alt_method = method_map.get(pylons.request.method)
0061 if alt_method:
0062 alt_method = getattr(self, alt_method)
0063 log.debug("Dispatching to %s instead", alt_method)
0064 return self._inspect_call(alt_method, **kwargs)
0065 return func(self, *args, **kwargs)
0066 return decorator(dispatcher)