aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bn_django/git_browse/models.py10
-rw-r--r--bn_django/git_wiki/models.py208
-rw-r--r--bn_django/git_wiki/templates/git_wiki/base.html11
-rw-r--r--bn_django/git_wiki/templates/git_wiki/frontpage.html2
-rw-r--r--bn_django/git_wiki/templates/git_wiki/shortlog_table4
-rw-r--r--bn_django/git_wiki/urls.py8
-rw-r--r--bn_django/git_wiki/views.py44
-rw-r--r--static/style/git_wiki.css4
8 files changed, 196 insertions, 95 deletions
diff --git a/bn_django/git_browse/models.py b/bn_django/git_browse/models.py
index 4cc73a3..315365a 100644
--- a/bn_django/git_browse/models.py
+++ b/bn_django/git_browse/models.py
@@ -159,10 +159,12 @@ class Commit(models.Model):
rawdiff = models.TextField("ASCII contents of full commit diff")
commit_date = models.DateField("Date of commit to repository")
author_date = models.DateField("Date commit was writen/created")
- author = models.CharField("Name of commit author")
- author_email = models.DateField("Email address of commit author")
- committer = models.CharField("Name of committer")
- committer_email = models.DateField("Email address of committer")
+ author = models.CharField("Name of commit author", maxlength=96)
+ author_email = models.CharField("Email address of commit author", \
+ maxlength=196)
+ committer = models.CharField("Name of committer", maxlength=96)
+ committer_email = models.CharField("Email address of committer", \
+ maxlength=196)
comment = models.TextField("Notes on the commit")
parenthash = models.CharField("parent's hash", maxlength=40)
#TODO: parent = models.ForeignKey()
diff --git a/bn_django/git_wiki/models.py b/bn_django/git_wiki/models.py
index 4201a84..47fc612 100644
--- a/bn_django/git_wiki/models.py
+++ b/bn_django/git_wiki/models.py
@@ -9,55 +9,6 @@ except AttributeError:
if ADMIN_URL[-1] == '/':
ADMIN_URL=ADMIN_URL[:-1]
-GITPREFIX = 'cd ' +str(GITWIKI_BASE) + '; ' + str(GITCOMMAND) + ' --git-dir=' \
- + str(GITWIKI_BASE) + '/.git '
-
-def reposcan():
- import os
- heads = dict()
- for h in os.listdir(GITWIKI_BASE + self.slug + '/.git/refs/heads/'):
- f = open(GITWIKI_BASE + self.slug + '/.git/refs/heads/' + h,'r')
- heads[h.strip()] = f.readline().strip()
- f.close()
- tags = dict()
- for t in os.listdir(GITWIKI_BASE + self.slug + '/.git/refs/tags/'):
- f = open(GITWIKI_BASE + self.slug + '/.git/refs/tags/' + t,'r')
- tags[t.strip()] = f.readline().strip()
- f.close()
- return (heads, tags)
-
-def shortlog(hash=None,tree=None):
- import commands
-
- if tree:
- hash=tree.id
- logtxt = commands.getoutput(GITPREFIX \
- + ' log --relative-date --max-count=6 | cat')
- print GITPREFIX
- print logtxt
- log_items = logtxt.split('\ncommit ')
- if (log_items[0] == ''):
- log_items.pop(0)
- if (log_items[0].startswith('commit ')):
- log_items[0] = log_items[0][7:]
- shortlog = list()
- for li in log_items:
- logobj = dict()
- lines = li.splitlines()
- if len(lines) < 3: continue
- logobj['hash'] = lines[0].strip()
- logobj['shorthash'] = lines[0].strip()[:5]
- logobj['author'] = lines[1][8:]
- logobj['date'] = lines[2][8:]
- if len(lines) > 4:
- logobj['description'] = lines[4][4:]
- else:
- logobj['description'] = '(none)'
- # here we truncate commit comments for shortlogs
- logobj['shortdescription'] = logobj['description'][:128]
- shortlog.append(logobj)
- return shortlog
-
class Tree(models.Model):
mode = models.CharField("file mode/permissions", blank=False,maxlength=4)
path = models.CharField("relative path from repo base", maxlength=512)
@@ -66,7 +17,7 @@ class Tree(models.Model):
type = 'tree'
def slug(self):
#TODO: secure this
- return self.name.strip().lower()
+ return ''.join(self.path.strip().lower().split())
class Admin:
ordering = ['path','name']
@@ -78,6 +29,38 @@ class Tree(models.Model):
def get_admin_url(self):
return "%s/k/%s/" % (ADMIN_URL, self.id)
+ def update(self):
+ import commands
+ if (not self.id): return
+
+ self.id = self.id.strip()
+ tree_ls = commands.getoutput(GITPREFIX + ' ls-tree --full-name ' \
+ + self.id)
+ tree_objs = list()
+ blob_objs = list()
+ for line in tree_ls.splitlines():
+ l = line.split()
+ if len(l) < 4:
+ continue
+ if l[1] == 'tree':
+ t = Tree(id=l[2])
+ t.path = ' '.join(l[3:])
+ if self.path and self.path != '/':
+ t.path = self.path + '/' + t.path
+ t.name = t.path
+ tree_objs.append(t)
+ if l[1] == 'blob':
+ i = Item(id=l[2])
+ i.path = ' '.join(l[3:])
+ if self.path and self.path != '/':
+ i.path = self.path + '/' + i.path
+ i.name=i.path
+ blob_objs.append(i)
+ self.tree_objs = tree_objs
+ self.blob_objs = blob_objs
+ self.all_objs = tree_objs + blob_objs
+
+
class Item(models.Model):
mode = models.CharField("file mode/permissions", blank=False,maxlength=4)
path = models.CharField("relative path from repo base", maxlength=512)
@@ -86,6 +69,9 @@ class Item(models.Model):
size = models.IntegerField("filesize in byte", maxlength=128,blank=False)
contents = models.TextField("ASCII contents of the file")
type='blob'
+ def slug(self):
+ #TODO: secure this
+ return ''.join(self.name.strip().lower().split())
class Admin:
ordering = ['path','name']
@@ -111,10 +97,12 @@ class Commit(models.Model):
rawdiff = models.TextField("ASCII contents of full commit diff")
commit_date = models.DateField("Date of commit to repository")
author_date = models.DateField("Date commit was writen/created")
- author = models.CharField("Name of commit author")
- author_email = models.DateField("Email address of commit author")
- committer = models.CharField("Name of committer")
- committer_email = models.DateField("Email address of committer")
+ author = models.CharField("Name of commit author", maxlength=96)
+ author_email = models.CharField("Email address of commit author",\
+ maxlength=196)
+ committer = models.CharField("Name of committer", maxlength=96)
+ committer_email = models.CharField("Email address of committer", \
+ maxlength=196)
comment = models.TextField("Notes on the commit")
parenthash = models.CharField("parent's hash", maxlength=40)
#TODO: parent = models.ForeignKey()
@@ -143,14 +131,112 @@ class Commit(models.Model):
raw = raw.splitlines()
if len(raw) < 3: return
self.treehash = raw[0].split()[-1].strip()
- self.parenthash = raw[1][6:].strip()
- self.author = raw[2].split()[1]
- self.author_date = time.ctime(int(raw[2].split()[-2]))
- self.committer = raw[3].split()[1]
- self.committer_date = time.ctime(int(raw[3].split()[-2]))
- if len(raw) > 4:
- for l in raw[4:]:
+ if raw[1].startswith('parent'):
+ self.parenthash = raw[1][6:].strip()
+ raw.pop(1)
+ self.author = raw[1].split()[1]
+ self.author_date = time.ctime(int(raw[1].split()[-2]))
+ self.committer = raw[2].split()[1]
+ self.committer_date = time.ctime(int(raw[2].split()[-2]))
+ if len(raw) > 3:
+ for l in raw[3:]:
self.comment += str(l) + '\n'
else:
self.comment = '(none)'
return
+
+
+def fromslug(reqslug):
+ import commands
+
+ if reqslug == '' or reqslug == '/':
+ f = open(GITWIKI_BASE + '/.git/HEAD','r')
+ head = f.readline().strip().split()[1]
+ f.close()
+ f = open(GITWIKI_BASE + '/.git/'+head,'r')
+ hash = f.readline().strip()
+ f.close()
+ ret = Tree(id=hash)
+ ret.path='/'
+ ret.name='/'
+ ret.reqslug = '/'
+ return ret
+
+ reqslug = ''.join(reqslug.strip().lower().split())
+ if reqslug[-1] == '/':
+ reqslug=reqslug[:-1]
+ itemtxt = commands.getoutput(GITPREFIX \
+ + ' ls-tree -t -r HEAD')
+ if not itemtxt:
+ return None
+ hash, path, type = None, None, None
+ for l in itemtxt.splitlines():
+ words = l.split()
+ if len(words) < 4:
+ continue
+ ftype = words[1]
+ fhash = words[2]
+ fpath = ' '.join(words[3:])
+ if fpath[-1] == '/':
+ fpath=fpath[:-1]
+ if ''.join(fpath.strip().lower().split()) == reqslug:
+ hash = fhash
+ path = fpath
+ type = ftype
+ break;
+ if (not hash) or (not type) or (not path):
+ return None
+ if type == 'blob':
+ ret = Item(id=hash)
+ elif type == 'tree':
+ ret = Tree(id=hash)
+ ret.path=path
+ ret.name=path
+ ret.reqslug = reqslug
+ return ret
+
+def reposcan():
+ import os
+ heads = dict()
+ for h in os.listdir(GITWIKI_BASE + '/.git/refs/heads/'):
+ f = open(GITWIKI_BASE + '/.git/refs/heads/' + h,'r')
+ heads[h.strip()] = f.readline().strip()
+ f.close()
+ tags = dict()
+ for t in os.listdir(GITWIKI_BASE + '/.git/refs/tags/'):
+ f = open(GITWIKI_BASE + '/.git/refs/tags/' + t,'r')
+ tags[t.strip()] = f.readline().strip()
+ f.close()
+ return (heads, tags)
+
+def shortlog(hash=None,tree=None):
+ import commands
+
+ if tree:
+ hash=tree.id
+ logtxt = commands.getoutput(GITPREFIX \
+ + ' log --relative-date --max-count=6 | cat')
+ print GITPREFIX
+ print logtxt
+ log_items = logtxt.split('\ncommit ')
+ if (log_items[0] == ''):
+ log_items.pop(0)
+ if (log_items[0].startswith('commit ')):
+ log_items[0] = log_items[0][7:]
+ shortlog = list()
+ for li in log_items:
+ logobj = dict()
+ lines = li.splitlines()
+ if len(lines) < 3: continue
+ logobj['hash'] = lines[0].strip()
+ logobj['shorthash'] = lines[0].strip()[:5]
+ logobj['author'] = lines[1][8:]
+ logobj['date'] = lines[2][8:]
+ if len(lines) > 4:
+ logobj['description'] = lines[4][4:]
+ else:
+ logobj['description'] = '(none)'
+ # here we truncate commit comments for shortlogs
+ logobj['shortdescription'] = logobj['description'][:128]
+ shortlog.append(logobj)
+ return shortlog
diff --git a/bn_django/git_wiki/templates/git_wiki/base.html b/bn_django/git_wiki/templates/git_wiki/base.html
index ed88aa1..526a707 100644
--- a/bn_django/git_wiki/templates/git_wiki/base.html
+++ b/bn_django/git_wiki/templates/git_wiki/base.html
@@ -23,17 +23,6 @@
{% endblock %}
{% block content %}
-{% if item %}
{% block gitwiki %}
{% endblock %}
- <br />
- <span class="righty">
- <a href="/k/{{ item.slug }}/pdf/">pdf</a> - <a href="/k/{{ item.slug }}/log">log</a>
- </span>
- <br />
-{% else %}
-<p>No such knowledge!</p>
-<p>Perhaps you meant...</p>
-{% endif %}
-
{% endblock %}
diff --git a/bn_django/git_wiki/templates/git_wiki/frontpage.html b/bn_django/git_wiki/templates/git_wiki/frontpage.html
index b4c4cbd..85698c4 100644
--- a/bn_django/git_wiki/templates/git_wiki/frontpage.html
+++ b/bn_django/git_wiki/templates/git_wiki/frontpage.html
@@ -20,7 +20,7 @@ If you're curious you can track my work in the <a href="/code">code</a> section.
<div class="right_stuff">
For more recent content see the <a href="/timeline/">timeline</a>
</div>
-
+<h3><a href="/k/">Browse the knowledge!</a></h3>
<h3>Latest knowledge</h3>
{% include "git_wiki/shortlog_table" %}
<hr />
diff --git a/bn_django/git_wiki/templates/git_wiki/shortlog_table b/bn_django/git_wiki/templates/git_wiki/shortlog_table
index 8d30f80..85f916d 100644
--- a/bn_django/git_wiki/templates/git_wiki/shortlog_table
+++ b/bn_django/git_wiki/templates/git_wiki/shortlog_table
@@ -12,12 +12,12 @@
<td class="shorthash">
{% if heads %}{% for h in heads.iteritems %}
{% ifequal h.1 l.hash %}
- <span style="head">[{{ h.0 }}]</span>
+ <span class="head">[{{ h.0 }}]</span>
{% endifequal %}
{% endfor %}{% endif %}
{% if tags %}{% for t in tags.iteritems %}
{% ifequal l.hash t.1 %}
- <span style="tag">[{{ t.0 }}]</span>
+ <span class="tag">[{{ t.0 }}]</span>
{% endifequal %}{% endfor %}{% endif %}
<a href="/k/commit/{{ l.hash }}" class="subtle">
diff --git a/bn_django/git_wiki/urls.py b/bn_django/git_wiki/urls.py
index d765aea..0cd2031 100644
--- a/bn_django/git_wiki/urls.py
+++ b/bn_django/git_wiki/urls.py
@@ -15,7 +15,9 @@ info_dict = { 'extra_context': { 'admin_url': ADMIN_URL,
urlpatterns = patterns('bn_django.git_wiki.views',
(r'^(?P<hash>[0-9a-z]{40})/$', 'olditem',),
- (r'^(?P<req>.+)/$', 'item',),
- (r'^(?P<req>.+)/log/$', 'item',),
- (r'^(?P<req>.+)/edit/$', 'item',)
+ (r'^commit/(?P<hash>[0-9a-z]{40})/$', 'view_commit',),
+ (r'^(?P<reqslug>[\w\-\_\/]*)/log/$', 'tree',),
+ (r'^(?P<reqslug>[\w\-\_\/]*)/edit/$', 'tree',),
+ (r'^(?P<reqslug>[\w\-\_\/]*)/pdf/$', 'tree',),
+ (r'^(?P<reqslug>[\w\-\_\/]*)$', 'tree',),
)
diff --git a/bn_django/git_wiki/views.py b/bn_django/git_wiki/views.py
index 1212f44..2e66061 100644
--- a/bn_django/git_wiki/views.py
+++ b/bn_django/git_wiki/views.py
@@ -1,7 +1,7 @@
from django import forms, http, template
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, render_to_response
-from django.http import HttpResponse
+from django.http import HttpResponse, Http404
import os, commands
@@ -11,23 +11,36 @@ from settings import *
# Create your views here.
def frontpage(request):
- t = fromslug('/')
+ t = fromslug('')
t.update()
return render_to_response('git_wiki/frontpage.html', \
dict(shortlog=shortlog(), tree=t))
-def tree(request, reqslug):
- t = fromslug(reqslug)
- if t.type == 'blob':
- return item(request, reqslug)
+def tree(request, reqslug, tree=None):
+ if not tree:
+ t = fromslug(reqslug)
+ if not t:
+ raise Http404
+ if t.type == 'blob':
+ return item(request, reqslug, blob=t)
+ else:
+ t = tree
+
t.update()
+ (heads,tags) = reposcan()
return render_to_response('git_wiki/tree.html',
- dict(shortlog=shortlog(tree=t), tree=t))
+ dict(shortlog=shortlog(tree=t), tree=t,
+ heads=heads,tags=tags))
-def item(request, reqslug):
- i = fromslug(reqslug)
- if i.type == 'tree':
- return tree(request, reqslug)
+def item(request, reqslug, blob=None):
+ if not blob:
+ i = fromslug(reqslug)
+ if not i:
+ raise Http404
+ if i.type == 'tree':
+ return tree(request, reqslug)
+ else:
+ i = blob
i.update()
return render_to_response('git_wiki/item.html',
dict(item=i))
@@ -37,3 +50,12 @@ def olditem(request, hash):
i.update()
return render_to_response('git_browse/olditem.html',
dict(item=i))
+
+def view_commit(request, hash):
+ (heads, tags) = reposcan()
+ c = Commit(id=hash)
+ c.update()
+
+ return render_to_response('git_wiki/commit.html',
+ dict(heads=heads, tags=tags,
+ commit=c))
diff --git a/static/style/git_wiki.css b/static/style/git_wiki.css
index 7fc04e8..cfdc8bd 100644
--- a/static/style/git_wiki.css
+++ b/static/style/git_wiki.css
@@ -63,7 +63,7 @@ span.hash {
font-family: courier; }
-a.head {
+span.head {
color: green; }
-a.tag {
+span.tag {
color: yellow; }