summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Bicking <ian@ianbicking.org>2005-09-28 21:56:31 +0000
committerIan Bicking <ian@ianbicking.org>2005-09-28 21:56:31 +0000
commit4209f55f4a7d6598f1a7715ec20280984c45663d (patch)
tree70bb4e482d449a9e3e86bd042a5cfd27b1913b16
parent3a0706f56f2f109b21965fe27c020687a893f525 (diff)
downloadpaste-git-4209f55f4a7d6598f1a7715ec20280984c45663d.tar.gz
Added parser that reads files from an egg using pkg_resources
-rw-r--r--paste/urlparser.py54
-rw-r--r--tests/test_urlparser.py20
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)