Mercurial > public > mercurial-scm > hg
diff mercurial/hgweb/hgwebdir_mod.py @ 2356:2db831b33e8f
Final stage of the hgweb split up.
hgweb and hgwebdir now have their own modules.
author | Eric Hopper <hopper@omnifarious.org> |
---|---|
date | Wed, 31 May 2006 10:42:44 -0700 |
parents | mercurial/hgweb/__init__.py@eb08fb4d41e1 |
children | 8819fc1dcf4b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial/hgweb/hgwebdir_mod.py Wed May 31 10:42:44 2006 -0700 @@ -0,0 +1,152 @@ +# hgweb.py - web interface to a mercurial repository +# +# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> +# Copyright 2005 Matt Mackall <mpm@selenic.com> +# +# This software may be used and distributed according to the terms +# of the GNU General Public License, incorporated herein by reference. + +import os +from mercurial.demandload import demandload +demandload(globals(), "ConfigParser") +demandload(globals(), "mercurial:ui,hg,util,templater") +demandload(globals(), "mercurial.hgweb.request:hgrequest") +from mercurial.i18n import gettext as _ + +# This is a stopgap +class hgwebdir(object): + def __init__(self, config): + def cleannames(items): + return [(name.strip(os.sep), path) for name, path in items] + + self.motd = "" + self.repos_sorted = ('name', False) + if isinstance(config, (list, tuple)): + self.repos = cleannames(config) + self.repos_sorted = ('', False) + elif isinstance(config, dict): + self.repos = cleannames(config.items()) + self.repos.sort() + else: + cp = ConfigParser.SafeConfigParser() + cp.read(config) + self.repos = [] + if cp.has_section('web') and cp.has_option('web', 'motd'): + self.motd = cp.get('web', 'motd') + if cp.has_section('paths'): + self.repos.extend(cleannames(cp.items('paths'))) + if cp.has_section('collections'): + for prefix, root in cp.items('collections'): + for path in util.walkrepos(root): + repo = os.path.normpath(path) + name = repo + if name.startswith(prefix): + name = name[len(prefix):] + self.repos.append((name.lstrip(os.sep), repo)) + self.repos.sort() + + def run(self, req=hgrequest()): + def header(**map): + yield tmpl("header", **map) + + def footer(**map): + yield tmpl("footer", motd=self.motd, **map) + + m = os.path.join(templater.templatepath(), "map") + tmpl = templater.templater(m, templater.common_filters, + defaults={"header": header, + "footer": footer}) + + def archivelist(ui, nodeid, url): + for i in ['zip', 'gz', 'bz2']: + if ui.configbool("web", "allow" + i, False): + yield {"type" : i, "node": nodeid, "url": url} + + def entries(sortcolumn="", descending=False, **map): + rows = [] + parity = 0 + for name, path in self.repos: + u = ui.ui() + try: + u.readconfig(os.path.join(path, '.hg', 'hgrc')) + except IOError: + pass + get = u.config + + url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name]) + .replace("//", "/")) + + # update time with local timezone + try: + d = (get_mtime(path), util.makedate()[1]) + except OSError: + continue + + contact = (get("ui", "username") or # preferred + get("web", "contact") or # deprecated + get("web", "author", "")) # also + description = get("web", "description", "") + name = get("web", "name", name) + row = dict(contact=contact or "unknown", + contact_sort=contact.upper() or "unknown", + name=name, + name_sort=name, + url=url, + description=description or "unknown", + description_sort=description.upper() or "unknown", + lastchange=d, + lastchange_sort=d[1]-d[0], + archives=archivelist(u, "tip", url)) + if (not sortcolumn + or (sortcolumn, descending) == self.repos_sorted): + # fast path for unsorted output + row['parity'] = parity + parity = 1 - parity + yield row + else: + rows.append((row["%s_sort" % sortcolumn], row)) + if rows: + rows.sort() + if descending: + rows.reverse() + for key, row in rows: + row['parity'] = parity + parity = 1 - parity + yield row + + virtual = req.env.get("PATH_INFO", "").strip('/') + if virtual: + real = dict(self.repos).get(virtual) + if real: + try: + hgweb(real).run(req) + except IOError, inst: + req.write(tmpl("error", error=inst.strerror)) + except hg.RepoError, inst: + req.write(tmpl("error", error=str(inst))) + else: + req.write(tmpl("notfound", repo=virtual)) + else: + if req.form.has_key('static'): + static = os.path.join(templater.templatepath(), "static") + fname = req.form['static'][0] + req.write(staticfile(static, fname) + or tmpl("error", error="%r not found" % fname)) + else: + sortable = ["name", "description", "contact", "lastchange"] + sortcolumn, descending = self.repos_sorted + if req.form.has_key('sort'): + sortcolumn = req.form['sort'][0] + descending = sortcolumn.startswith('-') + if descending: + sortcolumn = sortcolumn[1:] + if sortcolumn not in sortable: + sortcolumn = "" + + sort = [("sort_%s" % column, + "%s%s" % ((not descending and column == sortcolumn) + and "-" or "", column)) + for column in sortable] + req.write(tmpl("index", entries=entries, + sortcolumn=sortcolumn, descending=descending, + **dict(sort)))