diff --git a/klaus.py b/klaus.py index 88236360baf5ea1d1c852d43c997ec540c8646ac..f4624c14fd894de02f2f2dea5ebd6dee0a229249 100644 --- a/klaus.py +++ b/klaus.py @@ -1,4 +1,5 @@ import os +import stat import time from functools import wraps @@ -78,8 +79,6 @@ def get_repo(name): raise HttpError(404, 'No repository named "%s"' % name) def get_commit(repo, id): - if isinstance(repo, basestring): - repo = get_repo(repo) try: commit = repo[id] if not isinstance(commit, Commit): @@ -88,23 +87,45 @@ def get_commit(repo, id): except KeyError: raise HttpError(404, '"%s" has no commit "%s"' % (repo.name, id)) +def get_branch_or_commit(repo, id): + try: + return repo.get_branch(id) + except KeyError: + return get_commit(repo, id) + +def get_tree_or_blob_url(repo, commit_id, tree_entry): + if tree_entry.mode & stat.S_IFDIR: + view = 'view_tree' + else: + view = 'view_blob' + return app.build_url(view, + repo=repo.name, commit_id=commit_id, path=tree_entry.path) + @app.route('/') def repo_list(env): return {'repos' : app.repos.items()} @app.route('/:repo:/') def view_repo(env, repo): - redirect_to = app.build_url('view_tree', repo=repo, commit_id='master') + redirect_to = app.build_url('view_tree', repo=repo, commit_id='master', path='') return '302 Move On', {'Location' : redirect_to}, '' -@app.route('/:repo:/tree/:commit_id:/') -def view_tree(env, repo, commit_id): +@app.route('/:repo:/tree/:commit_id:/(?P<path>.*)') +def view_tree(env, repo, commit_id, path): repo = get_repo(repo) - try: - commit = repo.get_branch(commit_id) - except KeyError: - commit = get_commit(repo, commit_id) - return {'repo' : repo, 'commit' : commit} + commit = get_branch_or_commit(repo, commit_id) + files = ((name, get_tree_or_blob_url(repo, commit_id, entry)) + for name, entry in repo.listdir(commit, path)) + return {'repo' : repo, 'commit_id' : commit_id, + 'files' : files, 'path' : path} + +@app.route('/:repo:/blob/:commit_id:/(?P<path>.*)') +def view_blob(env, repo, commit_id, path): + repo = get_repo(repo) + commit = get_branch_or_commit(repo, commit_id) + directory, filename = os.path.split(path) + blob = repo[repo.get_tree(commit, directory)[filename][1]] + return {'repo' : repo, 'blob' : blob, 'path' : path, 'commit_id' : commit_id} @app.route('/:repo:/commit/:id:/') def view_commit(env, repo, id): diff --git a/repo.py b/repo.py index af34db80c8e167120292c4c845f5c8be4b85d2ca..4d3b10e5779282e86280daa243581d597455f363 100644 --- a/repo.py +++ b/repo.py @@ -20,12 +20,16 @@ class RepoWrapper(dulwich.repo.Repo): head = self[head.parents[0]] max_commits -= 1 - def listdir(self, commit=None, root=None): + def get_tree(self, commit, path): tree = self[commit.tree] - if root is not None: - for directory in root.split('/'): - tree = self[tree[directory].sha] - return tree.iteritems() + if path: + for directory in path.split('/'): + tree = self[tree[directory][1]] + return tree + + def listdir(self, commit, root=None): + tree = self.get_tree(commit, root) + return ((entry.path, entry.in_path(root)) for entry in tree.iteritems()) def commit_diff(self, commit): parent = self[commit.parents[0]] diff --git a/templates/view_blob.html b/templates/view_blob.html new file mode 100644 index 0000000000000000000000000000000000000000..b339de0329591d5637dd68c4a791d653b01d8bd7 --- /dev/null +++ b/templates/view_blob.html @@ -0,0 +1,12 @@ +{% if path %} + {% set title = '%s in %s/%s' % (path, repo.name, commit_id) %} +{% else %} + {% set title = '%s/%s' % (repo.name, commit_id) %} +{% endif %} + +{% extends 'base.html' %} +{% block content %} + +{{ blob.data|pygmentize }} + +{% endblock %} diff --git a/templates/view_tree.html b/templates/view_tree.html index 13a3249453f653551c9e2ab1477cba84a9997e28..bde19caff82b3d330bb40a4ed4fd5fcdc598524d 100644 --- a/templates/view_tree.html +++ b/templates/view_tree.html @@ -1,4 +1,9 @@ -{% set title = repo.name %} +{% if path %} + {% set title = '%s in %s/%s' % (path, repo.name, commit_id) %} +{% else %} + {% set title = '%s/%s' % (repo.name, commit_id) %} +{% endif %} + {% extends 'base.html' %} {% block content %} @@ -17,8 +22,8 @@ </ul> <ul class=tree> -{% for file, _, _ in repo.listdir(commit=commit) %} - <li>{{ file }}</li> +{% for name, url in files %} + <li><a href="{{ url }}">{{ name }}</a></li> {% endfor %} </ul>