--- a/review/web_templates/base.html Tue Mar 02 21:59:51 2010 -0500
+++ b/review/web_templates/base.html Wed Mar 03 18:04:53 2010 -0500
@@ -3,7 +3,7 @@
<html>
<head>
- <title>Reviewing {{ utils["basename"](datastore.target.root) }}</title>
+ <title>Reviewing {{ utils["basename"](datastore.target.root) }}{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="/media/aal.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/media/style.css" type="text/css" media="screen" />
@@ -15,11 +15,11 @@
<body>
<div id="head-wrap">
<h1>
- Reviewing:
+ Reviewing
<a href="/">
{{ utils["basename"](datastore.target.root) }}
</a>
- {% block title %}{% endblock %}
+ {% block header %}{% endblock %}
</h1>
</div>
<div id="content-wrap">
--- a/review/web_templates/changeset.html Tue Mar 02 21:59:51 2010 -0500
+++ b/review/web_templates/changeset.html Wed Mar 03 18:04:53 2010 -0500
@@ -1,135 +1,176 @@
-$def with (rd, rcset)
+{% extends "base.html" %}
-$ ctx = rd.target[rcset.node]
-<h2>Changeset ${ ctx.rev() }: ${ ctx.description() }</h2>
+{% block title %} at {{ title }}{% endblock %}
+{% block header %} at {{ title }}{% endblock %}
-$ review_level_comments = rcset.review_level_comments()
-$for comment in review_level_comments:
- <div class="comment">
- <div class="avatar"><img height="52" width="52" src="http://www.gravatar.com/avatar/${ md5(email(comment.author)).hexdigest() }?s=52"/></div>
- <div>
- <div class="author"><a href="mailto:${ email(comment.author) }">${ templatefilters.person(comment.author) }</a> said:</div>
- <div class="message">${ comment.message }</div>
+{% block content %}
+ <h2>Changeset {{ rev.rev() }}: {{ rev.description().splitlines()[0] }}</h2>
+
+ {% for comment in rcset.review_level_comments() %}
+ <div class="comment">
+ <div class="avatar">
+ <img height="52" width="52"
+ src="{{ utils['comment_gravatar'](comment) }}?s=52"
+ />
+ </div>
+ <div>
+ <div class="author">
+ <a href="mailto:${ email(comment.author) }">{{ utils['templatefilters'].person(comment.author) }}</a>
+ said:
+ </div>
+ <div class="message">{{ comment.message }}</div>
+ </div>
</div>
+ {% endfor %}
+
+ <div id="comment-review">
+ <p class="comment-activate"><a href="">Add a comment on this changeset</a></p>
+ <form id="comment-review-form" method="post" action="">
+ <div class="field">
+ <label for="body">Add a comment on this changeset:</label>
+ <textarea cols="60" rows="6" name="body"></textarea>
+ </div>
+ <div class="buttons">
+ <input type="submit" class="button" value="Submit" />
+ </div>
+ </form>
</div>
-<div id="comment-review">
- <p class="comment-activate"><a href="">Add a comment on this changeset</a></p>
- <form id="comment-review-form" method="post" action="">
- <div class="field">
- <label for="body">Add a comment on this changeset:</label>
- <textarea cols="60" rows="6" name="body"></textarea>
- </div>
- <div class="buttons">
- <input type="submit" class="button" value="Submit" />
- </div>
- </form>
-</div>
-
-<h2>Files</h2>
-
-$for filename, diff in rcset.diffs().iteritems():
- <div class="file-review">
- <div class="filename-header">
- <a class="fold-file" href=""> ↓</a>
- <h3>${ filename }</h3>
- </div>
-
- <div class="file-review-contents">
- $ file_level_comments = rcset.file_level_comments(filename)
- $for comment in file_level_comments:
- <div class="comment">
- <div class="avatar">
- <img height="52" width="52" src="http://www.gravatar.com/avatar/${ md5(email(comment.author)).hexdigest() }?s=52"/>
- </div>
- <div>
- <div class="author"><a href="mailto:${ email(comment.author) }">${ templatefilters.person(comment.author) }</a> said:</div>
- <div class="message">${ comment.message }</div>
- </div>
- </div>
-
-
- <div id="comment-file">
- <p class="comment-activate"><a href="">Add a comment on this file</a></p>
- <form id="comment-file-form" method="post" action="">
- <div class="field">
- <label for="body">Add a comment on this file:</label>
- <textarea cols="60" rows="6" name="body"></textarea>
- </div>
- <div class="buttons">
- <input type="submit" class="button" value="Submit" />
- </div>
- <input type="hidden" name="filename" value="${ filename }" />
- </form>
+ <h2>Files</h2>
+
+ {% for filename, diff in rcset.diffs().iteritems() %}
+ <div class="file-review">
+ <div class="filename-header">
+ <a class="fold-file" href=""> ↓</a>
+ <h3>{{ filename }}</h3>
</div>
- <div class="diff">
- <table>
- $ 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
- <tr class="skipped">
- <td><code>… skipped ${ skipped_count } lines …</code></td>
+ <div class="file-review-contents">
+ {% for comment in rcset.file_level_comments(filename) %}
+ <div class="comment">
+ <div class="avatar">
+ <img height="52" width="52" src="{{ utils['comment_gravatar'](comment) }}?s=52"/>
+ </div>
+ <div>
+ <div class="author">
+ <a href="mailto:{{ utils['email'](comment.author) }}">
+ {{ utils['templatefilters'].person(comment.author) }}</a>
+ said:
+ </div>
+ <div class="message">{{ comment.message }}</div>
+ </div>
+ </div>
+ {% endfor %}
+
+ <div id="comment-file">
+ <p class="comment-activate"><a href="">Add a comment on this file</a></p>
+
+ <form id="comment-file-form" method="post" action="">
+ <div class="field">
+ <label for="body">Add a comment on this file:</label>
+ <textarea cols="60" rows="6" name="body"></textarea>
+ </div>
+ <div class="buttons">
+ <input type="submit" class="button" value="Submit" />
+ </div>
+ <input type="hidden" name="filename" value="{{ filename }}" />
+ </form>
+ </div>
+
+ <div class="diff">
+ <table>
+ {% set max_line = diff['max'] %}
+ {% set content = diff['content'] %}
+ {% set line_level_comments = rcset.line_level_comments(filename) %}
+ {% set previous_n = -1 %}
+
+ {% for n, line in content %}
+ {% if n - 1 < previous_n %}
+ {% set skipped_count = n - previous_n %}
+ {% if previous_n == -1 %}
+ {% set skipped_count = skipped_count - 1 %}
+ {% endif %}
+ <tr class="skipped">
+ <td><code>… skipped {{ skipped_count }} lines …</code></td>
+ </tr>
+ {% endif %}
+
+ {% for comment in utils['skipped_comments'](n, previous_n, line_level_comments) %}
+ <tr><td class="comment">
+ <div class="avatar"><img height="52" width="52" src="{{ utils['comment_gravatar'](comment) }}?s=52"/></div>
+ <div>
+ <div class="author">
+ <a href="mailto:{{ utils['email'](comment.author) }}">
+ {{ utils['templatefilters'].person(comment.author) }}
+ </a>
+ said (on a skipped line):
+ </div>
+ <div class="message">{{ comment.message }}</div>
+ </div>
+ </td></tr>
+ {% endfor %}
+
+ <tr class="{{ utils['line_type'](line) }}">
+ <td class="diff-line"><code>{{ line[1:] }}</code></td>
</tr>
- $ skipped_comments = filter(lambda c: max(c.lines) in range(previous_n + 1, n), line_level_comments)
- $for comment in skipped_comments:
- <tr><td class="comment">
- <div class="avatar"><img height="52" width="52" src="http://www.gravatar.com/avatar/${ md5(email(comment.author)).hexdigest() }?s=52"/></div>
- <div>
- <div class="author"><a href="mailto:${ email(comment.author) }">${ templatefilters.person(comment.author) }</a> said (on a skipped line):</div>
- <div class="message">${ comment.message }</div>
- </div>
- </td></tr>
- $ kind = 'rem' if line[0] == '-' else 'add' if line[0] == '+' else 'con'
- <tr class="${ kind }">
- <td class="diff-line"><code>${ line[1:] or ' ' }</code></td>
- </tr>
- $ line_comments = filter(lambda c: max(c.lines) == n, line_level_comments)
- $for comment in line_comments:
- <tr><td class="comment">
- <div class="avatar"><img height="52" width="52" src="http://www.gravatar.com/avatar/${ md5(email(comment.author)).hexdigest() }?s=52"/></div>
- <div>
- <div class="author"><a href="mailto:${ email(comment.author) }">${ templatefilters.person(comment.author) }</a> said:</div>
- <div class="message">${ comment.message }</div>
- </div>
- </td></tr>
- <tr class="comment-line">
- <td>
- <form id="comment-line-form" method="post" action="">
- <div class="field">
- <label for="body">Add a comment on this line:</label>
- <textarea cols="60" rows="6" name="body"></textarea>
+
+ {% for comment in utils['line_comments'](n, line_level_comments) %}
+ <tr><td class="comment">
+ <div class="avatar"><img height="52" width="52" src="{{ utils['comment_gravatar'](comment) }}?s=52"/></div>
+ <div>
+ <div class="author">
+ <a href="mailto:{{ utils['email'](comment.author) }}">
+ {{ utils['templatefilters'].person(comment.author) }}
+ </a>
+ said:
+ </div>
+ <div class="message">{{ comment.message }}</div>
</div>
- <div class="buttons">
- <input type="submit" class="button" value="Submit" />
+ </td></tr>
+ {% endfor %}
+
+ <tr class="comment-line">
+ <td>
+ <form id="comment-line-form" method="post" action="">
+ <div class="field">
+ <label for="body">Add a comment on this line:</label>
+ <textarea cols="60" rows="6" name="body"></textarea>
+ </div>
+ <div class="buttons">
+ <input type="submit" class="button" value="Submit" />
+ </div>
+ <input type="hidden" name="filename" value="{{ filename }}" />
+ <input type="hidden" name="lines" value="{{ n }}" />
+ </form>
+ </td>
+ </tr>
+
+ {% set previous_n = n %}
+ {% endfor %}
+
+ {% if previous_n < max_line %}
+ <tr class="skipped">
+ <td><code>… skipped {{ max_line - previous_n }} lines …</code></td>
+ </tr>
+
+ {% for comment in utils['skipped_comments_end'](previous_n, max_line, line_level_comments) %}
+ <tr><td class="comment">
+ <div class="avatar"><img height="52" width="52" src="{{ utils['comment_gravatar'](comment) }}?s=52"/></div>
+ <div>
+ <div class="author">
+ <a href="mailto:{{ utils['email'](comment.author) }}">
+ {{ utils['templatefilters'].person(comment.author) }}
+ </a>
+ said (on a skipped line):
+ </div>
+ <div class="message">{{ comment.message }}</div>
</div>
- <input type="hidden" name="filename" value="${ filename }" />
- <input type="hidden" name="lines" value="${ n }" />
- </form>
- </td>
- </tr>
- $ previous_n = n
- $if previous_n < max_line:
- $ skipped_count = max_line - previous_n
- <tr class="skipped">
- <td><code>… skipped ${ skipped_count } lines …</code></td>
- </tr>
- $ skipped_comments = filter(lambda c: max(c.lines) in range(previous_n + 1, max_line), line_level_comments)
- $for comment in skipped_comments:
- <tr><td class="comment">
- <div class="avatar"><img height="52" width="52" src="http://www.gravatar.com/avatar/${ md5(email(comment.author)).hexdigest() }?s=52"/></div>
- <div>
- <div class="author"><a href="mailto:${ email(comment.author) }">${ templatefilters.person(comment.author) }</a> said (on a skipped line):</div>
- <div class="message">${ comment.message }</div>
- </div>
- </td></tr>
- </table>
+ </td></tr>
+ {% endfor %}
+ {% endif %}
+ </table>
+ </div>
</div>
</div>
- </div>
\ No newline at end of file
+ {% endfor %}
+{% endblock %}
\ No newline at end of file
--- a/review/web_templates/index.html Tue Mar 02 21:59:51 2010 -0500
+++ b/review/web_templates/index.html Wed Mar 03 18:04:53 2010 -0500
@@ -1,6 +1,7 @@
{% extends "base.html" %}
{% block title %}{% endblock %}
+{% block header %}{% endblock %}
{% block content %}
<h2>Changesets</h2>
@@ -11,7 +12,7 @@
<tr class="${ loop.parity }">
<td>{{ rev.rev() }}:{{ node_short }}</td>
<td>
- <a href="/review/{{ node_short }}/">{{ rev.description().splitlines()[0] }}</a>
+ <a href="/changeset/{{ node_short }}/">{{ rev.description().splitlines()[0] }}</a>
</td>
<td class="last">
{{ utils['len'](rcset.comments) }} comments,
@@ -21,10 +22,3 @@
{% endfor %}
</table>
{% endblock %}
-
-
-
-<!-- $ ctx_node = ctx.node()
-$ ctx_node_short = node_short(ctx_node)
-$ ctx_comments = rd[ctx_node].comments
-$ ctx_signoffs = rd[ctx_node].signoffs -->
--- a/review/web_ui.py Tue Mar 02 21:59:51 2010 -0500
+++ b/review/web_ui.py Wed Mar 03 18:04:53 2010 -0500
@@ -30,6 +30,21 @@
LOG_PAGE_LEN = 1000000
+def _comment_gravatar(comment):
+ return 'http://www.gravatar.com/avatar/%s/' % md5(email(comment.author)).hexdigest()
+
+def _skipped_comments(n, previous_n, line_level_comments):
+ return filter(lambda c: max(c.lines) in range(previous_n + 1, n), line_level_comments)
+
+def _skipped_comments_end(previous_n, max_line, line_level_comments):
+ return filter(lambda c: max(c.lines) in range(previous_n + 1, max_line), line_level_comments)
+
+def _line_type(line):
+ return 'rem' if line[0] == '-' else 'add' if line[0] == '+' else 'con'
+
+def _line_comments(n, line_level_comments):
+ return filter(lambda c: max(c.lines) == n, line_level_comments)
+
utils = {
'node_short': short,
'basename': os.path.basename,
@@ -37,6 +52,11 @@
'email': email,
'templatefilters': templatefilters,
'len': len,
+ 'comment_gravatar': _comment_gravatar,
+ 'skipped_comments': _skipped_comments,
+ 'skipped_comments_end': _skipped_comments_end,
+ 'line_type': _line_type,
+ 'line_comments': _line_comments,
}
class ReviewWebUI(object):
@@ -55,6 +75,20 @@
rcsets=rcsets,
)
+
+ @cherrypy.expose
+ def changeset(self, *args):
+ if len(args) != 1:
+ return 'OH GOD HOW DID THIS GET HERE I AM NOT GOOD WITH LINKS'
+ rev_id = args[0]
+ rcset = self.datastore[rev_id]
+ rev = rcset.target[rev_id]
+
+ return jinja_env.get_template('changeset.html').render(
+ utils=utils, datastore=self.datastore,
+ title='%s:%s' % (rev.rev(), short(rev.node())),
+ rcset=rcset, rev=rev,
+ )
def load_interface(ui, repo, open=False, port=8080):