diff options
author | Ian Bicking <ian@ianbicking.org> | 2005-09-28 21:56:31 +0000 |
---|---|---|
committer | Ian Bicking <ian@ianbicking.org> | 2005-09-28 21:56:31 +0000 |
commit | 4209f55f4a7d6598f1a7715ec20280984c45663d (patch) | |
tree | 70bb4e482d449a9e3e86bd042a5cfd27b1913b16 | |
parent | 3a0706f56f2f109b21965fe27c020687a893f525 (diff) | |
download | paste-git-4209f55f4a7d6598f1a7715ec20280984c45663d.tar.gz |
Added parser that reads files from an egg using pkg_resources
-rw-r--r-- | paste/urlparser.py | 54 | ||||
-rw-r--r-- | tests/test_urlparser.py | 20 |
2 files changed, 73 insertions, 1 deletions
diff --git a/paste/urlparser.py b/paste/urlparser.py index c95e86b..8ad2eb7 100644 --- a/paste/urlparser.py +++ b/paste/urlparser.py @@ -4,6 +4,8 @@ import os import sys import imp +import pkg_resources +import mimetypes import wsgilib from paste.util import import_string from paste.deploy import converters @@ -11,7 +13,7 @@ from paste.deploy import converters class NoDefault: pass -__all__ = ['URLParser', 'StaticURLParser'] +__all__ = ['URLParser', 'StaticURLParser', 'PkgResourcesParser'] class URLParser(object): @@ -468,3 +470,53 @@ class StaticURLParser(object): def make_static(global_conf, document_root): return StaticURLParser(document_root) + +class PkgResourcesParser(StaticURLParser): + + def __init__(self, egg_or_spec, resource_name, manager=None): + if isinstance(egg_or_spec, (str, unicode)): + self.egg = pkg_resources.get_distribution(egg_or_spec) + else: + self.egg = egg_or_spec + self.resource_name = resource_name + if manager is None: + manager = pkg_resources.ResourceManager() + self.manager = manager + + def __repr__(self): + return '<%s for %s:%r>' % ( + self.__class__.__name__, + self.egg.project_name, + self.resource_name) + + def __call__(self, environ, start_response): + path_info = environ.get('PATH_INFO', '') + if not path_info: + return self.add_slash(environ, start_response) + if path_info == '/': + # @@: This should obviously be configurable + filename = 'index.html' + else: + filename = wsgilib.path_info_pop(environ) + resource = self.resource_name + '/' + filename + if not self.egg.has_resource(resource): + return self.not_found(environ, start_response) + if self.egg.resource_isdir(resource): + # @@: Cache? + return self.__class__(self.egg, resource, self.manager)(environ, start_response) + if environ.get('PATH_INFO') and environ.get('PATH_INFO') != '/': + return self.error_extra_path(environ, start_response) + + type, encoding = mimetypes.guess_type(resource) + # @@: I don't know what to do with the encoding. + try: + file = self.egg.get_resource_stream(self.manager, resource) + except (IOError, OSError), e: + status, headers, body = wsgilib.error_response( + '403 Forbidden', + 'You are not permitted to view this file (%s)' % e) + start_response(status, headers) + return [body] + start_response('200 OK', + [('content-type', type)]) + return wsgilib._FileIter(file) diff --git a/tests/test_urlparser.py b/tests/test_urlparser.py index 5a1d518..a6d66bb 100644 --- a/tests/test_urlparser.py +++ b/tests/test_urlparser.py @@ -75,3 +75,23 @@ def test_not_found_hook(): assert res.status == 200 assert 'user: bob' in res +def test_static_parser(): + app = StaticURLParser(path('find_file')) + testapp = TestApp(app) + res = testapp.get('', status=301) + res = testapp.get('/', status=404) + res = testapp.get('/index.txt') + assert res.body.strip() == 'index1' + res = testapp.get('/index.txt/foo', status=500) + +def test_egg_parser(): + app = PkgResourcesParser('Paste', 'paste') + testapp = TestApp(app) + res = testapp.get('', status=301) + res = testapp.get('/', status=404) + res = testapp.get('/flup_session', status=404) + res = testapp.get('/util/classinit.py') + assert 'ClassInitMeta' in res + res = testapp.get('/util/classinit', status=404) + res = testapp.get('/util', status=301) + res = testapp.get('/util/classinit.py/foo', status=500) |