|
Pierre-Yves Chibon |
33b534 |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
"""
|
|
Pierre-Yves Chibon |
ddede6 |
(c) 2014 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
Authors:
|
|
Pierre-Yves Chibon |
ddede6 |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
"""
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
import flask
|
|
Pierre-Yves Chibon |
ddede6 |
import os
|
|
Pierre-Yves Chibon |
ddede6 |
from math import ceil
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
import pygit2
|
|
Pierre-Yves Chibon |
ddede6 |
from sqlalchemy.exc import SQLAlchemyError
|
|
Pierre-Yves Chibon |
ddede6 |
from pygments import highlight
|
|
Pierre-Yves Chibon |
ddede6 |
from pygments.lexers import guess_lexer
|
|
Pierre-Yves Chibon |
ddede6 |
from pygments.lexers.text import DiffLexer
|
|
Pierre-Yves Chibon |
ddede6 |
from pygments.formatters import HtmlFormatter
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
import progit.doc_utils
|
|
Pierre-Yves Chibon |
822345 |
import progit.exceptions
|
|
Pierre-Yves Chibon |
ddede6 |
import progit.lib
|
|
Pierre-Yves Chibon |
ddede6 |
import progit.forms
|
|
Pierre-Yves Chibon |
ddede6 |
from progit import APP, SESSION, LOG, cla_required
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
def __get_tree(repo_obj, tree, filepath, startswith=False):
|
|
Pierre-Yves Chibon |
ddede6 |
''' Retrieve the entry corresponding to the provided filename in a
|
|
Pierre-Yves Chibon |
ddede6 |
given tree.
|
|
Pierre-Yves Chibon |
ddede6 |
'''
|
|
Pierre-Yves Chibon |
ddede6 |
filename = filepath[0]
|
|
Pierre-Yves Chibon |
ddede6 |
if isinstance(tree, pygit2.Blob):
|
|
Pierre-Yves Chibon |
ddede6 |
return (tree, None)
|
|
Pierre-Yves Chibon |
ddede6 |
cnt = 0
|
|
Pierre-Yves Chibon |
ddede6 |
for el in tree:
|
|
Pierre-Yves Chibon |
ddede6 |
cnt += 1
|
|
Pierre-Yves Chibon |
ddede6 |
ok = False
|
|
Pierre-Yves Chibon |
d6aad2 |
if el.name.startswith(filename):
|
|
Pierre-Yves Chibon |
ddede6 |
ok = True
|
|
Pierre-Yves Chibon |
ddede6 |
if el.name == filename:
|
|
Pierre-Yves Chibon |
ddede6 |
ok = True
|
|
Pierre-Yves Chibon |
822345 |
if ok and len(filepath) == 1:
|
|
Pierre-Yves Chibon |
822345 |
return (el, tree)
|
|
Pierre-Yves Chibon |
822345 |
elif ok:
|
|
Pierre-Yves Chibon |
822345 |
return __get_tree(
|
|
Pierre-Yves Chibon |
d6aad2 |
repo_obj, repo_obj[el.oid], filepath[1:],
|
|
Pierre-Yves Chibon |
d6aad2 |
startswith=startswith)
|
|
Pierre-Yves Chibon |
822345 |
|
|
Pierre-Yves Chibon |
822345 |
if len(filepath) == 1:
|
|
Pierre-Yves Chibon |
3b01c0 |
return None, tree
|
|
Pierre-Yves Chibon |
822345 |
else:
|
|
Pierre-Yves Chibon |
822345 |
return __get_tree(
|
|
Pierre-Yves Chibon |
d6aad2 |
repo_obj, repo_obj[tree.oid], filepath[1:],
|
|
Pierre-Yves Chibon |
d6aad2 |
startswith=startswith)
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
def __get_tree_and_content(repo_obj, commit, path, startswith):
|
|
Pierre-Yves Chibon |
ddede6 |
''' Return the tree and the content of the specified file. '''
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
3b01c0 |
(blob_or_tree, tree_obj) = __get_tree(
|
|
Pierre-Yves Chibon |
3b01c0 |
repo_obj, commit.tree, path, startswith=startswith)
|
|
Pierre-Yves Chibon |
3b01c0 |
|
|
Pierre-Yves Chibon |
3b01c0 |
if blob_or_tree is None:
|
|
Pierre-Yves Chibon |
3b01c0 |
return tree_obj, None
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
if not repo_obj[blob_or_tree.oid]:
|
|
Pierre-Yves Chibon |
ddede6 |
flask.abort(404, 'File not found')
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
blob_or_tree_obj = repo_obj[blob_or_tree.oid]
|
|
Pierre-Yves Chibon |
ddede6 |
blob = repo_obj[blob_or_tree.oid]
|
|
Pierre-Yves Chibon |
822345 |
|
|
Pierre-Yves Chibon |
822345 |
content = None
|
|
Pierre-Yves Chibon |
ddede6 |
if isinstance(blob, pygit2.Blob): # Returned a file
|
|
Pierre-Yves Chibon |
ddede6 |
name, ext = os.path.splitext(blob_or_tree.name)
|
|
Pierre-Yves Chibon |
ddede6 |
content = progit.doc_utils.convert_readme(blob_or_tree_obj.data, ext)
|
|
Pierre-Yves Chibon |
ddede6 |
else: # Returned a tree
|
|
Pierre-Yves Chibon |
1d2e52 |
raise progit.exceptions.FileNotFoundException('File not found')
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
tree = sorted(tree_obj, key=lambda x: x.filemode)
|
|
Pierre-Yves Chibon |
ddede6 |
return (tree, content)
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
c4da03 |
## URLs
|
|
Pierre-Yves Chibon |
c4da03 |
|
|
Pierre-Yves Chibon |
c4da03 |
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/<repo>/docs')</repo>
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/<repo>/docs/<path:filename>')</path:filename></repo>
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/<repo>/docs/<branchname>')</branchname></repo>
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/<repo>/docs/<branchname>/<path:filename>')</path:filename></branchname></repo>
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/fork/<username>/<repo>/docs')</repo></username>
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/fork/<username>/<repo>/docs/<path:filename>')</path:filename></repo></username>
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/fork/<username>/<repo>/docs/<branchname>')</branchname></repo></username>
|
|
Pierre-Yves Chibon |
c4da03 |
@APP.route('/fork/<username>/<repo>/docs/<branchname>/<path:filename>')</path:filename></branchname></repo></username>
|
|
Pierre-Yves Chibon |
4b7a7d |
def view_docs(repo, username=None, branchname=None, filename=None):
|
|
Pierre-Yves Chibon |
c4da03 |
""" Display the documentation
|
|
Pierre-Yves Chibon |
ddede6 |
"""
|
|
Pierre-Yves Chibon |
c4da03 |
status = flask.request.args.get('status', None)
|
|
Pierre-Yves Chibon |
c4da03 |
|
|
Pierre-Yves Chibon |
ddede6 |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
if not repo:
|
|
Pierre-Yves Chibon |
ddede6 |
flask.abort(404, 'Project not found')
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
4b7a7d |
if not repo.project_docs:
|
|
Pierre-Yves Chibon |
c2f4ca |
flask.abort(404, 'No documentation found for this project')
|
|
Pierre-Yves Chibon |
c2f4ca |
|
|
Pierre-Yves Chibon |
4b7a7d |
reponame = os.path.join(APP.config['DOCS_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
a386bc |
if not os.path.exists(reponame):
|
|
Pierre-Yves Chibon |
a386bc |
flask.flash(
|
|
Pierre-Yves Chibon |
4b7a7d |
'No docs repository could be found, please contact an admin',
|
|
Pierre-Yves Chibon |
a386bc |
'error')
|
|
Pierre-Yves Chibon |
a386bc |
return flask.redirect(flask.url_for(
|
|
Pierre-Yves Chibon |
a386bc |
'view_repo', repo=repo.name, username=username))
|
|
Pierre-Yves Chibon |
a386bc |
|
|
Pierre-Yves Chibon |
ddede6 |
repo_obj = pygit2.Repository(reponame)
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
if branchname in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
ddede6 |
branch = repo_obj.lookup_branch(branchname)
|
|
Pierre-Yves Chibon |
ddede6 |
commit = branch.get_object()
|
|
Pierre-Yves Chibon |
ddede6 |
else:
|
|
Pierre-Yves Chibon |
ddede6 |
if not repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
ddede6 |
commit = repo_obj[repo_obj.head.target]
|
|
Pierre-Yves Chibon |
ddede6 |
else:
|
|
Pierre-Yves Chibon |
ddede6 |
commit = None
|
|
Pierre-Yves Chibon |
ddede6 |
branchname = 'master'
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
content = None
|
|
Pierre-Yves Chibon |
0c352b |
tree = None
|
|
Pierre-Yves Chibon |
ddede6 |
startswith = False
|
|
Pierre-Yves Chibon |
ddede6 |
if not filename:
|
|
Pierre-Yves Chibon |
ddede6 |
path = ['index']
|
|
Pierre-Yves Chibon |
ddede6 |
startswith = True
|
|
Pierre-Yves Chibon |
ddede6 |
else:
|
|
Pierre-Yves Chibon |
ddede6 |
path = filename.split('/')
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
if commit:
|
|
Pierre-Yves Chibon |
822345 |
try:
|
|
Pierre-Yves Chibon |
822345 |
(tree, content) = __get_tree_and_content(
|
|
Pierre-Yves Chibon |
822345 |
repo_obj, commit, path, startswith)
|
|
Pierre-Yves Chibon |
822345 |
except progit.exceptions.FileNotFoundException:
|
|
Pierre-Yves Chibon |
822345 |
if not path[0].startswith('index'):
|
|
Pierre-Yves Chibon |
822345 |
path.append('index')
|
|
Pierre-Yves Chibon |
822345 |
filename = filename + '/'
|
|
Pierre-Yves Chibon |
3b01c0 |
|
|
Pierre-Yves Chibon |
013e6f |
(tree, content) = __get_tree_and_content(
|
|
Pierre-Yves Chibon |
d6aad2 |
repo_obj, commit, path, startswith=True)
|
|
Pierre-Yves Chibon |
ddede6 |
|
|
Pierre-Yves Chibon |
ddede6 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
4b7a7d |
'docs.html',
|
|
Pierre-Yves Chibon |
75a541 |
select='docs',
|
|
Pierre-Yves Chibon |
c1f7d5 |
repo_obj=repo_obj,
|
|
Pierre-Yves Chibon |
ddede6 |
repo=repo,
|
|
Pierre-Yves Chibon |
ddede6 |
username=username,
|
|
Pierre-Yves Chibon |
ddede6 |
branchname=branchname,
|
|
Pierre-Yves Chibon |
ddede6 |
filename=filename,
|
|
Pierre-Yves Chibon |
ddede6 |
tree=tree,
|
|
Pierre-Yves Chibon |
ddede6 |
content=content,
|
|
Pierre-Yves Chibon |
ddede6 |
)
|