In pygit, add diff colorizing.

portnov [2008-06-10 07:37:29]
In pygit, add diff colorizing.
Filename
media/css/main.css
pygit/pygit.py
pygit/views.py
templates/git.html
templates/git_blame.html
templates/git_diff.html
templates/git_tree.html
diff --git a/media/css/main.css b/media/css/main.css
index 1332236..255728c 100644
--- a/media/css/main.css
+++ b/media/css/main.css
@@ -9,6 +9,10 @@ td {
   padding: 0.6ex;
 }

+tr:hover {
+  background: #eee;
+}
+
 #body {
   padding: 1ex;
 }
@@ -103,3 +107,15 @@ p.date {
 .bug-state-5 {
   background: #ccc;
 }
+
+.diff-add {
+  color: blue;
+}
+
+.diff-del {
+  color: red;
+}
+
+.diff-at {
+  color: green;
+}
diff --git a/pygit/pygit.py b/pygit/pygit.py
index fb11d98..4dc8097 100644
--- a/pygit/pygit.py
+++ b/pygit/pygit.py
@@ -67,7 +67,10 @@ def diff_all(rid,cid1,cid2=None):
   if cid2:
     c2 = r.commits(cid2)[0]
   else:
-    c2 = c1.parents[0]
+    if c1.parents:
+      c2 = c1.parents[0]
+    else:
+      return [("Initial commit","Nothing to diff.")]
   ds = Commit.diff(r,c2,c1)
   return [(d.a_path,d.diff) for d in ds]

@@ -77,7 +80,10 @@ def diff_path(rid,path,cid1,cid2=None):
   if cid2:
     c2 = r.commits(cid2)[0]
   else:
-    c2 = c1.parents[0]
+    if c1.parents:
+      c2 = c1.parents[0]
+    else:
+      return [("Initial commit","Nothing to diff.")]
   ds = Commit.diff(r,c2,c1)
   return [(d.a_path,d.diff) for d in ds if d.a_path==path]

diff --git a/pygit/views.py b/pygit/views.py
index 5070df5..28c58dd 100644
--- a/pygit/views.py
+++ b/pygit/views.py
@@ -3,11 +3,22 @@
 import sys
 from os.path import dirname,join

+# from django.template.defaultfilters import escape
+
 import pygit

 sys.path.append(dirname(dirname(__file__)))
 from mgmt.views import render_it

+class Repo(object):
+  pass
+
+def repo_rid(rid):
+  r = Repo()
+  r.rid = rid
+  r.description = pygit.description(rid)
+  return r
+
 def all_repos(request):
   return render_it('repos.html',
       {'repos': pygit.repos()},
@@ -30,8 +41,9 @@ def one_repo(request,rid,branch='master'):

 def tree(request,rid,branch,tid,path):
   dirs,files = pygit.tree(rid,tid)
+  repo = repo_rid(rid)
   return render_it('git_tree.html',
-      {'rid': rid,
+      {'repo': repo,
        'branch': branch,
        'path': path,
        'dirs': dirs,
@@ -39,20 +51,47 @@ def tree(request,rid,branch,tid,path):
       request)

 def blame(request,rid,branch,path):
+  repo = repo_rid(rid)
   bl = pygit.blame(rid,path,branch)
   return render_it('git_blame.html',
-      {'rid': rid,
+      {'repo': repo,
        'path': path,
        'blame': bl},
       request)

+def escape(s):
+  s1 = s.replace('<','&lt;')
+  return s1.replace('>','&gt;')
+
 def diff(request,rid,cid,path=None):
+  def format_diff(diff):
+    data = diff[1]
+    def format_line(line):
+      span=None
+      if not line:
+        return line
+      if line[0]=='+':
+        span='diff-add'
+      if line[0]=='-':
+        span='diff-del'
+      if line[:2]=='@@':
+        span='diff-at'
+      if span:
+        return "<span class='%s'>%s</span>" % (span,line)
+      else:
+        return line
+    lines = map(escape,data.split('\n'))
+    return diff[0], '\n'.join(map(format_line,lines))
+
   if not path:
     ds = pygit.diff_all(rid,cid)
   else:
     ds = pygit.diff_path(rid,path,cid)
+  repo = repo_rid(rid)
+  ds = map(format_diff,ds)
   return render_it('git_diff.html',
-    {'path': path,
+    {'repo': repo,
+     'path': path,
      'cid': cid,
      'diffs': ds},
     request)
diff --git a/templates/git.html b/templates/git.html
new file mode 100644
index 0000000..f293572
--- /dev/null
+++ b/templates/git.html
@@ -0,0 +1,8 @@
+{% extends "base.html" %}
+
+{% block main %}
+<div class='links'>Репозиторий: <a href='/git/repo/{{repo.rid}}/'>{{repo.description}}</a></div>
+
+  {% block git %}
+  {% endblock %}
+{% endblock %}
diff --git a/templates/git_blame.html b/templates/git_blame.html
index 3d0f7ea..f48dbaf 100644
--- a/templates/git_blame.html
+++ b/templates/git_blame.html
@@ -1,14 +1,14 @@
-{% extends "base.html" %}
+{% extends "git.html" %}

 {% block title %}История файла {{path}}{% endblock %}

-{% block main %}
+{% block git %}
 <h2>История файла {{path}}</h2>

 <table>
   {% for cid,author,dt,message,line in blame %}
   <tr>
-    <td><a href='/git/diff/{{rid}}/{{cid}}/{{path}}/'>{{cid}}</a></td>
+    <td><a href='/git/diff/{{repo.rid}}/{{cid}}/{{path}}/'>{{cid}}</a></td>
     <td>{{author}}</td><td>{{dt}}</td><td>{{message}}</td><td>{{forloop.counter}}</td><td>{{line}}</td>
   </tr>
   {% endfor %}
diff --git a/templates/git_diff.html b/templates/git_diff.html
index 0963758..55c1c5a 100644
--- a/templates/git_diff.html
+++ b/templates/git_diff.html
@@ -1,15 +1,17 @@
-{% extends "base.html" %}
+{% extends "git.html" %}

 {% block title %}Diff: #{{cid}}{% if path %} {{path}}{% endif %}{% endblock %}

-{% block main %}
+{% block git %}

 <h2>Diff: #{{cid}}{% if path %} {{path}}{% endif %}</h2>
+{% autoescape off %}
 {% for file,diff in diffs %}
   <h3>{{file}}</h3>
   <code><pre>
   {{diff}}
   </pre></code>
 {% endfor %}
+{% endautoescape %}

 {% endblock %}
diff --git a/templates/git_tree.html b/templates/git_tree.html
index 82a75f1..5544958 100644
--- a/templates/git_tree.html
+++ b/templates/git_tree.html
@@ -1,16 +1,16 @@
-{% extends "base.html" %}
+{% extends "git.html" %}

 {% block title %}Список файлов{% endblock %}

-{% block main %}
+{% block git %}
 <h3>Файлы:</h3>

 <ul>
   {% for id,name in dirs %}
-  <li><a href='/git/repo/{{rid}}/{{branch}}/tree/{{id}}/{{path}}/{{name}}/'>{{name}}</a></li>
+  <li><a href='/git/repo/{{repo.rid}}/{{branch}}/tree/{{id}}/{{path}}/{{name}}/'>{{name}}</a></li>
   {% endfor %}
   {% for id,name in files %}
-  <li><a href='/git/blame/{{rid}}/{{branch}}/{{path}}/{{name}}/'>{{name}}</a></li>
+  <li><a href='/git/blame/{{repo.rid}}/{{branch}}/{{path}}/{{name}}/'>{{name}}</a></li>
   {% endfor %}
 </ul>
ViewGit