diff options
-rw-r--r-- | bn_django/git_browse/models.py | 10 | ||||
-rw-r--r-- | bn_django/git_wiki/models.py | 208 | ||||
-rw-r--r-- | bn_django/git_wiki/templates/git_wiki/base.html | 11 | ||||
-rw-r--r-- | bn_django/git_wiki/templates/git_wiki/frontpage.html | 2 | ||||
-rw-r--r-- | bn_django/git_wiki/templates/git_wiki/shortlog_table | 4 | ||||
-rw-r--r-- | bn_django/git_wiki/urls.py | 8 | ||||
-rw-r--r-- | bn_django/git_wiki/views.py | 44 | ||||
-rw-r--r-- | static/style/git_wiki.css | 4 |
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; } |