|
Pierre-Yves Chibon |
2088eb |
#-*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Pierre-Yves Chibon |
2088eb |
(c) 2014 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
Authors:
|
|
Pierre-Yves Chibon |
2088eb |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
import flask
|
|
Pierre-Yves Chibon |
2088eb |
import os
|
|
Pierre-Yves Chibon |
2088eb |
from math import ceil
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
import pygit2
|
|
Pierre-Yves Chibon |
2088eb |
from sqlalchemy.exc import SQLAlchemyError
|
|
Pierre-Yves Chibon |
2088eb |
from pygments import highlight
|
|
Pierre-Yves Chibon |
2088eb |
from pygments.lexers import guess_lexer
|
|
Pierre-Yves Chibon |
2088eb |
from pygments.lexers.text import DiffLexer
|
|
Pierre-Yves Chibon |
2088eb |
from pygments.formatters import HtmlFormatter
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
8a621f |
import progit.exceptions
|
|
Pierre-Yves Chibon |
8a621f |
import progit.lib
|
|
Pierre-Yves Chibon |
8a621f |
import progit.forms
|
|
Pierre-Yves Chibon |
2088eb |
from progit import APP, SESSION, LOG
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
### Application
|
|
Pierre-Yves Chibon |
2088eb |
@APP.route('/')
|
|
Pierre-Yves Chibon |
2088eb |
def index():
|
|
Pierre-Yves Chibon |
2088eb |
""" Front page of the application.
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Pierre-Yves Chibon |
2088eb |
page = flask.request.args.get('page', 1)
|
|
Pierre-Yves Chibon |
377f7e |
try:
|
|
Pierre-Yves Chibon |
377f7e |
page = int(page)
|
|
Pierre-Yves Chibon |
377f7e |
except ValueError:
|
|
Pierre-Yves Chibon |
377f7e |
page = 1
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
377f7e |
limit = APP.config['ITEM_PER_PAGE']
|
|
Pierre-Yves Chibon |
377f7e |
start = limit * (page - 1)
|
|
Pierre-Yves Chibon |
377f7e |
|
|
Pierre-Yves Chibon |
d5f0ea |
repos = progit.lib.list_projects(SESSION, fork=False, start=start, limit=limit)
|
|
Pierre-Yves Chibon |
d5f0ea |
num_repos = progit.lib.list_projects(SESSION, fork=False, count=True)
|
|
Pierre-Yves Chibon |
af5896 |
|
|
Mathieu Bridon |
eb729c |
total_page = int(ceil(num_repos / float(limit)))
|
|
Pierre-Yves Chibon |
af5896 |
|
|
Pierre-Yves Chibon |
af5896 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
af5896 |
'index.html',
|
|
Pierre-Yves Chibon |
91a7c0 |
repos=repos,
|
|
Pierre-Yves Chibon |
af5896 |
total_page=total_page,
|
|
Pierre-Yves Chibon |
af5896 |
page=page,
|
|
Pierre-Yves Chibon |
af5896 |
)
|
|
Pierre-Yves Chibon |
af5896 |
|
|
Pierre-Yves Chibon |
af5896 |
|
|
Pierre-Yves Chibon |
8946a0 |
@APP.route('/users/')
|
|
Pierre-Yves Chibon |
8946a0 |
def view_users():
|
|
Pierre-Yves Chibon |
8946a0 |
""" Present the list of users.
|
|
Pierre-Yves Chibon |
8946a0 |
"""
|
|
Pierre-Yves Chibon |
8946a0 |
page = flask.request.args.get('page', 1)
|
|
Pierre-Yves Chibon |
8946a0 |
try:
|
|
Pierre-Yves Chibon |
8946a0 |
page = int(page)
|
|
Pierre-Yves Chibon |
8946a0 |
except ValueError:
|
|
Pierre-Yves Chibon |
8946a0 |
page = 1
|
|
Pierre-Yves Chibon |
8946a0 |
|
|
Pierre-Yves Chibon |
8946a0 |
## TODO: retrieve this from the DB
|
|
Pierre-Yves Chibon |
8946a0 |
users = ['pingou']
|
|
Pierre-Yves Chibon |
8946a0 |
|
|
Pierre-Yves Chibon |
8946a0 |
limit = APP.config['ITEM_PER_PAGE']
|
|
Pierre-Yves Chibon |
8946a0 |
start = limit * (page - 1)
|
|
Pierre-Yves Chibon |
8946a0 |
end = limit * page
|
|
Pierre-Yves Chibon |
8946a0 |
users_length = len(users)
|
|
Pierre-Yves Chibon |
8946a0 |
users = users[start:end]
|
|
Pierre-Yves Chibon |
8946a0 |
|
|
Pierre-Yves Chibon |
8946a0 |
total_page = int(ceil(users_length / float(limit)))
|
|
Pierre-Yves Chibon |
8946a0 |
|
|
Pierre-Yves Chibon |
8946a0 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
8946a0 |
'user_list.html',
|
|
Pierre-Yves Chibon |
8946a0 |
users=users,
|
|
Pierre-Yves Chibon |
8946a0 |
total_page=total_page,
|
|
Pierre-Yves Chibon |
8946a0 |
page=page,
|
|
Pierre-Yves Chibon |
8946a0 |
)
|
|
Pierre-Yves Chibon |
8946a0 |
|
|
Pierre-Yves Chibon |
8946a0 |
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/user/<username>')</username>
|
|
Pierre-Yves Chibon |
078ca3 |
def view_user(username):
|
|
Pierre-Yves Chibon |
af5896 |
""" Front page of a specific user.
|
|
Pierre-Yves Chibon |
af5896 |
"""
|
|
Pierre-Yves Chibon |
af5896 |
|
|
Pierre-Yves Chibon |
c5efd8 |
repopage = flask.request.args.get('repopage', 1)
|
|
Pierre-Yves Chibon |
af5896 |
try:
|
|
Pierre-Yves Chibon |
c5efd8 |
repopage = int(repopage)
|
|
Pierre-Yves Chibon |
af5896 |
except ValueError:
|
|
Pierre-Yves Chibon |
c5efd8 |
repopage = 1
|
|
Pierre-Yves Chibon |
377f7e |
|
|
Pierre-Yves Chibon |
c5efd8 |
forkpage = flask.request.args.get('forkpage', 1)
|
|
Pierre-Yves Chibon |
c5efd8 |
try:
|
|
Pierre-Yves Chibon |
c5efd8 |
forkpage = int(forkpage)
|
|
Pierre-Yves Chibon |
c5efd8 |
except ValueError:
|
|
Pierre-Yves Chibon |
c5efd8 |
forkpage = 1
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
af5896 |
limit = APP.config['ITEM_PER_PAGE']
|
|
Pierre-Yves Chibon |
c5efd8 |
repo_start = limit * (repopage - 1)
|
|
Pierre-Yves Chibon |
c5efd8 |
fork_start = limit * (forkpage - 1)
|
|
Pierre-Yves Chibon |
c5efd8 |
|
|
Pierre-Yves Chibon |
c5efd8 |
repos = progit.lib.list_projects(
|
|
Pierre-Yves Chibon |
c5efd8 |
SESSION,
|
|
Pierre-Yves Chibon |
c5efd8 |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
c5efd8 |
fork=False,
|
|
Pierre-Yves Chibon |
c5efd8 |
start=repo_start,
|
|
Pierre-Yves Chibon |
c5efd8 |
limit=limit)
|
|
Pierre-Yves Chibon |
c5efd8 |
repos_length = progit.lib.list_projects(
|
|
Pierre-Yves Chibon |
c5efd8 |
SESSION,
|
|
Pierre-Yves Chibon |
c5efd8 |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
c5efd8 |
fork=False,
|
|
Pierre-Yves Chibon |
c5efd8 |
count=True)
|
|
Pierre-Yves Chibon |
c5efd8 |
|
|
Pierre-Yves Chibon |
c5efd8 |
forks = progit.lib.list_projects(
|
|
Pierre-Yves Chibon |
c5efd8 |
SESSION,
|
|
Pierre-Yves Chibon |
c5efd8 |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
c5efd8 |
fork=True,
|
|
Pierre-Yves Chibon |
c5efd8 |
start=fork_start,
|
|
Pierre-Yves Chibon |
c5efd8 |
limit=limit)
|
|
Pierre-Yves Chibon |
c5efd8 |
forks_length = progit.lib.list_projects(
|
|
Pierre-Yves Chibon |
c5efd8 |
SESSION,
|
|
Pierre-Yves Chibon |
c5efd8 |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
c5efd8 |
fork=True,
|
|
Pierre-Yves Chibon |
c5efd8 |
count=True)
|
|
Pierre-Yves Chibon |
c5efd8 |
|
|
Pierre-Yves Chibon |
c5efd8 |
total_page_repos = int(ceil(repos_length / float(limit)))
|
|
Pierre-Yves Chibon |
c5efd8 |
total_page_forks = int(ceil(forks_length / float(limit)))
|
|
Pierre-Yves Chibon |
af5896 |
|
|
Pierre-Yves Chibon |
402b52 |
repos_obj = [
|
|
Pierre-Yves Chibon |
402b52 |
pygit2.Repository(
|
|
Pierre-Yves Chibon |
c5efd8 |
os.path.join(APP.config['GIT_FOLDER'], repo.path))
|
|
Pierre-Yves Chibon |
402b52 |
for repo in repos]
|
|
Pierre-Yves Chibon |
402b52 |
|
|
Pierre-Yves Chibon |
c5efd8 |
forks_obj = [
|
|
Pierre-Yves Chibon |
c5efd8 |
pygit2.Repository(
|
|
Pierre-Yves Chibon |
c5efd8 |
os.path.join(APP.config['FORK_FOLDER'], username, repo.path))
|
|
Pierre-Yves Chibon |
c5efd8 |
for repo in forks]
|
|
Pierre-Yves Chibon |
c5efd8 |
|
|
Pierre-Yves Chibon |
2088eb |
return flask.render_template(
|
|
Pierre-Yves Chibon |
af5896 |
'user_info.html',
|
|
Pierre-Yves Chibon |
078ca3 |
username=username,
|
|
Pierre-Yves Chibon |
2088eb |
repos=repos,
|
|
Pierre-Yves Chibon |
2088eb |
repos_obj=repos_obj,
|
|
Pierre-Yves Chibon |
c5efd8 |
total_page_repos=total_page_repos,
|
|
Pierre-Yves Chibon |
c5efd8 |
forks=forks,
|
|
Pierre-Yves Chibon |
c5efd8 |
forks_obj=forks_obj,
|
|
Pierre-Yves Chibon |
c5efd8 |
total_page_forks=total_page_forks,
|
|
Pierre-Yves Chibon |
c5efd8 |
repopage=repopage,
|
|
Pierre-Yves Chibon |
c5efd8 |
forkpage=forkpage,
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
8a621f |
@APP.route('/new/', methods=('GET', 'POST'))
|
|
Pierre-Yves Chibon |
8a621f |
def new_project():
|
|
Pierre-Yves Chibon |
8a621f |
""" Form to create a new project.
|
|
Pierre-Yves Chibon |
8a621f |
"""
|
|
Pierre-Yves Chibon |
8a621f |
form = progit.forms.ProjectForm()
|
|
Pierre-Yves Chibon |
8a621f |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
8a621f |
name = form.name.data
|
|
Pierre-Yves Chibon |
8a621f |
description = form.description.data
|
|
Pierre-Yves Chibon |
8a621f |
|
|
Pierre-Yves Chibon |
8a621f |
try:
|
|
Pierre-Yves Chibon |
8a621f |
message = progit.lib.new_project(
|
|
Pierre-Yves Chibon |
8a621f |
SESSION,
|
|
Pierre-Yves Chibon |
8a621f |
name=name,
|
|
Pierre-Yves Chibon |
8a621f |
description=description,
|
|
Pierre-Yves Chibon |
8a621f |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
8a621f |
folder=APP.config['GIT_FOLDER'],
|
|
Pierre-Yves Chibon |
8a621f |
)
|
|
Pierre-Yves Chibon |
8a621f |
SESSION.commit()
|
|
Pierre-Yves Chibon |
8a621f |
flask.flash(message)
|
|
Pierre-Yves Chibon |
8a621f |
return flask.redirect(flask.url_for('view_repo', repo=name))
|
|
Pierre-Yves Chibon |
8a621f |
except progit.exceptions.ProgitException, err:
|
|
Pierre-Yves Chibon |
8a621f |
flask.flash(str(err), 'error')
|
|
Pierre-Yves Chibon |
8a621f |
except SQLAlchemyError, err: # pragma: no cover
|
|
Pierre-Yves Chibon |
8a621f |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
8a621f |
flask.flash(str(err), 'error')
|
|
Pierre-Yves Chibon |
8a621f |
|
|
Pierre-Yves Chibon |
8a621f |
return flask.render_template(
|
|
Pierre-Yves Chibon |
8a621f |
'new_project.html',
|
|
Pierre-Yves Chibon |
8a621f |
form=form,
|
|
Pierre-Yves Chibon |
8a621f |
)
|
|
Pierre-Yves Chibon |
8a621f |
|
|
Pierre-Yves Chibon |
cbf031 |
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>')</repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
def view_repo(repo):
|
|
Pierre-Yves Chibon |
2088eb |
""" Front page of a specific repo.
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Mathieu Bridon |
998605 |
repo = progit.lib.get_project(SESSION, repo)
|
|
Mathieu Bridon |
998605 |
|
|
Mathieu Bridon |
998605 |
if repo is None:
|
|
Pierre-Yves Chibon |
2088eb |
flask.abort(404)
|
|
Mathieu Bridon |
998605 |
|
|
Mathieu Bridon |
998605 |
repo_obj = pygit2.Repository(os.path.join(APP.config["GIT_FOLDER"],
|
|
Mathieu Bridon |
998605 |
repo.path))
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
cnt = 0
|
|
Pierre-Yves Chibon |
2088eb |
last_commits = []
|
|
Pierre-Yves Chibon |
0fa300 |
tree = []
|
|
Pierre-Yves Chibon |
0fa300 |
if not repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
cbf031 |
for commit in repo_obj.walk(
|
|
Pierre-Yves Chibon |
cbf031 |
repo_obj.head.target, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
0fa300 |
last_commits.append(commit)
|
|
Pierre-Yves Chibon |
0fa300 |
cnt += 1
|
|
Pierre-Yves Chibon |
0fa300 |
if cnt == 10:
|
|
Pierre-Yves Chibon |
0fa300 |
break
|
|
Pierre-Yves Chibon |
0fa300 |
tree = sorted(last_commits[0].tree, key=lambda x: x.filemode)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
return flask.render_template(
|
|
Pierre-Yves Chibon |
2088eb |
'repo_info.html',
|
|
Pierre-Yves Chibon |
2088eb |
repo=repo,
|
|
Pierre-Yves Chibon |
226b9c |
repo_obj=repo_obj,
|
|
Pierre-Yves Chibon |
f3dba9 |
branches=sorted(repo_obj.listall_branches()),
|
|
Pierre-Yves Chibon |
2088eb |
branchname='master',
|
|
Pierre-Yves Chibon |
2088eb |
last_commits=last_commits,
|
|
Pierre-Yves Chibon |
0fa300 |
tree=tree,
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/branch/<branchname>')</branchname></repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
def view_repo_branch(repo, branchname):
|
|
Pierre-Yves Chibon |
2088eb |
""" Displays the information about a specific branch.
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Mathieu Bridon |
bdddc1 |
repo = progit.lib.get_project(SESSION, repo)
|
|
Mathieu Bridon |
bdddc1 |
|
|
Mathieu Bridon |
bdddc1 |
if repo is None:
|
|
Pierre-Yves Chibon |
2088eb |
flask.abort(404)
|
|
Mathieu Bridon |
bdddc1 |
|
|
Mathieu Bridon |
bdddc1 |
repo_obj = pygit2.Repository(os.path.join(APP.config["GIT_FOLDER"],
|
|
Mathieu Bridon |
bdddc1 |
repo.path))
|
|
Mathieu Bridon |
bdddc1 |
|
|
Pierre-Yves Chibon |
2088eb |
if not branchname in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
2088eb |
flask.abort(404)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
branch = repo_obj.lookup_branch(branchname)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
cnt = 0
|
|
Pierre-Yves Chibon |
2088eb |
last_commits = []
|
|
Pierre-Yves Chibon |
2088eb |
for commit in repo_obj.walk(branch.get_object().hex, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
2088eb |
last_commits.append(commit)
|
|
Pierre-Yves Chibon |
2088eb |
cnt += 1
|
|
Pierre-Yves Chibon |
2088eb |
if cnt == 10:
|
|
Pierre-Yves Chibon |
2088eb |
break
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
return flask.render_template(
|
|
Pierre-Yves Chibon |
2088eb |
'repo_info.html',
|
|
Pierre-Yves Chibon |
2088eb |
repo=repo,
|
|
Pierre-Yves Chibon |
18d24c |
branches=sorted(repo_obj.listall_branches()),
|
|
Pierre-Yves Chibon |
2088eb |
branchname=branchname,
|
|
Pierre-Yves Chibon |
2088eb |
last_commits=last_commits,
|
|
Pierre-Yves Chibon |
2088eb |
tree=sorted(last_commits[0].tree, key=lambda x: x.filemode),
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
6428d8 |
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/log')</repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/log/<branchname>')</branchname></repo>
|
|
Pierre-Yves Chibon |
2c090d |
def view_log(repo, branchname='master'):
|
|
Pierre-Yves Chibon |
2088eb |
""" Displays the logs of the specified repo.
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Mathieu Bridon |
ba640f |
repo = progit.lib.get_project(SESSION, repo)
|
|
Mathieu Bridon |
ba640f |
|
|
Mathieu Bridon |
ba640f |
if repo is None:
|
|
Pierre-Yves Chibon |
2088eb |
flask.abort(404)
|
|
Mathieu Bridon |
ba640f |
|
|
Mathieu Bridon |
ba640f |
repo_obj = pygit2.Repository(os.path.join(APP.config["GIT_FOLDER"],
|
|
Mathieu Bridon |
ba640f |
repo.path))
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
b0c4da |
if branchname and not branchname in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
b0c4da |
flask.abort(404)
|
|
Pierre-Yves Chibon |
b0c4da |
|
|
Pierre-Yves Chibon |
2c090d |
|
|
Pierre-Yves Chibon |
2c090d |
branch = repo_obj.lookup_branch(branchname)
|
|
Pierre-Yves Chibon |
b0c4da |
|
|
Pierre-Yves Chibon |
2088eb |
try:
|
|
Pierre-Yves Chibon |
2088eb |
page = int(flask.request.args.get('page', 1))
|
|
Pierre-Yves Chibon |
2088eb |
except ValueError:
|
|
Pierre-Yves Chibon |
2088eb |
page = 1
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
limit = APP.config['ITEM_PER_PAGE']
|
|
Pierre-Yves Chibon |
2088eb |
start = limit * (page - 1)
|
|
Pierre-Yves Chibon |
2088eb |
end = limit * page
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
n_commits = 0
|
|
Pierre-Yves Chibon |
2088eb |
last_commits = []
|
|
Pierre-Yves Chibon |
2088eb |
for commit in repo_obj.walk(
|
|
Pierre-Yves Chibon |
b0c4da |
branch.get_object().hex, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
2088eb |
if n_commits >= start and n_commits <= end:
|
|
Pierre-Yves Chibon |
2088eb |
last_commits.append(commit)
|
|
Pierre-Yves Chibon |
2088eb |
n_commits += 1
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
total_page = int(ceil(n_commits / float(limit)))
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
return flask.render_template(
|
|
Pierre-Yves Chibon |
2088eb |
'repo_info.html',
|
|
Pierre-Yves Chibon |
2088eb |
origin='view_log',
|
|
Pierre-Yves Chibon |
2088eb |
repo=repo,
|
|
Pierre-Yves Chibon |
18d24c |
branches=sorted(repo_obj.listall_branches()),
|
|
Pierre-Yves Chibon |
2088eb |
branchname=branchname,
|
|
Pierre-Yves Chibon |
2088eb |
last_commits=last_commits,
|
|
Pierre-Yves Chibon |
2088eb |
page=page,
|
|
Pierre-Yves Chibon |
2088eb |
total_page=total_page,
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/blob/<identifier>/<path:filename>')</path:filename></identifier></repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/blob/<identifier>/<path:filename>')</path:filename></identifier></repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
def view_file(repo, identifier, filename):
|
|
Pierre-Yves Chibon |
2088eb |
""" Displays the content of a file or a tree for the specified repo.
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Mathieu Bridon |
4c73b0 |
repo = progit.lib.get_project(SESSION, repo)
|
|
Mathieu Bridon |
4c73b0 |
|
|
Mathieu Bridon |
4c73b0 |
if repo is None:
|
|
Pierre-Yves Chibon |
5a3b73 |
flask.abort(404)
|
|
Mathieu Bridon |
4c73b0 |
|
|
Mathieu Bridon |
4c73b0 |
repo_obj = pygit2.Repository(os.path.join(APP.config["GIT_FOLDER"],
|
|
Mathieu Bridon |
4c73b0 |
repo.path))
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
if identifier in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
2088eb |
branchname = identifier
|
|
Pierre-Yves Chibon |
2088eb |
branch = repo_obj.lookup_branch(identifier)
|
|
Pierre-Yves Chibon |
2088eb |
commit = branch.get_object()
|
|
Pierre-Yves Chibon |
2088eb |
else:
|
|
Pierre-Yves Chibon |
2088eb |
try:
|
|
Pierre-Yves Chibon |
2d4003 |
commit = repo_obj.get(identifier)
|
|
Pierre-Yves Chibon |
2d4003 |
branchname = identifier
|
|
Pierre-Yves Chibon |
2088eb |
except ValueError:
|
|
Pierre-Yves Chibon |
2088eb |
# If it's not a commit id then it's part of the filename
|
|
Pierre-Yves Chibon |
2088eb |
commit = repo_obj[repo_obj.head.target]
|
|
Pierre-Yves Chibon |
6428d8 |
branchname = 'master'
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
def __get_file_in_tree(tree, filepath):
|
|
Pierre-Yves Chibon |
2088eb |
''' Retrieve the entry corresponding to the provided filename in a
|
|
Pierre-Yves Chibon |
2088eb |
given tree.
|
|
Pierre-Yves Chibon |
2088eb |
'''
|
|
Pierre-Yves Chibon |
2088eb |
filename = filepath[0]
|
|
Pierre-Yves Chibon |
2088eb |
if isinstance(tree, pygit2.Blob):
|
|
Pierre-Yves Chibon |
2088eb |
return
|
|
Pierre-Yves Chibon |
2088eb |
for el in tree:
|
|
Pierre-Yves Chibon |
2088eb |
if el.name == filename:
|
|
Pierre-Yves Chibon |
2088eb |
if len(filepath) == 1:
|
|
Pierre-Yves Chibon |
2088eb |
return repo_obj[el.oid]
|
|
Pierre-Yves Chibon |
2088eb |
else:
|
|
Pierre-Yves Chibon |
2088eb |
return __get_file_in_tree(repo_obj[el.oid], filepath[1:])
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
content = __get_file_in_tree(commit.tree, filename.split('/'))
|
|
Pierre-Yves Chibon |
2088eb |
if not content:
|
|
Pierre-Yves Chibon |
2088eb |
flask.abort(404, 'File not found')
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
content = repo_obj[content.oid]
|
|
Pierre-Yves Chibon |
2088eb |
if isinstance(content, pygit2.Blob):
|
|
Pierre-Yves Chibon |
2088eb |
content = highlight(
|
|
Pierre-Yves Chibon |
2088eb |
content.data,
|
|
Pierre-Yves Chibon |
2088eb |
guess_lexer(content.data),
|
|
Pierre-Yves Chibon |
2088eb |
HtmlFormatter(
|
|
Pierre-Yves Chibon |
2088eb |
noclasses=True,
|
|
Pierre-Yves Chibon |
2088eb |
style="tango",)
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
2088eb |
output_type = 'file'
|
|
Pierre-Yves Chibon |
2088eb |
else:
|
|
Pierre-Yves Chibon |
6428d8 |
content = sorted(content, key=lambda x: x.filemode)
|
|
Pierre-Yves Chibon |
2088eb |
output_type = 'tree'
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
return flask.render_template(
|
|
Pierre-Yves Chibon |
2088eb |
'file.html',
|
|
Pierre-Yves Chibon |
2088eb |
repo=repo,
|
|
Pierre-Yves Chibon |
2088eb |
branchname=branchname,
|
|
Pierre-Yves Chibon |
2088eb |
filename=filename,
|
|
Pierre-Yves Chibon |
2088eb |
content=content,
|
|
Pierre-Yves Chibon |
2088eb |
output_type=output_type,
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
84f83a |
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/<commitid>')</commitid></repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
def view_commit(repo, commitid):
|
|
Pierre-Yves Chibon |
2088eb |
""" Render a commit in a repo
|
|
Pierre-Yves Chibon |
2088eb |
"""
|
|
Mathieu Bridon |
eaccc4 |
repo = progit.lib.get_project(SESSION, repo)
|
|
Mathieu Bridon |
eaccc4 |
|
|
Mathieu Bridon |
eaccc4 |
if repo is None:
|
|
Pierre-Yves Chibon |
2088eb |
flask.abort(404)
|
|
Mathieu Bridon |
eaccc4 |
|
|
Mathieu Bridon |
eaccc4 |
repo_obj = pygit2.Repository(os.path.join(APP.config["GIT_FOLDER"],
|
|
Mathieu Bridon |
eaccc4 |
repo.path))
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
try:
|
|
Pierre-Yves Chibon |
2088eb |
commit = repo_obj.get(commitid)
|
|
Pierre-Yves Chibon |
2088eb |
except ValueError:
|
|
Pierre-Yves Chibon |
2088eb |
flask.abort(404)
|
|
Pierre-Yves Chibon |
84f83a |
|
|
Pierre-Yves Chibon |
84f83a |
if commit.parents:
|
|
Pierre-Yves Chibon |
84f83a |
diff = commit.tree.diff_to_tree()
|
|
Pierre-Yves Chibon |
84f83a |
|
|
Pierre-Yves Chibon |
84f83a |
parent = repo_obj.revparse_single('%s^' % commitid)
|
|
Pierre-Yves Chibon |
84f83a |
diff = repo_obj.diff(parent, commit)
|
|
Pierre-Yves Chibon |
84f83a |
else:
|
|
Pierre-Yves Chibon |
84f83a |
# First commit in the repo
|
|
Pierre-Yves Chibon |
84f83a |
diff = commit.tree.diff_to_tree(swap=True)
|
|
Pierre-Yves Chibon |
84f83a |
|
|
Pierre-Yves Chibon |
2088eb |
html_diff = highlight(
|
|
Pierre-Yves Chibon |
2088eb |
diff.patch,
|
|
Pierre-Yves Chibon |
2088eb |
DiffLexer(),
|
|
Pierre-Yves Chibon |
2088eb |
HtmlFormatter(
|
|
Pierre-Yves Chibon |
2088eb |
noclasses=True,
|
|
Pierre-Yves Chibon |
2088eb |
style="tango",)
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
2088eb |
|
|
Pierre-Yves Chibon |
2088eb |
return flask.render_template(
|
|
Pierre-Yves Chibon |
2088eb |
'commit.html',
|
|
Pierre-Yves Chibon |
2088eb |
repo=repo,
|
|
Pierre-Yves Chibon |
2088eb |
commitid=commitid,
|
|
Pierre-Yves Chibon |
2088eb |
commit=commit,
|
|
Pierre-Yves Chibon |
2088eb |
diff=diff,
|
|
Pierre-Yves Chibon |
2088eb |
html_diff=html_diff,
|
|
Pierre-Yves Chibon |
2088eb |
)
|
|
Pierre-Yves Chibon |
12e862 |
|
|
Pierre-Yves Chibon |
12e862 |
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/tree/')</repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
@APP.route('/<repo>/tree/<identifier>')</identifier></repo>
|
|
Pierre-Yves Chibon |
91a7c0 |
def view_tree(repo, identifier=None):
|
|
Pierre-Yves Chibon |
12e862 |
""" Render the tree of the repo
|
|
Pierre-Yves Chibon |
12e862 |
"""
|
|
Mathieu Bridon |
6dd1b4 |
repo = progit.lib.get_project(SESSION, repo)
|
|
Mathieu Bridon |
6dd1b4 |
|
|
Mathieu Bridon |
6dd1b4 |
if repo is None:
|
|
Pierre-Yves Chibon |
12e862 |
flask.abort(404)
|
|
Mathieu Bridon |
6dd1b4 |
|
|
Mathieu Bridon |
6dd1b4 |
repo_obj = pygit2.Repository(os.path.join(APP.config["GIT_FOLDER"],
|
|
Mathieu Bridon |
6dd1b4 |
repo.path))
|
|
Pierre-Yves Chibon |
12e862 |
|
|
Pierre-Yves Chibon |
12e862 |
if identifier in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
12e862 |
branchname = identifier
|
|
Pierre-Yves Chibon |
12e862 |
branch = repo_obj.lookup_branch(identifier)
|
|
Pierre-Yves Chibon |
12e862 |
commit = branch.get_object()
|
|
Pierre-Yves Chibon |
12e862 |
else:
|
|
Pierre-Yves Chibon |
12e862 |
try:
|
|
Pierre-Yves Chibon |
12e862 |
commit = repo_obj.get(identifier)
|
|
Pierre-Yves Chibon |
12e862 |
branchname = identifier
|
|
Pierre-Yves Chibon |
12e862 |
except (ValueError, TypeError):
|
|
Pierre-Yves Chibon |
12e862 |
# If it's not a commit id then it's part of the filename
|
|
Pierre-Yves Chibon |
12e862 |
commit = repo_obj[repo_obj.head.target]
|
|
Pierre-Yves Chibon |
2f9532 |
branchname = 'master'
|
|
Pierre-Yves Chibon |
12e862 |
|
|
Pierre-Yves Chibon |
6428d8 |
content = sorted(commit.tree, key=lambda x: x.filemode)
|
|
Pierre-Yves Chibon |
12e862 |
output_type = 'tree'
|
|
Pierre-Yves Chibon |
12e862 |
|
|
Pierre-Yves Chibon |
12e862 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
12e862 |
'file.html',
|
|
Pierre-Yves Chibon |
12e862 |
repo=repo,
|
|
Pierre-Yves Chibon |
12e862 |
branchname=branchname,
|
|
Pierre-Yves Chibon |
12e862 |
filename='',
|
|
Pierre-Yves Chibon |
12e862 |
content=content,
|
|
Pierre-Yves Chibon |
12e862 |
output_type=output_type,
|
|
Pierre-Yves Chibon |
12e862 |
)
|