Mercurial > hg > simpypi
annotate simpypi/factory.py @ 25:511210365ce3
WIP getting paste StaticURLParser to serve directories
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Wed, 29 Feb 2012 10:29:11 -0800 |
parents | 13ed82d10144 |
children | fb03f34a982f |
rev | line source |
---|---|
19
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
1 #!/usr/bin/env python |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
2 |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
3 """ |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
4 factories for simpypi |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
5 """ |
0 | 6 |
19
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
7 import optparse |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
8 import os |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
9 import shutil |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
10 import sys |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
11 import tempfile |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
12 |
0 | 13 from paste.httpexceptions import HTTPExceptionHandler |
14 from paste.urlparser import StaticURLParser | |
15 from pkg_resources import resource_filename | |
19
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
16 from wsgi import SimPyPI |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
17 from wsgiref import simple_server |
0 | 18 |
23
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
19 class DirectoryServer(StaticURLParser): |
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
20 def __init__(self, directory): |
24 | 21 StaticURLParser.__init__(self, directory) |
23
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
22 |
25
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
23 def index(self, directory): |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
24 """ |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
25 generate a directory listing for a given directory |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
26 """ |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
27 parts = ['<html><head><title>Simple Index</title></head><body>'] |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
28 listings = os.listdir(directory) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
29 listings = [(os.path.isdir(os.path.join(directory, entry)) and entry + '/' or entry, entry) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
30 for entry in listings] |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
31 for link, entry in listings: |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
32 parts.append('<a href="%s">%s</a><br/>' % (link, entry)) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
33 parts.append('</body></html>') |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
34 return '\n'.join(parts) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
35 |
23
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
36 def __call__(self, environ, start_response): |
25
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
37 |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
38 # normalize path |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
39 # from paste.urlparser.StaticURLParser |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
40 path_info = environ.get('PATH_INFO', '') |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
41 if not path_info: |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
42 return self.add_slash(environ, start_response) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
43 full = self.normpath(os.path.join(self.directory, path_info.strip('/'))) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
44 if not full.startswith(self.root_directory): |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
45 # Out of bounds |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
46 return self.not_found(environ, start_response) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
47 |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
48 # return index listing |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
49 if os.path.isdir(full): |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
50 if not path_info.endswith('/'): |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
51 return self.add_slash(environ, start_response) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
52 index = self.index(full) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
53 response_headers = [('Content-Type', 'text/html'), |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
54 ('Content-Length', str(len(index)))] |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
55 start_response('200 OK', response_headers) |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
56 return [index] |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
57 |
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
58 return StaticURLParser.__call__(self, environ, start_response) |
23
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
59 |
0 | 60 class PassthroughFileserver(object): |
61 """serve files if they exist""" | |
62 | |
16
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
63 def __init__(self, app, directory): |
0 | 64 self.app = app |
16
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
65 self.directory = directory |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
66 self.fileserver = StaticURLParser(directory) |
0 | 67 |
68 def __call__(self, environ, start_response): | |
16
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
69 path = self.path(environ['PATH_INFO'].strip('/')) |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
70 if path and os.path.exists(os.path.join(self.directory, path)): |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
71 return self.fileserver(environ, start_response) |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
72 return self.app(environ, start_response) |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
73 |
23
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
74 class NamespacedFileserver(DirectoryServer): |
16
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
75 |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
76 def __init__(self, app, directory, namespace): |
23
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
77 DirectoryServer.__init__(self, directory) |
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
78 self.app = app |
16
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
79 self.namespace = namespace |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
80 |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
81 def __call__(self, environ, start_response): |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
82 path = environ['PATH_INFO'] |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
83 if path == self.namespace: |
25
511210365ce3
WIP getting paste StaticURLParser to serve directories
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
84 return self.add_slash(environ, start_response) |
16
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
85 environ['PATH_INFO'] = '/' |
24 | 86 return DirectoryServer.__call__(self, environ, start_response) |
16
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
87 elif path.startswith(self.namespace + '/'): |
d3efc504c0b1
more towards the type of fileserver we actually care about
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
88 environ['PATH_INFO'] = path[len(self.namespace):] |
24 | 89 return DirectoryServer.__call__(self, environ, start_response) |
0 | 90 return self.app(environ, start_response) |
91 | |
23
e72d9655d753
start stubbing a directory server
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
92 |
1 | 93 def factory(**app_conf): |
0 | 94 """create a webob view and wrap it in middleware""" |
4 | 95 directory = app_conf['directory'] |
19
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
96 app = SimPyPI(**app_conf) |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
97 return NamespacedFileserver(app, directory, '/index') |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
98 |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
99 def main(args=sys.argv[:]): |
0 | 100 |
19
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
101 # parse command line options |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
102 usage = '%prog [options]' |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
103 parser = optparse.OptionParser(usage=usage) |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
104 parser.add_option('-p', '--port', dest='port', |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
105 type='int', default=8080, |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
106 help="port to run the server on") |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
107 parser.add_option('-d', '--directory', dest='directory', |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
108 help='directory to serve') |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
109 options, args = parser.parse_args(args) |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
110 |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
111 # create a temporary directory, if none specified |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
112 tmpdir = None |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
113 if not options.directory: |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
114 tmpdir = tempfile.mkdtemp() |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
115 options.directory = tmpdir |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
116 |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
117 # serve |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
118 print "http://localhost:%d/" % options.port |
2 | 119 try: |
19
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
120 app = factory(directory=options.directory) |
20 | 121 server = simple_server.make_server(host='0.0.0.0', port=options.port, app=app) |
3 | 122 server.serve_forever() |
2 | 123 finally: |
19
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
124 if tmpdir: |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
125 shutil.rmtree(tmpdir) |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
126 |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
127 if __name__ == '__main__': |
bf70fc5a115f
make a real python program
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
128 main() |