comparison mercurial/hgweb/hgweb_mod.py @ 4461:12e4d9524951

hgweb: use generator to count parity of horizontal stripes for easier reading. - use web.stripes in all places and consistently - start with parity0 for lists generated in reverse (e.g. changelog)
author Thomas Arendsen Hein <thomas@intevation.de>
date Tue, 29 May 2007 16:42:05 +0200
parents e19d9b1223ee
children 8af65bc092b0
comparison
equal deleted inserted replaced
4460:3e679426dd7f 4461:12e4d9524951
10 import tempfile, urllib, bz2 10 import tempfile, urllib, bz2
11 from mercurial.node import * 11 from mercurial.node import *
12 from mercurial.i18n import gettext as _ 12 from mercurial.i18n import gettext as _
13 from mercurial import mdiff, ui, hg, util, archival, streamclone, patch 13 from mercurial import mdiff, ui, hg, util, archival, streamclone, patch
14 from mercurial import revlog, templater 14 from mercurial import revlog, templater
15 from common import get_mtime, staticfile, style_map 15 from common import get_mtime, staticfile, style_map, paritygen
16 16
17 def _up(p): 17 def _up(p):
18 if p[0] != "/": 18 if p[0] != "/":
19 p = "/" + p 19 p = "/" + p
20 if p[-1] == "/": 20 if p[-1] == "/":
145 if t and t[-1] != os.sep: 145 if t and t[-1] != os.sep:
146 t += os.sep 146 t += os.sep
147 l += [x for x in files if x.startswith(t)] 147 l += [x for x in files if x.startswith(t)]
148 return l 148 return l
149 149
150 parity = [0] 150 parity = paritygen(self.stripecount)
151 def diffblock(diff, f, fn): 151 def diffblock(diff, f, fn):
152 yield self.t("diffblock", 152 yield self.t("diffblock",
153 lines=prettyprintlines(diff), 153 lines=prettyprintlines(diff),
154 parity=parity[0], 154 parity=parity.next(),
155 file=f, 155 file=f,
156 filenode=hex(fn or nullid)) 156 filenode=hex(fn or nullid))
157 parity[0] = 1 - parity[0]
158 157
159 def prettyprintlines(diff): 158 def prettyprintlines(diff):
160 for l in diff.splitlines(1): 159 for l in diff.splitlines(1):
161 if l.startswith('+'): 160 if l.startswith('+'):
162 yield self.t("difflineplus", line=l) 161 yield self.t("difflineplus", line=l)
195 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, 194 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
196 opts=diffopts), f, tn) 195 opts=diffopts), f, tn)
197 196
198 def changelog(self, ctx, shortlog=False): 197 def changelog(self, ctx, shortlog=False):
199 def changelist(**map): 198 def changelist(**map):
200 parity = (start - end) & 1
201 cl = self.repo.changelog 199 cl = self.repo.changelog
202 l = [] # build a list in forward order for efficiency 200 l = [] # build a list in forward order for efficiency
203 for i in xrange(start, end): 201 for i in xrange(start, end):
204 ctx = self.repo.changectx(i) 202 ctx = self.repo.changectx(i)
205 n = ctx.node() 203 n = ctx.node()
206 204
207 l.insert(0, {"parity": parity, 205 l.insert(0, {"parity": parity.next(),
208 "author": ctx.user(), 206 "author": ctx.user(),
209 "parent": self.siblings(ctx.parents(), i - 1), 207 "parent": self.siblings(ctx.parents(), i - 1),
210 "child": self.siblings(ctx.children(), i + 1), 208 "child": self.siblings(ctx.children(), i + 1),
211 "changelogtag": self.showtag("changelogtag",n), 209 "changelogtag": self.showtag("changelogtag",n),
212 "desc": ctx.description(), 210 "desc": ctx.description(),
213 "date": ctx.date(), 211 "date": ctx.date(),
214 "files": self.listfilediffs(ctx.files(), n), 212 "files": self.listfilediffs(ctx.files(), n),
215 "rev": i, 213 "rev": i,
216 "node": hex(n)}) 214 "node": hex(n)})
217 parity = 1 - parity
218 215
219 for e in l: 216 for e in l:
220 yield e 217 yield e
221 218
222 maxchanges = shortlog and self.maxshortchanges or self.maxchanges 219 maxchanges = shortlog and self.maxshortchanges or self.maxchanges
224 count = cl.count() 221 count = cl.count()
225 pos = ctx.rev() 222 pos = ctx.rev()
226 start = max(0, pos - maxchanges + 1) 223 start = max(0, pos - maxchanges + 1)
227 end = min(count, start + maxchanges) 224 end = min(count, start + maxchanges)
228 pos = end - 1 225 pos = end - 1
226 parity = paritygen(self.stripecount, offset=start-end)
229 227
230 changenav = revnavgen(pos, maxchanges, count, self.repo.changectx) 228 changenav = revnavgen(pos, maxchanges, count, self.repo.changectx)
231 229
232 yield self.t(shortlog and 'shortlog' or 'changelog', 230 yield self.t(shortlog and 'shortlog' or 'changelog',
233 changenav=changenav, 231 changenav=changenav,
265 263
266 count += 1 264 count += 1
267 n = ctx.node() 265 n = ctx.node()
268 266
269 yield self.t('searchentry', 267 yield self.t('searchentry',
270 parity=self.stripes(count), 268 parity=parity.next(),
271 author=ctx.user(), 269 author=ctx.user(),
272 parent=self.siblings(ctx.parents()), 270 parent=self.siblings(ctx.parents()),
273 child=self.siblings(ctx.children()), 271 child=self.siblings(ctx.children()),
274 changelogtag=self.showtag("changelogtag",n), 272 changelogtag=self.showtag("changelogtag",n),
275 desc=ctx.description(), 273 desc=ctx.description(),
280 278
281 if count >= self.maxchanges: 279 if count >= self.maxchanges:
282 break 280 break
283 281
284 cl = self.repo.changelog 282 cl = self.repo.changelog
283 parity = paritygen(self.stripecount)
285 284
286 yield self.t('search', 285 yield self.t('search',
287 query=query, 286 query=query,
288 node=hex(cl.tip()), 287 node=hex(cl.tip()),
289 entries=changelist) 288 entries=changelist)
292 n = ctx.node() 291 n = ctx.node()
293 parents = ctx.parents() 292 parents = ctx.parents()
294 p1 = parents[0].node() 293 p1 = parents[0].node()
295 294
296 files = [] 295 files = []
297 parity = 0 296 parity = paritygen(self.stripecount)
298 for f in ctx.files(): 297 for f in ctx.files():
299 files.append(self.t("filenodelink", 298 files.append(self.t("filenodelink",
300 node=hex(n), file=f, 299 node=hex(n), file=f,
301 parity=parity)) 300 parity=parity.next()))
302 parity = 1 - parity
303 301
304 def diff(**map): 302 def diff(**map):
305 yield self.diff(p1, n, None) 303 yield self.diff(p1, n, None)
306 304
307 yield self.t('changeset', 305 yield self.t('changeset',
324 pagelen = self.maxshortchanges 322 pagelen = self.maxshortchanges
325 pos = fctx.filerev() 323 pos = fctx.filerev()
326 start = max(0, pos - pagelen + 1) 324 start = max(0, pos - pagelen + 1)
327 end = min(count, start + pagelen) 325 end = min(count, start + pagelen)
328 pos = end - 1 326 pos = end - 1
327 parity = paritygen(self.stripecount, offset=start-end)
329 328
330 def entries(**map): 329 def entries(**map):
331 l = [] 330 l = []
332 parity = (count - 1) & 1
333 331
334 for i in xrange(start, end): 332 for i in xrange(start, end):
335 ctx = fctx.filectx(i) 333 ctx = fctx.filectx(i)
336 n = fl.node(i) 334 n = fl.node(i)
337 335
338 l.insert(0, {"parity": parity, 336 l.insert(0, {"parity": parity.next(),
339 "filerev": i, 337 "filerev": i,
340 "file": f, 338 "file": f,
341 "node": hex(ctx.node()), 339 "node": hex(ctx.node()),
342 "author": ctx.user(), 340 "author": ctx.user(),
343 "date": ctx.date(), 341 "date": ctx.date(),
344 "rename": self.renamelink(fl, n), 342 "rename": self.renamelink(fl, n),
345 "parent": self.siblings(fctx.parents()), 343 "parent": self.siblings(fctx.parents()),
346 "child": self.siblings(fctx.children()), 344 "child": self.siblings(fctx.children()),
347 "desc": ctx.description()}) 345 "desc": ctx.description()})
348 parity = 1 - parity
349 346
350 for e in l: 347 for e in l:
351 yield e 348 yield e
352 349
353 nodefunc = lambda x: fctx.filectx(fileid=x) 350 nodefunc = lambda x: fctx.filectx(fileid=x)
358 def filerevision(self, fctx): 355 def filerevision(self, fctx):
359 f = fctx.path() 356 f = fctx.path()
360 text = fctx.data() 357 text = fctx.data()
361 fl = fctx.filelog() 358 fl = fctx.filelog()
362 n = fctx.filenode() 359 n = fctx.filenode()
360 parity = paritygen(self.stripecount)
363 361
364 mt = mimetypes.guess_type(f)[0] 362 mt = mimetypes.guess_type(f)[0]
365 rawtext = text 363 rawtext = text
366 if util.binary(text): 364 if util.binary(text):
367 mt = mt or 'application/octet-stream' 365 mt = mt or 'application/octet-stream'
370 368
371 def lines(): 369 def lines():
372 for l, t in enumerate(text.splitlines(1)): 370 for l, t in enumerate(text.splitlines(1)):
373 yield {"line": t, 371 yield {"line": t,
374 "linenumber": "% 6d" % (l + 1), 372 "linenumber": "% 6d" % (l + 1),
375 "parity": self.stripes(l)} 373 "parity": parity.next()}
376 374
377 yield self.t("filerevision", 375 yield self.t("filerevision",
378 file=f, 376 file=f,
379 path=_up(f), 377 path=_up(f),
380 text=lines(), 378 text=lines(),
392 390
393 def fileannotate(self, fctx): 391 def fileannotate(self, fctx):
394 f = fctx.path() 392 f = fctx.path()
395 n = fctx.filenode() 393 n = fctx.filenode()
396 fl = fctx.filelog() 394 fl = fctx.filelog()
395 parity = paritygen(self.stripecount)
397 396
398 def annotate(**map): 397 def annotate(**map):
399 parity = 0
400 last = None 398 last = None
401 for f, l in fctx.annotate(follow=True): 399 for f, l in fctx.annotate(follow=True):
402 fnode = f.filenode() 400 fnode = f.filenode()
403 name = self.repo.ui.shortuser(f.user()) 401 name = self.repo.ui.shortuser(f.user())
404 402
405 if last != fnode: 403 if last != fnode:
406 parity = 1 - parity
407 last = fnode 404 last = fnode
408 405
409 yield {"parity": parity, 406 yield {"parity": parity.next(),
410 "node": hex(f.node()), 407 "node": hex(f.node()),
411 "rev": f.rev(), 408 "rev": f.rev(),
412 "author": name, 409 "author": name,
413 "file": f.path(), 410 "file": f.path(),
414 "line": l} 411 "line": l}
430 def manifest(self, ctx, path): 427 def manifest(self, ctx, path):
431 mf = ctx.manifest() 428 mf = ctx.manifest()
432 node = ctx.node() 429 node = ctx.node()
433 430
434 files = {} 431 files = {}
432 parity = paritygen(self.stripecount)
435 433
436 if path and path[-1] != "/": 434 if path and path[-1] != "/":
437 path += "/" 435 path += "/"
438 l = len(path) 436 l = len(path)
439 abspath = "/" + path 437 abspath = "/" + path
448 else: 446 else:
449 short = os.path.basename(remain) 447 short = os.path.basename(remain)
450 files[short] = (f, n) 448 files[short] = (f, n)
451 449
452 def filelist(**map): 450 def filelist(**map):
453 parity = 0
454 fl = files.keys() 451 fl = files.keys()
455 fl.sort() 452 fl.sort()
456 for f in fl: 453 for f in fl:
457 full, fnode = files[f] 454 full, fnode = files[f]
458 if not fnode: 455 if not fnode:
459 continue 456 continue
460 457
461 yield {"file": full, 458 yield {"file": full,
462 "parity": self.stripes(parity), 459 "parity": parity.next(),
463 "basename": f, 460 "basename": f,
464 "size": ctx.filectx(full).size(), 461 "size": ctx.filectx(full).size(),
465 "permissions": mf.execf(full)} 462 "permissions": mf.execf(full)}
466 parity += 1
467 463
468 def dirlist(**map): 464 def dirlist(**map):
469 parity = 0
470 fl = files.keys() 465 fl = files.keys()
471 fl.sort() 466 fl.sort()
472 for f in fl: 467 for f in fl:
473 full, fnode = files[f] 468 full, fnode = files[f]
474 if fnode: 469 if fnode:
475 continue 470 continue
476 471
477 yield {"parity": self.stripes(parity), 472 yield {"parity": parity.next(),
478 "path": os.path.join(abspath, f), 473 "path": os.path.join(abspath, f),
479 "basename": f[:-1]} 474 "basename": f[:-1]}
480 parity += 1
481 475
482 yield self.t("manifest", 476 yield self.t("manifest",
483 rev=ctx.rev(), 477 rev=ctx.rev(),
484 node=hex(node), 478 node=hex(node),
485 path=abspath, 479 path=abspath,
486 up=_up(abspath), 480 up=_up(abspath),
487 upparity=self.stripes(0), 481 upparity=parity.next(),
488 fentries=filelist, 482 fentries=filelist,
489 dentries=dirlist, 483 dentries=dirlist,
490 archives=self.archivelist(hex(node))) 484 archives=self.archivelist(hex(node)))
491 485
492 def tags(self): 486 def tags(self):
493 i = self.repo.tagslist() 487 i = self.repo.tagslist()
494 i.reverse() 488 i.reverse()
489 parity = paritygen(self.stripecount)
495 490
496 def entries(notip=False, **map): 491 def entries(notip=False, **map):
497 parity = 0
498 for k, n in i: 492 for k, n in i:
499 if notip and k == "tip": 493 if notip and k == "tip":
500 continue 494 continue
501 yield {"parity": self.stripes(parity), 495 yield {"parity": parity.next(),
502 "tag": k, 496 "tag": k,
503 "date": self.repo.changectx(n).date(), 497 "date": self.repo.changectx(n).date(),
504 "node": hex(n)} 498 "node": hex(n)}
505 parity += 1
506 499
507 yield self.t("tags", 500 yield self.t("tags",
508 node=hex(self.repo.changelog.tip()), 501 node=hex(self.repo.changelog.tip()),
509 entries=lambda **x: entries(False, **x), 502 entries=lambda **x: entries(False, **x),
510 entriesnotip=lambda **x: entries(True, **x)) 503 entriesnotip=lambda **x: entries(True, **x))
512 def summary(self): 505 def summary(self):
513 i = self.repo.tagslist() 506 i = self.repo.tagslist()
514 i.reverse() 507 i.reverse()
515 508
516 def tagentries(**map): 509 def tagentries(**map):
517 parity = 0 510 parity = paritygen(self.stripecount)
518 count = 0 511 count = 0
519 for k, n in i: 512 for k, n in i:
520 if k == "tip": # skip tip 513 if k == "tip": # skip tip
521 continue; 514 continue;
522 515
523 count += 1 516 count += 1
524 if count > 10: # limit to 10 tags 517 if count > 10: # limit to 10 tags
525 break; 518 break;
526 519
527 yield self.t("tagentry", 520 yield self.t("tagentry",
528 parity=self.stripes(parity), 521 parity=parity.next(),
529 tag=k, 522 tag=k,
530 node=hex(n), 523 node=hex(n),
531 date=self.repo.changectx(n).date()) 524 date=self.repo.changectx(n).date())
532 parity += 1
533 525
534 526
535 def branches(**map): 527 def branches(**map):
536 parity = 0 528 parity = paritygen(self.stripecount)
537 529
538 b = self.repo.branchtags() 530 b = self.repo.branchtags()
539 l = [(-self.repo.changelog.rev(n), n, t) for t, n in b.items()] 531 l = [(-self.repo.changelog.rev(n), n, t) for t, n in b.items()]
540 l.sort() 532 l.sort()
541 533
542 for r,n,t in l: 534 for r,n,t in l:
543 ctx = self.repo.changectx(n) 535 ctx = self.repo.changectx(n)
544 536
545 yield {'parity': self.stripes(parity), 537 yield {'parity': parity.next(),
546 'branch': t, 538 'branch': t,
547 'node': hex(n), 539 'node': hex(n),
548 'date': ctx.date()} 540 'date': ctx.date()}
549 parity += 1
550 541
551 def changelist(**map): 542 def changelist(**map):
552 parity = 0 543 parity = paritygen(self.stripecount, offset=start-end)
553 l = [] # build a list in forward order for efficiency 544 l = [] # build a list in forward order for efficiency
554 for i in xrange(start, end): 545 for i in xrange(start, end):
555 ctx = self.repo.changectx(i) 546 ctx = self.repo.changectx(i)
556 hn = hex(ctx.node()) 547 hn = hex(ctx.node())
557 548
558 l.insert(0, self.t( 549 l.insert(0, self.t(
559 'shortlogentry', 550 'shortlogentry',
560 parity=parity, 551 parity=parity.next(),
561 author=ctx.user(), 552 author=ctx.user(),
562 desc=ctx.description(), 553 desc=ctx.description(),
563 date=ctx.date(), 554 date=ctx.date(),
564 rev=i, 555 rev=i,
565 node=hn)) 556 node=hn))
566 parity = 1 - parity
567 557
568 yield l 558 yield l
569 559
570 cl = self.repo.changelog 560 cl = self.repo.changelog
571 count = cl.count() 561 count = cl.count()
843 fctx = ctx.filectx(path) 833 fctx = ctx.filectx(path)
844 except hg.RepoError: 834 except hg.RepoError:
845 fctx = self.repo.filectx(path, fileid=changeid) 835 fctx = self.repo.filectx(path, fileid=changeid)
846 836
847 return fctx 837 return fctx
848
849 def stripes(self, parity):
850 "make horizontal stripes for easier reading"
851 if self.stripecount:
852 return (1 + parity / self.stripecount) & 1
853 else:
854 return 0
855 838
856 def do_log(self, req): 839 def do_log(self, req):
857 if req.form.has_key('file') and req.form['file'][0]: 840 if req.form.has_key('file') and req.form['file'][0]:
858 self.do_filelog(req) 841 self.do_filelog(req)
859 else: 842 else: