Show More
@@ -1,62 +1,62 b'' | |||||
1 | # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod |
|
1 | # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod | |
2 | # |
|
2 | # | |
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> | |
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
|
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
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 os, mimetypes |
|
9 | import os, mimetypes | |
10 |
|
10 | |||
11 | def get_mtime(repo_path): |
|
11 | def get_mtime(repo_path): | |
12 | store_path = os.path.join(repo_path, ".hg") |
|
12 | store_path = os.path.join(repo_path, ".hg") | |
13 | if not os.path.isdir(os.path.join(store_path, "data")): |
|
13 | if not os.path.isdir(os.path.join(store_path, "data")): | |
14 | store_path = os.path.join(store_path, "store") |
|
14 | store_path = os.path.join(store_path, "store") | |
15 | cl_path = os.path.join(store_path, "00changelog.i") |
|
15 | cl_path = os.path.join(store_path, "00changelog.i") | |
16 | if os.path.exists(cl_path): |
|
16 | if os.path.exists(cl_path): | |
17 | return os.stat(cl_path).st_mtime |
|
17 | return os.stat(cl_path).st_mtime | |
18 | else: |
|
18 | else: | |
19 | return os.stat(store_path).st_mtime |
|
19 | return os.stat(store_path).st_mtime | |
20 |
|
20 | |||
21 | def staticfile(directory, fname, req): |
|
21 | def staticfile(directory, fname, req): | |
22 | """return a file inside directory with guessed content-type header |
|
22 | """return a file inside directory with guessed content-type header | |
23 |
|
23 | |||
24 | fname always uses '/' as directory separator and isn't allowed to |
|
24 | fname always uses '/' as directory separator and isn't allowed to | |
25 | contain unusual path components. |
|
25 | contain unusual path components. | |
26 | Content-type is guessed using the mimetypes module. |
|
26 | Content-type is guessed using the mimetypes module. | |
27 | Return an empty string if fname is illegal or file not found. |
|
27 | Return an empty string if fname is illegal or file not found. | |
28 |
|
28 | |||
29 | """ |
|
29 | """ | |
30 | parts = fname.split('/') |
|
30 | parts = fname.split('/') | |
31 | path = directory |
|
31 | path = directory | |
32 | for part in parts: |
|
32 | for part in parts: | |
33 | if (part in ('', os.curdir, os.pardir) or |
|
33 | if (part in ('', os.curdir, os.pardir) or | |
34 | os.sep in part or os.altsep is not None and os.altsep in part): |
|
34 | os.sep in part or os.altsep is not None and os.altsep in part): | |
35 | return "" |
|
35 | return "" | |
36 | path = os.path.join(path, part) |
|
36 | path = os.path.join(path, part) | |
37 | try: |
|
37 | try: | |
38 | os.stat(path) |
|
38 | os.stat(path) | |
39 | ct = mimetypes.guess_type(path)[0] or "text/plain" |
|
39 | ct = mimetypes.guess_type(path)[0] or "text/plain" | |
40 | req.header([('Content-type', ct), |
|
40 | req.header([('Content-type', ct), | |
41 | ('Content-length', os.path.getsize(path))]) |
|
41 | ('Content-length', str(os.path.getsize(path)))]) | |
42 | return file(path, 'rb').read() |
|
42 | return file(path, 'rb').read() | |
43 | except (TypeError, OSError): |
|
43 | except (TypeError, OSError): | |
44 | # illegal fname or unreadable file |
|
44 | # illegal fname or unreadable file | |
45 | return "" |
|
45 | return "" | |
46 |
|
46 | |||
47 | def style_map(templatepath, style): |
|
47 | def style_map(templatepath, style): | |
48 | """Return path to mapfile for a given style. |
|
48 | """Return path to mapfile for a given style. | |
49 |
|
49 | |||
50 | Searches mapfile in the following locations: |
|
50 | Searches mapfile in the following locations: | |
51 | 1. templatepath/style/map |
|
51 | 1. templatepath/style/map | |
52 | 2. templatepath/map-style |
|
52 | 2. templatepath/map-style | |
53 | 3. templatepath/map |
|
53 | 3. templatepath/map | |
54 | """ |
|
54 | """ | |
55 | locations = style and [os.path.join(style, "map"), "map-"+style] or [] |
|
55 | locations = style and [os.path.join(style, "map"), "map-"+style] or [] | |
56 | locations.append("map") |
|
56 | locations.append("map") | |
57 | for location in locations: |
|
57 | for location in locations: | |
58 | mapfile = os.path.join(templatepath, location) |
|
58 | mapfile = os.path.join(templatepath, location) | |
59 | if os.path.isfile(mapfile): |
|
59 | if os.path.isfile(mapfile): | |
60 | return mapfile |
|
60 | return mapfile | |
61 | raise RuntimeError("No hgweb templates found in %r" % templatepath) |
|
61 | raise RuntimeError("No hgweb templates found in %r" % templatepath) | |
62 |
|
62 |
General Comments 0
You need to be logged in to leave comments.
Login now