summaryrefslogtreecommitdiff
path: root/paste/wareweb/packing.py
diff options
context:
space:
mode:
Diffstat (limited to 'paste/wareweb/packing.py')
-rw-r--r--paste/wareweb/packing.py213
1 files changed, 0 insertions, 213 deletions
diff --git a/paste/wareweb/packing.py b/paste/wareweb/packing.py
deleted file mode 100644
index 9cf080b..0000000
--- a/paste/wareweb/packing.py
+++ /dev/null
@@ -1,213 +0,0 @@
-import inspect
-import xmlrpclib
-import traceback
-from paste.httpexceptions import HTTPBadRequest
-json = None
-
-__all__ = ['unpack', 'unpack_xmlrpc', 'unpack_json']
-
-def unpack(func):
- argspec = FunctionArgSpec(func)
- def replacement_func(self):
- args, kw = argspec.unpack_args(self.path_parts, self.fields)
- return func(self, *args, **kw)
- replacement_func.__doc__ = func.__doc__
- replacement_func.__name__ = func.__name__
- return replacement_func
-
-def unpack_xmlrpc(func):
- def replacement_func(self):
- assert self.environ['CONTENT_TYPE'].startswith('text/xml')
- data = self.environ['wsgi.input'].read()
- xmlargs, method_name = xmlrpclib.loads(data)
- if method_name:
- kw = {'method_name': method_name}
- else:
- kw = {}
- self.set_header('content-type', 'text/xml; charset=UTF-8')
- try:
- result = func(self, *xmlargs, **kw)
- except:
- body = make_rpc_exception(environ, sys.exc_info())
- body = xmlrpclib.dumps(
- xmlrpclib.Fault(1, fault), encoding='utf-8')
- else:
- if not isinstance(result, tuple):
- result = (result,)
- body = xmlrpclib.dumps(
- result, methodresponse=True, encoding='utf-8')
- self.write(body)
- replacement_func.__doc__ = func.__doc__
- replacement_func.__name__ = func.__name__
- return replacement_func
-
-def make_rpc_exception(environ, exc_info):
- config = environ['paste.config']
- rpc_exception = config.get('rpc_exception', None)
- if rpc_exception not in (None, 'occurred', 'exception', 'traceback'):
- environ['wsgi.errors'].write(
- "Bad 'rpc_exception' setting: %r\n" % rpc_exception)
- rpc_exception = None
- if rpc_exception is None:
- if config.get('debug'):
- rpc_exception = 'traceback'
- else:
- rpc_exception = 'exception'
- if rpc_exception == 'occurred':
- fault = 'unhandled exception'
- elif rpc_exception == 'exception':
- fault = str(e)
- elif rpc_exception == 'traceback':
- out = StringIO()
- traceback.print_exception(*exc_info, **{'file': out})
- fault = out.getvalue()
- return fault
-
-def unpack_json(func):
- global json
- if json is None:
- import json
- def replacement_func(self):
- data = self.environ['wsgi.input'].read()
- jsonrpc = json.jsonToObj(data)
- method = jsonrpc['method']
- params = jsonrpc['params']
- id = jsonrpc['id']
- if method:
- kw = {'method_name': method}
- else:
- kw = {}
- self.set_header('content-type', 'text/plain; charset: UTF-8')
- try:
- result = func(self, *params, **kw)
- except:
- body = make_rpc_exception(environ, sys.exc_info())
- response = {
- 'result': None,
- 'error': body,
- 'id': id}
- else:
- response = {
- 'result': result,
- 'error': None,
- 'id': id}
- self.write(json.objToJson(response))
- replacement_func.__doc__ = func.__doc__
- replacement_func.__name__ = func.__name__
- return replacement_func
-
-
-class FunctionArgSpec(object):
-
- def __init__(self, func):
- self.funcargs, self.varargs, self.varkw, self.defaults = (
- inspect.getargspec(func))
- self.positional = []
- self.optional_pos = []
- self.coersions = self.collect_coersions(self.funcargs)
- while self.funcargs and self.funcargs[0].endswith('_path'):
- if len(self.defaults or ()) == len(self.funcargs):
- # This is an optional path segment
- self.optional_pos.append(self.funcargs.pop(0))
- self.defaults = self.defaults[1:]
- else:
- self.positional.append(self.funcargs.pop(0))
- self.reqargs = []
- if not self.defaults:
- self.reqargs = self.funcargs
- else:
- self.reqargs = self.funcargs[:-len(self.defaults)]
-
- def unpack_args(self, path_parts, fields):
- args = []
- kw = {}
- if len(self.positional) > len(path_parts):
- raise HTTPBadRequest(
- "Not enough parameters on the URL (expected %i more "
- "path segments)" % (len(self.positional)-len(path_parts)))
- if (not self.varargs
- and (len(self.positional)+len(self.optional_pos))
- < len(path_parts)):
- raise HTTPBadRequest(
- "Too many parameters on the URL (expected %i less path "
- "segments)" % (len(path_parts)-len(self.positional)
- -len(self.optional_pos)))
- for name, value in fields.iteritems():
- if not self.varkw and name not in self.coersions:
- raise HTTPBadRequest(
- "Variable %r not expected" % name)
- if name not in self.coersions:
- kw[name] = value
- continue
- orig_name, coercer = self.coersions[name]
- if coercer:
- try:
- value = coercer(value)
- except (ValueError, TypeError), e:
- raise HTTPBadRequest(
- "Bad variable %r: %s" % (name, e))
- kw[orig_name] = value
- for arg in self.reqargs:
- if arg not in kw:
- raise HTTPBadRequest(
- "Variable %r required" % arg)
- return args, kw
-
- def collect_coersions(self, funcargs):
- coersions = {}
- for name in funcargs:
- coercer = normal
- orig = name
- while 1:
- if name.endswith('_int'):
- coercer = self.add_coercer(coercer, make_int)
- name = name[:-4]
- elif name.endswith('_list'):
- coercer = self.add_coercer(coercer, make_list)
- name = name[:-5]
- elif name.endswith('_float'):
- coercer = self.add_coercer(coercer, make_float)
- name = name[:-6]
- elif name.endswith('_req'):
- coercer = self.add_coercer(coercer, make_required)
- name = name[:-4]
- else:
- break
- coersions[name] = (orig, coercer)
- return coersions
-
- def add_coercer(self, coercer, new_coercer):
- if not coercer or coercer is normal:
- return new_coercer
- else:
- def coerce(val):
- return new_coercer(coercer(val))
- return coerce
-
-def make_int(v):
- if isinstance(v, list):
- return map(int, v)
- else:
- return int(v)
-
-def make_float(v):
- if isinstance(v, list):
- return map(float, v)
- else:
- return float(v)
-
-def make_list(v):
- if isinstance(v, list):
- return v
- else:
- return [v]
-
-def make_required(s):
- if s is None:
- raise TypeError
- return s
-
-def normal(v):
- if isinstance(v, list):
- raise ValueError("List not expected")
- return v