Blame progit/repo.py

Pierre-Yves Chibon 47950c
#-*- coding: utf-8 -*-
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
"""
Pierre-Yves Chibon 47950c
 (c) 2014 - Copyright Red Hat Inc
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
 Authors:
Pierre-Yves Chibon 47950c
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
"""
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
import flask
Pierre-Yves Chibon 47950c
import os
Pierre-Yves Chibon 47950c
from math import ceil
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
import pygit2
Pierre-Yves Chibon 47950c
from sqlalchemy.exc import SQLAlchemyError
Pierre-Yves Chibon 47950c
from pygments import highlight
Pierre-Yves Chibon 47950c
from pygments.lexers import guess_lexer
Pierre-Yves Chibon 47950c
from pygments.lexers.text import DiffLexer
Pierre-Yves Chibon 47950c
from pygments.formatters import HtmlFormatter
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
import progit.exceptions
Pierre-Yves Chibon 47950c
import progit.lib
Pierre-Yves Chibon 47950c
import progit.forms
Pierre-Yves Chibon 47950c
from progit import APP, SESSION, LOG, __get_file_in_tree, cla_required
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>')</repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>')</repo></username>
Pierre-Yves Chibon 2c6a7c
def view_repo(repo, username=None):
Pierre-Yves Chibon 47950c
    """ Front page of a specific repo.
Pierre-Yves Chibon 47950c
    """
Pierre-Yves Chibon 47950c
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if repo is None:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    reponame = os.path.join(APP.config['GIT_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        reponame = os.path.join(APP.config['FORK_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    repo_obj = pygit2.Repository(reponame)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    cnt = 0
Pierre-Yves Chibon 47950c
    last_commits = []
Pierre-Yves Chibon 47950c
    tree = []
Pierre-Yves Chibon 47950c
    if not repo_obj.is_empty:
Pierre-Yves Chibon 47950c
        for commit in repo_obj.walk(
Pierre-Yves Chibon 47950c
                repo_obj.head.target, pygit2.GIT_SORT_TIME):
Pierre-Yves Chibon 47950c
            last_commits.append(commit)
Pierre-Yves Chibon 47950c
            cnt += 1
Pierre-Yves Chibon 47950c
            if cnt == 10:
Pierre-Yves Chibon 47950c
                break
Pierre-Yves Chibon 47950c
        tree = sorted(last_commits[0].tree, key=lambda x: x.filemode)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    readme = None
Pierre-Yves Chibon 47950c
    for i in tree:
Pierre-Yves Chibon 47950c
        name, ext = os.path.splitext(i.name)
Pierre-Yves Chibon 47950c
        if name == 'README':
Pierre-Yves Chibon 47950c
            content = repo_obj[i.oid].data
Pierre-Yves Chibon 47950c
            readme = progit.doc_utils.convert_readme(content, ext)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    diff_commits = []
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        parentname = os.path.join(
Pierre-Yves Chibon 47950c
            APP.config['GIT_FOLDER'], repo.parent.path)
Pierre-Yves Chibon 47950c
        orig_repo = pygit2.Repository(parentname)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
        if not repo_obj.is_empty and not orig_repo.is_empty:
Pierre-Yves Chibon 47950c
            orig_commit = orig_repo[orig_repo.head.target]
Pierre-Yves Chibon 47950c
            repo_commit = repo_obj[repo_obj.head.target]
Pierre-Yves Chibon 47950c
            diff = repo_obj.diff(
Pierre-Yves Chibon 47950c
                repo_obj.revparse_single(orig_commit.oid.hex),
Pierre-Yves Chibon 47950c
                repo_obj.revparse_single(repo_commit.oid.hex))
Pierre-Yves Chibon 47950c
            for commit in repo_obj.walk(
Pierre-Yves Chibon 47950c
                    repo_obj.head.target, pygit2.GIT_SORT_TIME):
Pierre-Yves Chibon 47950c
                if commit.oid.hex == orig_commit.oid.hex:
Pierre-Yves Chibon 47950c
                    break
Pierre-Yves Chibon 47950c
                diff_commits.append(commit.oid.hex)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    return flask.render_template(
Pierre-Yves Chibon 47950c
        'repo_info.html',
Pierre-Yves Chibon 47950c
        select='overview',
Pierre-Yves Chibon 47950c
        repo=repo,
Pierre-Yves Chibon 47950c
        repo_obj=repo_obj,
Pierre-Yves Chibon 47950c
        username=username,
Pierre-Yves Chibon 47950c
        readme=readme,
Pierre-Yves Chibon 47950c
        branches=sorted(repo_obj.listall_branches()),
Pierre-Yves Chibon 47950c
        branchname='master',
Pierre-Yves Chibon 47950c
        last_commits=last_commits,
Pierre-Yves Chibon 47950c
        tree=tree,
Pierre-Yves Chibon 47950c
        diff_commits=diff_commits,
Pierre-Yves Chibon 47950c
    )
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/branch/<branchname>')</branchname></repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/branch/<branchname>')</branchname></repo></username>
Pierre-Yves Chibon 2c6a7c
def view_repo_branch(repo, branchname, username=None):
Pierre-Yves Chibon 47950c
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if not repo:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    reponame = os.path.join(APP.config['GIT_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        reponame = os.path.join(APP.config['FORK_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    repo_obj = pygit2.Repository(reponame)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if not branchname in repo_obj.listall_branches():
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Branch no found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    branch = repo_obj.lookup_branch(branchname)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    cnt = 0
Pierre-Yves Chibon 47950c
    last_commits = []
Pierre-Yves Chibon 47950c
    for commit in repo_obj.walk(branch.get_object().hex, pygit2.GIT_SORT_TIME):
Pierre-Yves Chibon 47950c
        last_commits.append(commit)
Pierre-Yves Chibon 47950c
        cnt += 1
Pierre-Yves Chibon 47950c
        if cnt == 10:
Pierre-Yves Chibon 47950c
            break
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    diff_commits = []
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        parentname = os.path.join(
Pierre-Yves Chibon 47950c
            APP.config['GIT_FOLDER'], repo.parent.path)
Pierre-Yves Chibon 47950c
        orig_repo = pygit2.Repository(parentname)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
        if not repo_obj.is_empty and not orig_repo.is_empty:
Pierre-Yves Chibon 47950c
            orig_commit = orig_repo[orig_repo.head.target]
Pierre-Yves Chibon 47950c
            repo_commit = repo_obj[branch.get_object().hex]
Pierre-Yves Chibon 47950c
            diff = repo_obj.diff(
Pierre-Yves Chibon 47950c
                repo_obj.revparse_single(orig_commit.oid.hex),
Pierre-Yves Chibon 47950c
                repo_obj.revparse_single(repo_commit.oid.hex))
Pierre-Yves Chibon 47950c
            for commit in repo_obj.walk(
Pierre-Yves Chibon 47950c
                    repo_obj.head.target, pygit2.GIT_SORT_TIME):
Pierre-Yves Chibon 47950c
                if commit.oid.hex == orig_commit.oid.hex:
Pierre-Yves Chibon 47950c
                    break
Pierre-Yves Chibon 47950c
                diff_commits.append(commit.oid.hex)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    return flask.render_template(
Pierre-Yves Chibon 47950c
        'repo_info.html',
Pierre-Yves Chibon 47950c
        select='overview',
Pierre-Yves Chibon 47950c
        repo=repo,
Pierre-Yves Chibon 47950c
        username=username,
Pierre-Yves Chibon 47950c
        branches=sorted(repo_obj.listall_branches()),
Pierre-Yves Chibon 47950c
        branchname=branchname,
Pierre-Yves Chibon 47950c
        last_commits=last_commits,
Pierre-Yves Chibon 47950c
        tree=sorted(last_commits[0].tree, key=lambda x: x.filemode),
Pierre-Yves Chibon 47950c
        diff_commits=diff_commits,
Pierre-Yves Chibon 47950c
    )
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/log')</repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/log/<branchname>')</branchname></repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/log')</repo></username>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/log/<branchname>')</branchname></repo></username>
Pierre-Yves Chibon 2c6a7c
def view_log(repo, branchname=None, username=None):
Pierre-Yves Chibon 47950c
    """ Displays the logs of the specified repo.
Pierre-Yves Chibon 47950c
    """
Pierre-Yves Chibon 47950c
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if not repo:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    reponame = os.path.join(APP.config['GIT_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        reponame = os.path.join(APP.config['FORK_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    repo_obj = pygit2.Repository(reponame)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if branchname and not branchname in repo_obj.listall_branches():
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Branch no found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if branchname:
Pierre-Yves Chibon 47950c
        branch = repo_obj.lookup_branch(branchname)
Pierre-Yves Chibon 47950c
    else:
Pierre-Yves Chibon 47950c
        branch = repo_obj.lookup_branch('master')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    try:
Pierre-Yves Chibon 47950c
        page = int(flask.request.args.get('page', 1))
Pierre-Yves Chibon 47950c
    except ValueError:
Pierre-Yves Chibon 47950c
        page = 1
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    limit = APP.config['ITEM_PER_PAGE']
Pierre-Yves Chibon 47950c
    start = limit * (page - 1)
Pierre-Yves Chibon 47950c
    end = limit * page
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    n_commits = 0
Pierre-Yves Chibon 47950c
    last_commits = []
Pierre-Yves Chibon c184e7
    if branch:
Pierre-Yves Chibon c184e7
        for commit in repo_obj.walk(
Pierre-Yves Chibon c184e7
                branch.get_object().hex, pygit2.GIT_SORT_TIME):
Pierre-Yves Chibon c184e7
            if n_commits >= start and n_commits <= end:
Pierre-Yves Chibon c184e7
                last_commits.append(commit)
Pierre-Yves Chibon c184e7
            n_commits += 1
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    total_page = int(ceil(n_commits / float(limit)))
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    diff_commits = []
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        parentname = os.path.join(
Pierre-Yves Chibon 47950c
            APP.config['GIT_FOLDER'], repo.parent.path)
Pierre-Yves Chibon 47950c
        orig_repo = pygit2.Repository(parentname)
Pierre-Yves Chibon 47950c
        if not repo_obj.is_empty and not orig_repo.is_empty:
Pierre-Yves Chibon 47950c
            orig_commit = orig_repo[orig_repo.head.target]
Pierre-Yves Chibon 47950c
            repo_commit = repo_obj[branch.get_object().hex]
Pierre-Yves Chibon 47950c
            diff = repo_obj.diff(
Pierre-Yves Chibon 47950c
                repo_obj.revparse_single(orig_commit.oid.hex),
Pierre-Yves Chibon 47950c
                repo_obj.revparse_single(repo_commit.oid.hex))
Pierre-Yves Chibon 47950c
            for commit in repo_obj.walk(
Pierre-Yves Chibon 47950c
                    repo_obj.head.target, pygit2.GIT_SORT_TIME):
Pierre-Yves Chibon 47950c
                if commit.oid.hex == orig_commit.oid.hex:
Pierre-Yves Chibon 47950c
                    break
Pierre-Yves Chibon 47950c
                diff_commits.append(commit.oid.hex)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    origin = 'view_log'
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    return flask.render_template(
Pierre-Yves Chibon 47950c
        'repo_info.html',
Pierre-Yves Chibon 47950c
        select='logs',
Pierre-Yves Chibon 47950c
        origin=origin,
Pierre-Yves Chibon c184e7
        repo_obj=repo_obj,
Pierre-Yves Chibon 47950c
        repo=repo,
Pierre-Yves Chibon 47950c
        username=username,
Pierre-Yves Chibon 47950c
        branches=sorted(repo_obj.listall_branches()),
Pierre-Yves Chibon 47950c
        branchname=branchname,
Pierre-Yves Chibon 47950c
        last_commits=last_commits,
Pierre-Yves Chibon 47950c
        diff_commits=diff_commits,
Pierre-Yves Chibon 47950c
        page=page,
Pierre-Yves Chibon 47950c
        total_page=total_page,
Pierre-Yves Chibon 47950c
    )
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/blob/<identifier>/<path:filename>')</path:filename></identifier></repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/blob/<identifier>/<path:filename>')</path:filename></identifier></repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/blob/<identifier>/<path:filename>')</path:filename></identifier></repo></username>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/blob/<identifier>/<path:filename>')</path:filename></identifier></repo></username>
Pierre-Yves Chibon 2c6a7c
def view_file(repo, identifier, filename, username=None):
Pierre-Yves Chibon 47950c
    """ Displays the content of a file or a tree for the specified repo.
Pierre-Yves Chibon 47950c
    """
Pierre-Yves Chibon 47950c
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if not repo:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    reponame = os.path.join(APP.config['GIT_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        reponame = os.path.join(APP.config['FORK_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    repo_obj = pygit2.Repository(reponame)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if identifier in repo_obj.listall_branches():
Pierre-Yves Chibon 47950c
        branchname = identifier
Pierre-Yves Chibon 47950c
        branch = repo_obj.lookup_branch(identifier)
Pierre-Yves Chibon 47950c
        commit = branch.get_object()
Pierre-Yves Chibon 47950c
    else:
Pierre-Yves Chibon 47950c
        try:
Pierre-Yves Chibon 47950c
            commit = repo_obj.get(identifier)
Pierre-Yves Chibon 47950c
            branchname = identifier
Pierre-Yves Chibon 47950c
        except ValueError:
Pierre-Yves Chibon 47950c
            # If it's not a commit id then it's part of the filename
Pierre-Yves Chibon 47950c
            commit = repo_obj[repo_obj.head.target]
Pierre-Yves Chibon 47950c
            branchname = 'master'
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    content = __get_file_in_tree(repo_obj, commit.tree, filename.split('/'))
Pierre-Yves Chibon 47950c
    if not content:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'File not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    content = repo_obj[content.oid]
Pierre-Yves Chibon 47950c
    if isinstance(content, pygit2.Blob):
Pierre-Yves Chibon 47950c
        content = highlight(
Pierre-Yves Chibon 47950c
            content.data,
Pierre-Yves Chibon 47950c
            guess_lexer(content.data),
Pierre-Yves Chibon 47950c
            HtmlFormatter(
Pierre-Yves Chibon 47950c
                noclasses=True,
Pierre-Yves Chibon 47950c
                style="tango",)
Pierre-Yves Chibon 47950c
        )
Pierre-Yves Chibon 47950c
        output_type = 'file'
Pierre-Yves Chibon 47950c
    else:
Pierre-Yves Chibon 47950c
        content = sorted(content, key=lambda x: x.filemode)
Pierre-Yves Chibon 47950c
        output_type = 'tree'
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    return flask.render_template(
Pierre-Yves Chibon 47950c
        'file.html',
Pierre-Yves Chibon 47950c
        select='tree',
Pierre-Yves Chibon 47950c
        repo=repo,
Pierre-Yves Chibon 47950c
        username=username,
Pierre-Yves Chibon 47950c
        branchname=branchname,
Pierre-Yves Chibon 47950c
        filename=filename,
Pierre-Yves Chibon 47950c
        content=content,
Pierre-Yves Chibon 47950c
        output_type=output_type,
Pierre-Yves Chibon 47950c
    )
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/<commitid>')</commitid></repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/<commitid>')</commitid></repo></username>
Pierre-Yves Chibon 2c6a7c
def view_commit(repo, commitid, username=None):
Pierre-Yves Chibon 47950c
    """ Render a commit in a repo
Pierre-Yves Chibon 47950c
    """
Pierre-Yves Chibon 47950c
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if not repo:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    reponame = os.path.join(APP.config['GIT_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        reponame = os.path.join(APP.config['FORK_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    repo_obj = pygit2.Repository(reponame)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    try:
Pierre-Yves Chibon 47950c
        commit = repo_obj.get(commitid)
Pierre-Yves Chibon 47950c
    except ValueError:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Commit not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if commit.parents:
Pierre-Yves Chibon 47950c
        diff = commit.tree.diff_to_tree()
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
        parent = repo_obj.revparse_single('%s^' % commitid)
Pierre-Yves Chibon 47950c
        diff = repo_obj.diff(parent, commit)
Pierre-Yves Chibon 47950c
    else:
Pierre-Yves Chibon 47950c
        # First commit in the repo
Pierre-Yves Chibon 47950c
        diff = commit.tree.diff_to_tree(swap=True)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    html_diff = highlight(
Pierre-Yves Chibon 47950c
        diff.patch,
Pierre-Yves Chibon 47950c
        DiffLexer(),
Pierre-Yves Chibon 47950c
        HtmlFormatter(
Pierre-Yves Chibon 47950c
            noclasses=True,
Pierre-Yves Chibon 47950c
            style="tango",)
Pierre-Yves Chibon 47950c
    )
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    return flask.render_template(
Pierre-Yves Chibon 47950c
        'commit.html',
Pierre-Yves Chibon 47950c
        select='logs',
Pierre-Yves Chibon 47950c
        repo=repo,
Pierre-Yves Chibon 47950c
        username=username,
Pierre-Yves Chibon 47950c
        commitid=commitid,
Pierre-Yves Chibon 47950c
        commit=commit,
Pierre-Yves Chibon 47950c
        diff=diff,
Pierre-Yves Chibon 47950c
        html_diff=html_diff,
Pierre-Yves Chibon 47950c
    )
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/tree/')</repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/tree/<identifier>')</identifier></repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/tree/')</repo></username>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/tree/<identifier>')</identifier></repo></username>
Pierre-Yves Chibon 2c6a7c
def view_tree(repo, identifier=None, username=None):
Pierre-Yves Chibon 47950c
    """ Render the tree of the repo
Pierre-Yves Chibon 47950c
    """
Pierre-Yves Chibon 47950c
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if repo is None:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    reponame = os.path.join(APP.config['GIT_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    if repo.is_fork:
Pierre-Yves Chibon 47950c
        reponame = os.path.join(APP.config['FORK_FOLDER'], repo.path)
Pierre-Yves Chibon 47950c
    repo_obj = pygit2.Repository(reponame)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon c184e7
    branchname = None
Pierre-Yves Chibon c184e7
    content = None
Pierre-Yves Chibon c184e7
    output_type = None
Pierre-Yves Chibon c184e7
    if not repo_obj.is_empty:
Pierre-Yves Chibon c184e7
        if identifier in repo_obj.listall_branches():
Pierre-Yves Chibon 47950c
            branchname = identifier
Pierre-Yves Chibon c184e7
            branch = repo_obj.lookup_branch(identifier)
Pierre-Yves Chibon c184e7
            commit = branch.get_object()
Pierre-Yves Chibon c184e7
        else:
Pierre-Yves Chibon c184e7
            try:
Pierre-Yves Chibon c184e7
                commit = repo_obj.get(identifier)
Pierre-Yves Chibon c184e7
                branchname = identifier
Pierre-Yves Chibon c184e7
            except (ValueError, TypeError):
Pierre-Yves Chibon c184e7
                # If it's not a commit id then it's part of the filename
Pierre-Yves Chibon c184e7
                commit = repo_obj[repo_obj.head.target]
Pierre-Yves Chibon c184e7
                branchname = 'master'
Pierre-Yves Chibon c184e7
Pierre-Yves Chibon c184e7
        content = sorted(commit.tree, key=lambda x: x.filemode)
Pierre-Yves Chibon c184e7
        output_type = 'tree'
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    return flask.render_template(
Pierre-Yves Chibon 47950c
        'file.html',
Pierre-Yves Chibon 47950c
        select='tree',
Pierre-Yves Chibon c184e7
        repo_obj=repo_obj,
Pierre-Yves Chibon 47950c
        repo=repo,
Pierre-Yves Chibon 47950c
        username=username,
Pierre-Yves Chibon 47950c
        branchname=branchname,
Pierre-Yves Chibon 47950c
        filename='',
Pierre-Yves Chibon 47950c
        content=content,
Pierre-Yves Chibon 47950c
        output_type=output_type,
Pierre-Yves Chibon 47950c
    )
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 2c6a7c
@APP.route('/<repo>/forks')</repo>
Pierre-Yves Chibon 2c6a7c
@APP.route('/fork/<username>/<repo>/forks')</repo></username>
Pierre-Yves Chibon 2c6a7c
def view_forks(repo, username=None):
Pierre-Yves Chibon 2c6a7c
    """ Presents all the forks of the project.
Pierre-Yves Chibon 47950c
    """
Pierre-Yves Chibon 47950c
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    if not repo:
Pierre-Yves Chibon 47950c
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 47950c
Pierre-Yves Chibon 47950c
    return flask.render_template(
Pierre-Yves Chibon 47950c
        'forks.html',
Pierre-Yves Chibon 47950c
        select='forks',
Pierre-Yves Chibon ea8735
        username=username,
Pierre-Yves Chibon 47950c
        repo=repo,
Pierre-Yves Chibon 47950c
    )