mercurial/hgweb/protocol.py
author Jonathan Nieder <jrnieder@gmail.com>
Thu, 03 Feb 2011 00:27:44 -0600
branchstable
changeset 13340 02aa06a021a0
parent 12704 ca6e2adc3e4d
child 13721 3458c15ab2f0
permissions -rw-r--r--
backout: make help more explicit about what backout does The help for backout explains: The backout command merges the reverse effect of the reverted changeset into the working directory. Unfortunately, that does not make it obvious to a newcomer what the backout command does. Since it performs a 3-way merge, what is the common ancestor? Will the result be automatically committed? What is this reverted changeset --- is it the rev passed with -r on the command line or its inverse? So try to clarify the description, avoiding jargon and being explicit about what happens from the user's perspective. Thanks to Gilles Moris, Steve Borho, Kevin Bullock, and timeless for help.

#
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

import cStringIO, zlib, sys, urllib
from mercurial import util, wireproto
from common import HTTP_OK

HGTYPE = 'application/mercurial-0.1'

class webproto(object):
    def __init__(self, req):
        self.req = req
        self.response = ''
    def getargs(self, args):
        data = {}
        keys = args.split()
        for k in keys:
            if k == '*':
                star = {}
                for key in self.req.form.keys():
                    if key not in keys:
                        star[key] = self.req.form[key][0]
                data['*'] = star
            else:
                data[k] = self.req.form[k][0]
        return [data[k] for k in keys]
    def getfile(self, fp):
        length = int(self.req.env['CONTENT_LENGTH'])
        for s in util.filechunkiter(self.req, limit=length):
            fp.write(s)
    def redirect(self):
        self.oldio = sys.stdout, sys.stderr
        sys.stderr = sys.stdout = cStringIO.StringIO()
    def groupchunks(self, cg):
        z = zlib.compressobj()
        while 1:
            chunk = cg.read(4096)
            if not chunk:
                break
            yield z.compress(chunk)
        yield z.flush()
    def _client(self):
        return 'remote:%s:%s:%s' % (
            self.req.env.get('wsgi.url_scheme') or 'http',
            urllib.quote(self.req.env.get('REMOTE_HOST', '')),
            urllib.quote(self.req.env.get('REMOTE_USER', '')))

def iscmd(cmd):
    return cmd in wireproto.commands

def call(repo, req, cmd):
    p = webproto(req)
    rsp = wireproto.dispatch(repo, p, cmd)
    if isinstance(rsp, str):
        req.respond(HTTP_OK, HGTYPE, length=len(rsp))
        return [rsp]
    elif isinstance(rsp, wireproto.streamres):
        req.respond(HTTP_OK, HGTYPE)
        return rsp.gen
    elif isinstance(rsp, wireproto.pushres):
        val = sys.stdout.getvalue()
        sys.stdout, sys.stderr = p.oldio
        req.respond(HTTP_OK, HGTYPE)
        return ['%d\n%s' % (rsp.res, val)]
    elif isinstance(rsp, wireproto.pusherr):
        # drain the incoming bundle
        req.drain()
        sys.stdout, sys.stderr = p.oldio
        rsp = '0\n%s\n' % rsp.res
        req.respond(HTTP_OK, HGTYPE, length=len(rsp))
        return [rsp]