mercurial/hgweb/common.py
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
Tue, 13 Feb 2007 10:01:44 -0200
changeset 4079 40c9710e8182
parent 3853 c0b449154a90
child 3877 abaee83ce0a6
permissions -rw-r--r--
Pass a ui from create_server to hgwebdir and a repo from hgwebdir to hgweb This allows repo pages to respect hg serve --webdir-conf <file> --style=gitweb (part of issue253). Since we're creating a ui object anyway, use it as the parentui of the ui objects created for every repo entry. This has the unintended side-effect that --name=foo on the command line will set the name of all repos. If one of the repos being served has a .hg/hgrc owned by a user that is not trusted, hg will now print the "Not trusting file..." warning when reading it. This is consistent with the behaviour from a hg serve from inside the repo.

# hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod
#
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
# Copyright 2005, 2006 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, mimetypes
import os.path

def get_mtime(repo_path):
    store_path = os.path.join(repo_path, ".hg")
    if not os.path.isdir(os.path.join(store_path, "data")):
        store_path = os.path.join(store_path, "store")
    cl_path = os.path.join(store_path, "00changelog.i")
    if os.path.exists(cl_path):
        return os.stat(cl_path).st_mtime
    else:
        return os.stat(store_path).st_mtime

def staticfile(directory, fname, req):
    """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"
        req.header([('Content-type', ct),
                    ('Content-length', os.path.getsize(path))])
        return file(path, 'rb').read()
    except (TypeError, OSError):
        # illegal fname or unreadable file
        return ""

def style_map(templatepath, style):
    """Return path to mapfile for a given style.

    Searches mapfile in the following locations:
    1. templatepath/style/map
    2. templatepath/map-style
    3. templatepath/map
    """
    locations = style and [os.path.join(style, "map"), "map-"+style] or []
    locations.append("map")
    for location in locations:
        mapfile = os.path.join(templatepath, location)
        if os.path.isfile(mapfile):
            return mapfile
    raise RuntimeError("No hgweb templates found in %r" % templatepath)