nautilebleu / django_hg
django_hg allows managing (create, authenticate, clone/push/pull…) Mercurial repositories throught django.
Clone this repository (size: 144.8 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/nautilebleu/django_hg/
| commit 14: | 8932d6989fe4 |
| parent 13: | 16b135a6298d |
| branch: | admin |
Replace long if/elif dispatch in views.py/cmds by a __getattribute__
django_hg /
views.py
| r14:8932d6989fe4 | 243 loc | 7.1 KB | embed / history / annotate / raw / |
|---|
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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | # coding=utf-8
import os.path
from datetime import datetime
from math import ceil
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.auth import authenticate, login
from django.core.urlresolvers import reverse
from django.conf import settings as global_settings
import settings
from mercurial.error import RepoError
from django_hg.models import HgContext, HgRepository
from core.settings import MEDIA_URL
def __get_repo(request, name, rev):
"""
this private function get the repository object from the database and
returns the context view of the repository
"""
repo = get_object_or_404(HgRepository, name=name)
# Check that the user is allowed to view it
if repo.anonymous_access == False:
can_access = False
for m in repo.members() :
if request.user.id == m.user_id:
can_access = True
break
if can_access == False :
#redirect to an unauthorized page
return HttpResponseRedirect(reverse('signin'))
try:
repo.set_context(HgContext(repo, rev))
except RepoError :
raise Http404
return repo
def changeset(request, name, rev):
"""
display the file history
``name``
the name of the repository
``rev``
the revision in the changesets history
"""
repo = __get_repo(request, name, rev)
ctx = repo.get_context().repository[rev]
files = []
for f in ctx.files():
fc = ctx[f]
files.append({'name': f, 'size': len(fc.data()) })
return render_to_response('django_hg/changeset.html', {
'ctx' : {"user": ctx.user(),
"description": ctx.description(),
"date": ctx.date(),
"hash": ctx,
"rev": rev,
"files_count": len(ctx.files())
},
'files': files,
'MEDIA_URL': MEDIA_URL,
'repo' : repo,
'rev' : rev,
'user' : request.user
})
def changesets(request, name):
"""
display the changesets history of a repository
``name``
the name of the repository
"""
repo = __get_repo(request, name, 'tip')
max = repo.get_context().rev-1
page = int(request.GET.get('page', 1))
# forbid a page to be greater than the max or to be lower than one
if page > max/global_settings.DJANGO_HG_PAGER_ITEMS:
page = max/global_settings.DJANGO_HG_PAGER_ITEMS+1
elif page < 1:
page = 1
start = max-(page-1)*global_settings.DJANGO_HG_PAGER_ITEMS
end = max-(page)*global_settings.DJANGO_HG_PAGER_ITEMS
changelog = []
c = start
while c > end:
ctx = repo.get_context().repository[c]
# we pass a tuple instead of the object because it's really, really
# faster (from 12500 to 48 ms with the django repository ! )
changelog.append({"user": ctx.user(),
"description": ctx.description(),
"date": ctx.date(),
"files_count": len(ctx.files()),
"hash": ctx,
"rev": c,
})
c = c-1
if c < 0:
break
return render_to_response('django_hg/changesets.html', {
'changelog': changelog,
'end': end > 0 and end+1 or 1,
'items_per_page': global_settings.DJANGO_HG_PAGER_ITEMS,
'max': max,
'MEDIA_URL': global_settings.MEDIA_URL,
'page': page,
'repo': repo,
'start': start,
'user': request.user,
})
def commands(request, name):
"""
handles the commands sended by an hg client (clone, pull, push)
``name``
the name of the repository
"""
from mercurial import hg, ui
from mercurial.hgweb.request import wsgirequest
from mercurial.hgweb import protocol
cmds = ['between', 'branches', 'capabilities', 'changegroupsubset', 'heads']
repo = __get_repo(request, name, 'tip')
req = wsgirequest(request.META, None)
r = hg.repository(ui.ui(),
repo.repo_path)
if request.GET.get('cmd') in cmds:
resp = protocol.__getattribute__(request.GET.get('cmd'))(r, req)
return HttpResponse(resp, protocol.HGTYPE)
def filelog(request, name, rev, file):
"""
display the file history
``name``
the name of the repository
``file``
the file for which we want the history
"""
repo = __get_repo(request, name, 'tip')
ctx = repo.get_context().repository[rev]
fctx = ctx.filectx(file)
filelog = []
for fl in fctx.filelog():
l = fctx.filectx(fl)
filelog.append({
'user': l.user(),
'date': l.date(),
'description': l.description(),
'branch': l.branch(),
})
filelog.reverse()
return render_to_response('django_hg/filelog.html', {
'file': file,
'filelog': filelog,
'MEDIA_URL': global_settings.MEDIA_URL,
'path': os.path.dirname(file),
'referer': 'changesets', #request.META['HTTP_REFERER'],
'repo': repo,
'rev': rev,
'user': request.user,
})
def list(request):
"""
display a paginated list of repositories. If the user is authenticated, the
contains both public and private repositories. If not, the list contains
only public repositories
"""
page = int(request.GET.get('page', 1))
if page <= 0 :
page = 1
max = HgRepository.objects.count_for_user(request.user, 1)
if ceil(float(max)/float(settings.DJANGO_HG_PAGER_ITEMS))<page:
page = int(ceil(float(max)/float(settings.DJANGO_HG_PAGER_ITEMS)))
start = (page-1)*settings.DJANGO_HG_PAGER_ITEMS
end = page*settings.DJANGO_HG_PAGER_ITEMS
if end > max:
end = max
repositories = []
if (max > 0):
q = HgRepository.objects.get_for_user(request.user, 1)[start:end]
for repo in q:
try:
repo.set_context(HgContext(repo, 'tip'))
repositories.append(repo)
except:
pass
return render_to_response('django_hg/list.html', {
'end': end,
'items_per_page': settings.DJANGO_HG_PAGER_ITEMS,
'MEDIA_URL': settings.MEDIA_URL,
'repositories': repositories,
'page': page,
'start': start+1,
'max': int(max),
'user': request.user,
})
def detail(request, name, rev, path=''):
"""
display a repository
``name``
the name of the given repository
``rev``
the revision of the repository. By default, it's equal to ``tip``
``path``
optional. A valid path within the repository. If not given, the root of
the repository is returned
"""
repo = __get_repo(request, name, rev)
files = repo.get_context().get_tree(path)
return render_to_response('django_hg/detail.html', {
'files': files,
'MEDIA_URL': global_settings.MEDIA_URL,
'path': path,
'repo': repo,
'rev': rev,
'user': request.user
})
|
