##// END OF EJS Templates
hgweb: add a "URL breadcrumb" to the index and repository pages...
hgweb: add a "URL breadcrumb" to the index and repository pages The purpose of this change is to make it much easier to navigate up the repository tree when the hg web server is used to serve more than one repository. A "URL breadcrumb" is a path where each of the path items can be clicked to go to the corresponding path page. This lets you go up the folder hierarchy very quickly. For example, when showing the list of repositories in http://myserver/myteams/myprojects, the following "breadcrumb" will be shown: Mercurial > myteams > myprojects Clicking on "myprojects" reloads the page. Clicking on "myteams" goes up one folder. Clicking on the leftmost "Mercurial" goes to the server root. This "breadcrumb" also appears on all repository pages. For example on the summary page of the repository at http://myserver/myteams/myprojects/myrepo the following will be shown: Mercurial > myteams > myprojects > myrepo / summary This change has been applied to all templates that already had a link to the main repository page (i.e. gitweb, monoblue, paper and coal) plus to the index page of the spartan template. In order to make the breadcumb links stand out the some of the template styles have been customized.

File last commit:

r15017:f4522df3 default
r18258:bebb05a7 default
Show More
protocol.py
97 lines | 3.1 KiB | text/x-python | PythonLexer
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598 #
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598
Idan Kamara
ui: use I/O descriptors internally...
r14614 import cgi, cStringIO, zlib, urllib
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 from mercurial import util, wireproto
from common import HTTP_OK
Dirkjan Ochtman
hgweb: explicitly check if requested command exists
r5963
Dirkjan Ochtman
hgweb: explicit response status
r5993 HGTYPE = 'application/mercurial-0.1'
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 HGERRTYPE = 'application/hg-error'
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595
class webproto(object):
Idan Kamara
ui: use I/O descriptors internally...
r14614 def __init__(self, req, ui):
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 self.req = req
self.response = ''
Idan Kamara
ui: use I/O descriptors internally...
r14614 self.ui = ui
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 def getargs(self, args):
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 knownargs = self._args()
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 data = {}
keys = args.split()
for k in keys:
if k == '*':
star = {}
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 for key in knownargs.keys():
Peter Arrenbrecht
wireproto: fix handling of '*' args for HTTP and SSH
r13721 if key != 'cmd' and key not in keys:
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 star[key] = knownargs[key][0]
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 data['*'] = star
else:
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 data[k] = knownargs[k][0]
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 return [data[k] for k in keys]
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 def _args(self):
args = self.req.form.copy()
chunks = []
Matt Mackall
http: minor tweaks to long arg handling...
r14094 i = 1
Martin Geisler
check-code: flag 0/1 used as constant Boolean expression
r14494 while True:
Matt Mackall
http: minor tweaks to long arg handling...
r14094 h = self.req.env.get('HTTP_X_HGARG_' + str(i))
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 if h is None:
break
chunks += [h]
Matt Mackall
http: minor tweaks to long arg handling...
r14094 i += 1
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
return args
Dirkjan Ochtman
protocol: shuffle server methods to group send methods
r11621 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):
Idan Kamara
ui: use I/O descriptors internally...
r14614 self.oldio = self.ui.fout, self.ui.ferr
self.ui.ferr = self.ui.fout = cStringIO.StringIO()
def restore(self):
val = self.ui.fout.getvalue()
self.ui.ferr, self.ui.fout = self.oldio
return val
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 def groupchunks(self, cg):
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 z = zlib.compressobj()
Martin Geisler
check-code: flag 0/1 used as constant Boolean expression
r14494 while True:
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 chunk = cg.read(4096)
if not chunk:
break
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 yield z.compress(chunk)
yield z.flush()
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 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):
Idan Kamara
ui: use I/O descriptors internally...
r14614 p = webproto(req, repo.ui)
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 rsp = wireproto.dispatch(repo, p, cmd)
Dirkjan Ochtman
protocol: use generators instead of req.write() for hgweb stream responses
r11626 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):
Idan Kamara
ui: use I/O descriptors internally...
r14614 val = p.restore()
Dirkjan Ochtman
protocol: use generators instead of req.write() for hgweb stream responses
r11626 req.respond(HTTP_OK, HGTYPE)
return ['%d\n%s' % (rsp.res, val)]
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 elif isinstance(rsp, wireproto.pusherr):
Benoit Boissinot
wireproto/http: drain the incoming bundle in case of errors
r12704 # drain the incoming bundle
req.drain()
Idan Kamara
ui: use I/O descriptors internally...
r14614 p.restore()
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 rsp = '0\n%s\n' % rsp.res
req.respond(HTTP_OK, HGTYPE, length=len(rsp))
return [rsp]
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 elif isinstance(rsp, wireproto.ooberror):
rsp = rsp.message
req.respond(HTTP_OK, HGERRTYPE, length=len(rsp))
return [rsp]