# HG changeset patch # User Steve Losh # Date 1267579416 18000 # Node ID 36b37712c670f062502f4423bf35b19202ebc947 # Parent 256716e3a3d7a5c822d32531806b12ccb7238a19 Get a bare Cherrypy server up and running. diff -r 256716e3a3d7 -r 36b37712c670 review/web_templates/changeset.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/review/web_templates/changeset.html Tue Mar 02 20:23:36 2010 -0500 @@ -0,0 +1,135 @@ +$def with (rd, rcset) + +$ ctx = rd.target[rcset.node] +

Changeset ${ ctx.rev() }: ${ ctx.description() }

+ +$ review_level_comments = rcset.review_level_comments() +$for comment in review_level_comments: +
+
+
+ +
${ comment.message }
+
+
+ +
+

Add a comment on this changeset

+
+
+ + +
+
+ +
+
+
+ +

Files

+ +$for filename, diff in rcset.diffs().iteritems(): +
+
+    ↓ +

${ filename }

+
+ +
+ $ file_level_comments = rcset.file_level_comments(filename) + $for comment in file_level_comments: +
+
+ +
+
+ +
${ comment.message }
+
+
+ + +
+

Add a comment on this file

+
+
+ + +
+
+ +
+ +
+
+ +
+ + $ max_line = diff['max'] + $ content = diff['content'] + $ line_level_comments = rcset.line_level_comments(filename) + $ previous_n = -1 + $for n, line in content: + $if n - 1 > previous_n: + $ skipped_count = n - previous_n + $if previous_n == -1: + $ skipped_count -= 1 + + + + $ skipped_comments = filter(lambda c: max(c.lines) in range(previous_n + 1, n), line_level_comments) + $for comment in skipped_comments: + + $ kind = 'rem' if line[0] == '-' else 'add' if line[0] == '+' else 'con' + + + + $ line_comments = filter(lambda c: max(c.lines) == n, line_level_comments) + $for comment in line_comments: + + + + + $ previous_n = n + $if previous_n < max_line: + $ skipped_count = max_line - previous_n + + + + $ skipped_comments = filter(lambda c: max(c.lines) in range(previous_n + 1, max_line), line_level_comments) + $for comment in skipped_comments: + +
… skipped ${ skipped_count } lines …
+
+
+ +
${ comment.message }
+
+
${ line[1:] or ' ' }
+
+
+ +
${ comment.message }
+
+
+
+
+ + +
+
+ +
+ + +
+
… skipped ${ skipped_count } lines …
+
+
+ +
${ comment.message }
+
+
+
+
+
\ No newline at end of file diff -r 256716e3a3d7 -r 36b37712c670 review/web_templates/review.html --- a/review/web_templates/review.html Tue Mar 02 19:49:35 2010 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -$def with (rd, rcset) - -$ ctx = rd.target[rcset.node] -

Changeset ${ ctx.rev() }: ${ ctx.description() }

- -$ review_level_comments = rcset.review_level_comments() -$for comment in review_level_comments: -
-
-
- -
${ comment.message }
-
-
- -
-

Add a comment on this changeset

-
-
- - -
-
- -
-
-
- -

Files

- -$for filename, diff in rcset.diffs().iteritems(): -
-
-    ↓ -

${ filename }

-
- -
- $ file_level_comments = rcset.file_level_comments(filename) - $for comment in file_level_comments: -
-
- -
-
- -
${ comment.message }
-
-
- - -
-

Add a comment on this file

-
-
- - -
-
- -
- -
-
- -
- - $ max_line = diff['max'] - $ content = diff['content'] - $ line_level_comments = rcset.line_level_comments(filename) - $ previous_n = -1 - $for n, line in content: - $if n - 1 > previous_n: - $ skipped_count = n - previous_n - $if previous_n == -1: - $ skipped_count -= 1 - - - - $ skipped_comments = filter(lambda c: max(c.lines) in range(previous_n + 1, n), line_level_comments) - $for comment in skipped_comments: - - $ kind = 'rem' if line[0] == '-' else 'add' if line[0] == '+' else 'con' - - - - $ line_comments = filter(lambda c: max(c.lines) == n, line_level_comments) - $for comment in line_comments: - - - - - $ previous_n = n - $if previous_n < max_line: - $ skipped_count = max_line - previous_n - - - - $ skipped_comments = filter(lambda c: max(c.lines) in range(previous_n + 1, max_line), line_level_comments) - $for comment in skipped_comments: - -
… skipped ${ skipped_count } lines …
-
-
- -
${ comment.message }
-
-
${ line[1:] or ' ' }
-
-
- -
${ comment.message }
-
-
-
-
- - -
-
- -
- - -
-
… skipped ${ skipped_count } lines …
-
-
- -
${ comment.message }
-
-
-
-
-
\ No newline at end of file diff -r 256716e3a3d7 -r 36b37712c670 review/web_ui.py --- a/review/web_ui.py Tue Mar 02 19:49:35 2010 -0500 +++ b/review/web_ui.py Tue Mar 02 20:23:36 2010 -0500 @@ -2,127 +2,145 @@ from __future__ import with_statement import sys, os +from hashlib import md5 + +from mercurial import cmdutil, hg, templatefilters +from mercurial.node import short +from mercurial.util import email + import api -from mercurial import cmdutil, hg package_path = os.path.split(os.path.realpath(__file__))[0] template_path = os.path.join(package_path, 'web_templates') media_path = os.path.join(package_path, 'web_media') top_path = os.path.split(package_path)[0] bundled_path = os.path.join(top_path, 'bundled') -webpy_path = os.path.join(bundled_path, 'webpy') - -sys.path.insert(0, webpy_path) -import web - +cherrypy_path = os.path.join(bundled_path, 'cherrypy') +jinja2_path = os.path.join(bundled_path, 'jinja2') -_rd = None -urls = ( - '/', 'index', - '/media/([^/]*)', 'media', - '/review/([\da-f]{12})/?', 'review', - '/push/', 'push', - '/pull/', 'pull', -) +sys.path.insert(0, cherrypy_path) +sys.path.insert(0, jinja2_path) + +import cherrypy +from jinja2 import Environment, FileSystemLoader -from mercurial.node import short -from mercurial.util import email -from mercurial import templatefilters -from hashlib import md5 -g = { - 'node_short': short, - 'basename': os.path.basename, - 'md5': md5, - 'email': email, - 'templatefilters': templatefilters, -} -render = web.template.render(template_path, globals=g) +TEMPLATE_DIR = os.path.join(package_path, 'web_templates') +jinja_env = Environment(loader=FileSystemLoader(TEMPLATE_DIR)) -LOG_PAGE_LEN = 25 - -def render_in_base(fn): - def _fn(*args, **kwargs): - title, content = fn(*args, **kwargs) - return render.base(_rd, content, title) - return _fn - -class index: - @render_in_base - def GET(self): - rev_max = _rd.target['tip'].rev() - rev_min = rev_max - LOG_PAGE_LEN if rev_max >= LOG_PAGE_LEN else 0 - revs = (_rd.target[r] for r in xrange(rev_max, rev_min, -1)) - return ('', render.index(_rd, revs)) +class ReviewWebUI(object): + def __init__(self, datastore): + self.datastore = datastore + + + @cherrypy.expose + def index(self): + return jinja_env.get_template('index.html').render( + datastore=self.datastore + ) -class review: - @render_in_base - def GET(self, node_short): - title = '/ %s:%s – %s' % ( - _rd[node_short].target[node_short].rev(), - node_short, - _rd[node_short].target[node_short].description().splitlines()[0]) - return (title, render.review(_rd, _rd[node_short])) - - def POST(self, node_short): - i = web.input() - body = i['body'] - filename = i['filename'] if 'filename' in i else '' - lines = i['lines'].split(',') if 'lines' in i else '' - print filename, lines - - if body: - rcset = _rd[node_short] - rcset.add_comment(body, filename, lines) - - raise web.seeother('/review/%s/' % node_short) - -class push: - def GET(self): - path = web.input()['path'] - dest, revs, checkout = hg.parseurl(_rd.repo.ui.expandpath(path, path), None) - other = hg.repository(cmdutil.remoteui(_rd.repo, {}), dest) - - _rd.repo.push(other, True, revs=revs) - - raise web.seeother('/') - - -class pull: - def GET(self): - path = web.input()['path'] - source, revs, checkout = hg.parseurl(_rd.repo.ui.expandpath(path, path), None) - other = hg.repository(cmdutil.remoteui(_rd.repo, {}), source) - - modheads = _rd.repo.pull(other, heads=revs, force=True) - - if modheads: - hg.update(_rd.repo, 'tip') - - raise web.seeother('/') - - -class media: - def GET(self, fname): - if '..' in fname: - return '' - else: - with open(os.path.join(media_path, fname)) as f: - content = f.read() - return content - - -def load_interface(ui, repo, open=False): - global _rd - _rd = api.ReviewDatastore(ui, repo) - - sys.argv = sys.argv[:1] # Seriously, web.py? This is such a hack. - app = web.application(urls, globals()) - +def load_interface(ui, repo, open=False, port=8080): if open: import webbrowser - webbrowser.open(app.browser().url) + webbrowser.open('http://localhost:%d/' % port) + + cherrypy.quickstart(ReviewWebUI(api.ReviewDatastore(ui, repo))) + + - app.run() +# _rd = None +# urls = ( +# '/', 'index', +# '/media/([^/]*)', 'media', +# '/review/([\da-f]{12})/?', 'review', +# '/push/', 'push', +# '/pull/', 'pull', +# ) +# +# g = { +# 'node_short': short, +# 'basename': os.path.basename, +# 'md5': md5, +# 'email': email, +# 'templatefilters': templatefilters, +# } +# render = web.template.render(template_path, globals=g) +# +# LOG_PAGE_LEN = 25 +# +# def render_in_base(fn): +# def _fn(*args, **kwargs): +# title, content = fn(*args, **kwargs) +# return render.base(_rd, content, title) +# return _fn +# +# class index: +# @render_in_base +# def GET(self): +# rev_max = _rd.target['tip'].rev() +# rev_min = rev_max - LOG_PAGE_LEN if rev_max >= LOG_PAGE_LEN else 0 +# revs = (_rd.target[r] for r in xrange(rev_max, rev_min, -1)) +# return ('', render.index(_rd, revs)) +# +# +# class review: +# @render_in_base +# def GET(self, node_short): +# title = '/ %s:%s – %s' % ( +# _rd[node_short].target[node_short].rev(), +# node_short, +# _rd[node_short].target[node_short].description().splitlines()[0]) +# return (title, render.review(_rd, _rd[node_short])) +# +# def POST(self, node_short): +# i = web.input() +# body = i['body'] +# filename = i['filename'] if 'filename' in i else '' +# lines = i['lines'].split(',') if 'lines' in i else '' +# print filename, lines +# +# if body: +# rcset = _rd[node_short] +# rcset.add_comment(body, filename, lines) +# +# raise web.seeother('/review/%s/' % node_short) +# +# +# class push: +# def GET(self): +# path = web.input()['path'] +# dest, revs, checkout = hg.parseurl(_rd.repo.ui.expandpath(path, path), None) +# other = hg.repository(cmdutil.remoteui(_rd.repo, {}), dest) +# +# _rd.repo.push(other, True, revs=revs) +# +# raise web.seeother('/') +# +# +# class pull: +# def GET(self): +# path = web.input()['path'] +# source, revs, checkout = hg.parseurl(_rd.repo.ui.expandpath(path, path), None) +# other = hg.repository(cmdutil.remoteui(_rd.repo, {}), source) +# +# modheads = _rd.repo.pull(other, heads=revs, force=True) +# +# if modheads: +# hg.update(_rd.repo, 'tip') +# +# raise web.seeother('/') +# +# +# class media: +# def GET(self, fname): +# if '..' in fname: +# return '' +# else: +# with open(os.path.join(media_path, fname)) as f: +# content = f.read() +# return content +# +# +