5 # |
5 # |
6 # This software may be used and distributed according to the terms |
6 # This software may be used and distributed according to the terms |
7 # of the GNU General Public License, incorporated herein by reference. |
7 # of the GNU General Public License, incorporated herein by reference. |
8 |
8 |
9 import errno, mimetypes, os |
9 import errno, mimetypes, os |
|
10 |
|
11 HTTP_OK = 200 |
|
12 HTTP_BAD_REQUEST = 400 |
|
13 HTTP_NOT_FOUND = 404 |
|
14 HTTP_SERVER_ERROR = 500 |
10 |
15 |
11 class ErrorResponse(Exception): |
16 class ErrorResponse(Exception): |
12 def __init__(self, code, message=None): |
17 def __init__(self, code, message=None): |
13 Exception.__init__(self) |
18 Exception.__init__(self) |
14 self.code = code |
19 self.code = code |
52 return "" |
57 return "" |
53 path = os.path.join(path, part) |
58 path = os.path.join(path, part) |
54 try: |
59 try: |
55 os.stat(path) |
60 os.stat(path) |
56 ct = mimetypes.guess_type(path)[0] or "text/plain" |
61 ct = mimetypes.guess_type(path)[0] or "text/plain" |
57 req.header([ |
62 req.respond(HTTP_OK, ct, length = os.path.getsize(path)) |
58 ('Content-Type', ct), |
|
59 ('Content-Length', str(os.path.getsize(path))) |
|
60 ]) |
|
61 return file(path, 'rb').read() |
63 return file(path, 'rb').read() |
62 except TypeError: |
64 except TypeError: |
63 raise ErrorResponse(500, 'illegal file name') |
65 raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal file name') |
64 except OSError, err: |
66 except OSError, err: |
65 if err.errno == errno.ENOENT: |
67 if err.errno == errno.ENOENT: |
66 raise ErrorResponse(404) |
68 raise ErrorResponse(HTTP_NOT_FOUND) |
67 else: |
69 else: |
68 raise ErrorResponse(500, err.strerror) |
70 raise ErrorResponse(HTTP_SERVER_ERROR, err.strerror) |
69 |
71 |
70 def style_map(templatepath, style): |
72 def style_map(templatepath, style): |
71 """Return path to mapfile for a given style. |
73 """Return path to mapfile for a given style. |
72 |
74 |
73 Searches mapfile in the following locations: |
75 Searches mapfile in the following locations: |