aboutsummaryrefslogtreecommitdiffstats
path: root/bn_django/git_wiki/models.py
blob: 4201a841b2730a82d9d575950f8d65d996e84901 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
from django.db import models
from settings import *
from django.conf import settings

try:
    ADMIN_URL = settings.ADMIN_URL
except AttributeError:
    ADMIN_URL='/admin'
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)
    id = models.CharField("hash", maxlength=40,blank=False,primary_key=True)
    name = models.CharField("name of dir", maxlength=128,blank=False)
    type = 'tree'
    def slug(self):
        #TODO: secure this
        return self.name.strip().lower()

    class Admin: 
        ordering = ['path','name']

    def __str__(self):
        return self.name
    def get_absolute_url(self):
        return "/k/%s/" % self.slug()
    def get_admin_url(self):
        return "%s/k/%s/" % (ADMIN_URL, self.id)

class Item(models.Model):
    mode = models.CharField("file mode/permissions", blank=False,maxlength=4)
    path = models.CharField("relative path from repo base", maxlength=512)
    id = models.CharField("hash", maxlength=40,blank=False,primary_key=True)
    name = models.CharField("name of dir", maxlength=128,blank=False)
    size = models.IntegerField("filesize in byte", maxlength=128,blank=False)
    contents = models.TextField("ASCII contents of the file")
    type='blob'

    class Admin: 
        ordering = ['path','name']
    def __str__(self):
        return self.name
    def get_absolute_url(self):
        return "/k/%s/" % self.slug()
    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()
        self.contents = commands.getoutput(GITPREFIX + ' cat-file -p  ' \
                + self.id) 
        self.size = commands.getoutput(GITPREFIX + ' cat-file -s  ' + self.id)
        return

class Commit(models.Model):
    id = models.CharField("hash", maxlength=40,blank=False,primary_key=True)
    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")
    comment = models.TextField("Notes on the commit")
    parenthash = models.CharField("parent's hash", maxlength=40)
    #TODO: parent = models.ForeignKey()
    treehash = models.CharField("tree object's hash", maxlength=40)
    tree = models.ForeignKey(Tree)
    type='commit'

    class Admin: 
        ordering = ['commit_date','author_date','author']
    def __str__(self):
        return self.id
    def get_absolute_url(self):
        return "/k/commit/%s/" % (self.id)
    def get_admin_url(self):
        return "%s/k/commit/%s/" % (ADMIN_URL, self.id)
    
    def update(self):
        import commands,time
        if (not self.id): return
        
        self.id = self.id.strip()
        raw = commands.getoutput(GITPREFIX + ' cat-file -p  ' + self.id)
        self.rawdiff = commands.getoutput(GITPREFIX + ' diff ' + self.id \
                +' | cat')
        
        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:]:
                self.comment += str(l) + '\n'
        else:
            self.comment = '(none)'
        return