Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/hgweb.py @ 941:4cf418c2a013
Add a multi-repository server
This merges a bunch of the ideas for a multi-repository CGI script and
simplifies things a bit.
It uses PATH_INFO so it generally wants paths of the form:
http://host/hg.cgi/virtualpath
This gets mapped via a simple config file to the real path. All info
about the repo is read from the repo's hgrc.
author | mpm@selenic.com |
---|---|
date | Fri, 19 Aug 2005 16:38:25 -0800 |
parents | 6b735e0ddd81 |
children | ffb0665028f0 |
comparison
equal
deleted
inserted
replaced
940:1300271ba8de | 941:4cf418c2a013 |
---|---|
112 return template(tmpl, self.filters, **m) | 112 return template(tmpl, self.filters, **m) |
113 | 113 |
114 def rfc822date(x): | 114 def rfc822date(x): |
115 return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(x)) | 115 return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(x)) |
116 | 116 |
117 common_filters = { | |
118 "escape": cgi.escape, | |
119 "age": age, | |
120 "date": (lambda x: time.asctime(time.gmtime(x))), | |
121 "addbreaks": nl2br, | |
122 "obfuscate": obfuscate, | |
123 "short": (lambda x: x[:12]), | |
124 "firstline": (lambda x: x.splitlines(1)[0]), | |
125 "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"), | |
126 "rfc822date": rfc822date, | |
127 } | |
128 | |
117 class hgweb: | 129 class hgweb: |
118 maxchanges = 10 | 130 maxchanges = 10 |
119 maxfiles = 10 | 131 maxfiles = 10 |
120 | 132 |
121 def __init__(self, path, name, templates = ""): | 133 def __init__(self, path, name=None, templates=""): |
122 self.templates = templates | 134 self.templates = templates |
123 self.reponame = name | 135 self.reponame = name |
124 self.path = path | 136 self.path = path |
125 self.mtime = -1 | 137 self.mtime = -1 |
126 self.viewonly = 0 | 138 self.viewonly = 0 |
127 | |
128 self.filters = { | |
129 "escape": cgi.escape, | |
130 "age": age, | |
131 "date": (lambda x: time.asctime(time.gmtime(x))), | |
132 "addbreaks": nl2br, | |
133 "obfuscate": obfuscate, | |
134 "short": (lambda x: x[:12]), | |
135 "firstline": (lambda x: x.splitlines(1)[0]), | |
136 "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"), | |
137 "rfc822date": rfc822date, | |
138 } | |
139 | 139 |
140 def refresh(self): | 140 def refresh(self): |
141 s = os.stat(os.path.join(self.path, ".hg", "00changelog.i")) | 141 s = os.stat(os.path.join(self.path, ".hg", "00changelog.i")) |
142 if s.st_mtime != self.mtime: | 142 if s.st_mtime != self.mtime: |
143 self.mtime = s.st_mtime | 143 self.mtime = s.st_mtime |
617 if "?" in uri: uri = uri.split("?")[0] | 617 if "?" in uri: uri = uri.split("?")[0] |
618 url = "http://%s%s%s" % (os.environ["SERVER_NAME"], port, uri) | 618 url = "http://%s%s%s" % (os.environ["SERVER_NAME"], port, uri) |
619 | 619 |
620 name = self.reponame or self.repo.ui.config("web", "name", os.getcwd()) | 620 name = self.reponame or self.repo.ui.config("web", "name", os.getcwd()) |
621 | 621 |
622 self.t = templater(m, self.filters, | 622 self.t = templater(m, common_filters, |
623 {"url":url, | 623 {"url":url, |
624 "repo":name, | 624 "repo":name, |
625 "header":header, | 625 "header":header, |
626 "footer":footer, | 626 "footer":footer, |
627 }) | 627 }) |
816 def server(path, name, templates, address, port, use_ipv6 = False, | 816 def server(path, name, templates, address, port, use_ipv6 = False, |
817 accesslog = sys.stdout, errorlog = sys.stderr): | 817 accesslog = sys.stdout, errorlog = sys.stderr): |
818 httpd = create_server(path, name, templates, address, port, use_ipv6, | 818 httpd = create_server(path, name, templates, address, port, use_ipv6, |
819 accesslog, errorlog) | 819 accesslog, errorlog) |
820 httpd.serve_forever() | 820 httpd.serve_forever() |
821 | |
822 # This is a stopgap | |
823 class hgwebdir: | |
824 def __init__(self, config): | |
825 self.cp = ConfigParser.SafeConfigParser() | |
826 self.cp.read(config) | |
827 | |
828 def run(self): | |
829 try: | |
830 virtual = os.environ["PATH_INFO"] | |
831 except: | |
832 virtual = "" | |
833 | |
834 if virtual: | |
835 real = self.cp.get("paths", virtual[1:]) | |
836 h = hgweb.hgweb(real) | |
837 h.run() | |
838 return | |
839 | |
840 def header(**map): | |
841 yield tmpl("header", **map) | |
842 | |
843 def footer(**map): | |
844 yield tmpl("footer", **map) | |
845 | |
846 templates = templatepath() | |
847 m = os.path.join(templates, "map") | |
848 tmpl = templater(m, common_filters, | |
849 {"header": header, "footer": footer}) | |
850 | |
851 def entries(**map): | |
852 parity = 0 | |
853 for v,r in self.cp.items("paths"): | |
854 cp2 = ConfigParser.SafeConfigParser() | |
855 cp2.read(os.path.join(r, ".hg", "hgrc")) | |
856 | |
857 def get(sec, val, default): | |
858 try: | |
859 return cp2.get(sec, val) | |
860 except: | |
861 return default | |
862 | |
863 yield tmpl("indexentry", | |
864 author = get("web", "author", "unknown"), | |
865 name = get("web", "name", v), | |
866 url = os.environ["REQUEST_URI"] + "/" + v, | |
867 parity = parity, | |
868 shortdesc = get("web", "description", "unknown"), | |
869 lastupdate = os.stat(os.path.join(r, ".hg", | |
870 "00changelog.d")).st_mtime) | |
871 | |
872 parity = 1 - parity | |
873 | |
874 write(tmpl("index", entries = entries)) |