copy from mercurial/hgweb/__init__.py
copy to mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/__init__.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -6,17 +6,18 @@
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
-import os, cgi, sys
+import os
+import os.path
import mimetypes
from mercurial.demandload import demandload
-demandload(globals(), "time re socket zlib errno ConfigParser tempfile")
+demandload(globals(), "re zlib ConfigParser")
demandload(globals(), "mercurial:mdiff,ui,hg,util,archival,templater")
demandload(globals(), "mercurial.hgweb.request:hgrequest")
-demandload(globals(), "mercurial.hgweb.server:create_server")
+demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile")
from mercurial.node import *
from mercurial.i18n import gettext as _
-def up(p):
+def _up(p):
if p[0] != "/":
p = "/" + p
if p[-1] == "/":
@@ -26,38 +27,6 @@ def up(p):
return "/"
return up + "/"
-def get_mtime(repo_path):
- hg_path = os.path.join(repo_path, ".hg")
- cl_path = os.path.join(hg_path, "00changelog.i")
- if os.path.exists(os.path.join(cl_path)):
- return os.stat(cl_path).st_mtime
- else:
- return os.stat(hg_path).st_mtime
-
-def staticfile(directory, fname):
- """return a file inside directory with guessed content-type header
-
- fname always uses '/' as directory separator and isn't allowed to
- contain unusual path components.
- Content-type is guessed using the mimetypes module.
- Return an empty string if fname is illegal or file not found.
-
- """
- parts = fname.split('/')
- path = directory
- for part in parts:
- if (part in ('', os.curdir, os.pardir) or
- os.sep in part or os.altsep is not None and os.altsep in part):
- return ""
- path = os.path.join(path, part)
- try:
- os.stat(path)
- ct = mimetypes.guess_type(path)[0] or "text/plain"
- return "Content-type: %s\n\n%s" % (ct, file(path).read())
- except (TypeError, OSError):
- # illegal fname or unreadable file
- return ""
-
class hgweb(object):
def __init__(self, repo, name=None):
if type(repo) == type(""):
@@ -401,7 +370,7 @@ class hgweb(object):
yield self.t("filerevision",
file=f,
filenode=node,
- path=up(f),
+ path=_up(f),
text=lines(),
raw=rawtext,
mimetype=mt,
@@ -458,7 +427,7 @@ class hgweb(object):
file=f,
filenode=node,
annotate=annotate,
- path=up(f),
+ path=_up(f),
rev=changerev,
node=hex(cn),
manifest=hex(mfn),
@@ -534,7 +503,7 @@ class hgweb(object):
rev=rev,
node=hex(node),
path=path,
- up=up(path),
+ up=_up(path),
fentries=filelist,
dentries=dirlist,
archives=self.archivelist(hex(node)))
@@ -848,141 +817,3 @@ class hgweb(object):
else:
req.write(self.t("error"))
-
-# 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)))