Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/hgweb/hgwebdir_mod.py @ 16239:287f76b3f502
hgweb: support multi-level repository indexes by enabling descend and collapse
The descend option in hgweb can be used to display all reachable repositories
within a directory hierarchy if set to True. However, all reachable
repositories, regardless of their depth below the root of the hierarchy, are
then listed at the same level - expanded - in the hgweb interface. This patch
adds support for showing only each level of a directory hierarchy, with
subrepositories being shown alongside their parent repositories only at the
appropriate level (because there is no way to navigate to subrepositories from
within repositories), and the contents of directories hidden - collapsed -
behind a link for each directory. To enable this multi-level navigation, a new
option called collapse must be set to True when the descend option is set to
True.
author | Paul Boddie <paul@boddie.org.uk> |
---|---|
date | Sat, 18 Feb 2012 20:10:19 +0100 |
parents | a31b8e03af28 |
children | d94c470c3deb |
comparison
equal
deleted
inserted
replaced
16238:e8eecfe37d4e | 16239:287f76b3f502 |
---|---|
243 return archives | 243 return archives |
244 | 244 |
245 def rawentries(subdir="", **map): | 245 def rawentries(subdir="", **map): |
246 | 246 |
247 descend = self.ui.configbool('web', 'descend', True) | 247 descend = self.ui.configbool('web', 'descend', True) |
248 collapse = self.ui.configbool('web', 'collapse', False) | |
249 seenrepos = set() | |
250 seendirs = set() | |
248 for name, path in self.repos: | 251 for name, path in self.repos: |
249 | 252 |
250 if not name.startswith(subdir): | 253 if not name.startswith(subdir): |
251 continue | 254 continue |
252 name = name[len(subdir):] | 255 name = name[len(subdir):] |
253 if not descend and '/' in name: | 256 directory = False |
254 continue | 257 |
255 | 258 if '/' in name: |
256 u = self.ui.copy() | 259 if not descend: |
257 try: | 260 continue |
258 u.readconfig(os.path.join(path, '.hg', 'hgrc')) | 261 |
259 except Exception, e: | 262 nameparts = name.split('/') |
260 u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e)) | 263 rootname = nameparts[0] |
261 continue | 264 |
262 def get(section, name, default=None): | 265 if not collapse: |
263 return u.config(section, name, default, untrusted=True) | 266 pass |
264 | 267 elif rootname in seendirs: |
265 if u.configbool("web", "hidden", untrusted=True): | 268 continue |
266 continue | 269 elif rootname in seenrepos: |
267 | 270 pass |
268 if not self.read_allowed(u, req): | 271 else: |
269 continue | 272 directory = True |
273 name = rootname | |
274 | |
275 # redefine the path to refer to the directory | |
276 discarded = '/'.join(nameparts[1:]) | |
277 | |
278 # remove name parts plus accompanying slash | |
279 path = path[:-len(discarded) - 1] | |
270 | 280 |
271 parts = [name] | 281 parts = [name] |
272 if 'PATH_INFO' in req.env: | 282 if 'PATH_INFO' in req.env: |
273 parts.insert(0, req.env['PATH_INFO'].rstrip('/')) | 283 parts.insert(0, req.env['PATH_INFO'].rstrip('/')) |
274 if req.env['SCRIPT_NAME']: | 284 if req.env['SCRIPT_NAME']: |
275 parts.insert(0, req.env['SCRIPT_NAME']) | 285 parts.insert(0, req.env['SCRIPT_NAME']) |
276 url = re.sub(r'/+', '/', '/'.join(parts) + '/') | 286 url = re.sub(r'/+', '/', '/'.join(parts) + '/') |
287 | |
288 # show either a directory entry or a repository | |
289 if directory: | |
290 # get the directory's time information | |
291 try: | |
292 d = (get_mtime(path), util.makedate()[1]) | |
293 except OSError: | |
294 continue | |
295 | |
296 row = dict(contact="", | |
297 contact_sort="", | |
298 name=name, | |
299 name_sort=name, | |
300 url=url, | |
301 description="", | |
302 description_sort="", | |
303 lastchange=d, | |
304 lastchange_sort=d[1]-d[0], | |
305 archives=[]) | |
306 | |
307 seendirs.add(name) | |
308 yield row | |
309 continue | |
310 | |
311 u = self.ui.copy() | |
312 try: | |
313 u.readconfig(os.path.join(path, '.hg', 'hgrc')) | |
314 except Exception, e: | |
315 u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e)) | |
316 continue | |
317 def get(section, name, default=None): | |
318 return u.config(section, name, default, untrusted=True) | |
319 | |
320 if u.configbool("web", "hidden", untrusted=True): | |
321 continue | |
322 | |
323 if not self.read_allowed(u, req): | |
324 continue | |
277 | 325 |
278 # update time with local timezone | 326 # update time with local timezone |
279 try: | 327 try: |
280 r = hg.repository(self.ui, path) | 328 r = hg.repository(self.ui, path) |
281 except IOError: | 329 except IOError: |
300 description=description or "unknown", | 348 description=description or "unknown", |
301 description_sort=description.upper() or "unknown", | 349 description_sort=description.upper() or "unknown", |
302 lastchange=d, | 350 lastchange=d, |
303 lastchange_sort=d[1]-d[0], | 351 lastchange_sort=d[1]-d[0], |
304 archives=archivelist(u, "tip", url)) | 352 archives=archivelist(u, "tip", url)) |
353 | |
354 seenrepos.add(name) | |
305 yield row | 355 yield row |
306 | 356 |
307 sortdefault = None, False | 357 sortdefault = None, False |
308 def entries(sortcolumn="", descending=False, subdir="", **map): | 358 def entries(sortcolumn="", descending=False, subdir="", **map): |
309 rows = rawentries(subdir=subdir, **map) | 359 rows = rawentries(subdir=subdir, **map) |