Anonymous avatar Anonymous committed b977f81

Added parser that reads files from an egg using pkg_resources

Comments (0)

Files changed (2)

paste/urlparser.py

 import os
 import sys
 import imp
+import pkg_resources
+import mimetypes
 import wsgilib
 from paste.util import import_string
 from paste.deploy import converters
 class NoDefault:
     pass
 
-__all__ = ['URLParser', 'StaticURLParser']
+__all__ = ['URLParser', 'StaticURLParser', 'PkgResourcesParser']
 
 class URLParser(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)

tests/test_urlparser.py

     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)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.