From ddede6d7290f4ed3b71b3709fdc3596b1e15c65e Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Mar 25 2014 14:55:14 +0000 Subject: Add the wiki/documentation browser --- diff --git a/progit/__init__.py b/progit/__init__.py index fd93b2c..5517949 100644 --- a/progit/__init__.py +++ b/progit/__init__.py @@ -187,3 +187,4 @@ import progit.app import progit.fork import progit.issues import progit.repo +import progit.wiki diff --git a/progit/templates/wiki.html b/progit/templates/wiki.html new file mode 100644 index 0000000..b38971b --- /dev/null +++ b/progit/templates/wiki.html @@ -0,0 +1,55 @@ +{% extends "repo_master.html" %} + +{% block title %}Wiki - {{ repo.name }}{% endblock %} +{%block tag %}home{% endblock %} + + +{% block repo %} + +

Wiki

+

+ + {{ branchname }}/{% if filename %}{% + for file in filename.split('/') %} + {% if loop.first %} + {% set path = file %} + {% else %} + {% set path = path + '/' + file %} + {% endif %} + {% if loop.index != loop.length %}{{ file }}/{% else %}{{ file }}{% endif %} + {% endfor %}{% endif %} +

+ +{% if tree %} +
+ +
+{% endif %} + +
+ {% autoescape false %} + {{ content }} + {% endautoescape %} +
+ +{% endblock %} diff --git a/progit/wiki.py b/progit/wiki.py new file mode 100644 index 0000000..47eb00b --- /dev/null +++ b/progit/wiki.py @@ -0,0 +1,137 @@ +#-*- coding: utf-8 -*- + +""" + (c) 2014 - Copyright Red Hat Inc + + Authors: + Pierre-Yves Chibon + +""" + +import flask +import os +from math import ceil + +import pygit2 +from sqlalchemy.exc import SQLAlchemyError +from pygments import highlight +from pygments.lexers import guess_lexer +from pygments.lexers.text import DiffLexer +from pygments.formatters import HtmlFormatter + + +import progit.doc_utils +import progit.lib +import progit.forms +from progit import APP, SESSION, LOG, cla_required + + +def __get_tree(repo_obj, tree, filepath, startswith=False): + ''' Retrieve the entry corresponding to the provided filename in a + given tree. + ''' + filename = filepath[0] + if isinstance(tree, pygit2.Blob): + return (tree, None) + cnt = 0 + for el in tree: + cnt += 1 + ok = False + if cnt == len(tree) and el.name.startswith(filename): + ok = True + if el.name == filename: + ok = True + if ok: + if len(filepath) == 1: + return (el, tree) + else: + return __get_tree( + repo_obj, repo_obj[el.oid], filepath[1:]) + + +def __get_tree_and_content(repo_obj, commit, path, startswith): + ''' Return the tree and the content of the specified file. ''' + + (blob_or_tree, tree_obj) = __get_tree( + repo_obj, commit.tree, path, startswith=startswith) + + if not repo_obj[blob_or_tree.oid]: + flask.abort(404, 'File not found') + + + blob_or_tree_obj = repo_obj[blob_or_tree.oid] + blob = repo_obj[blob_or_tree.oid] + if isinstance(blob, pygit2.Blob): # Returned a file + name, ext = os.path.splitext(blob_or_tree.name) + content = progit.doc_utils.convert_readme(blob_or_tree_obj.data, ext) + else: # Returned a tree + path.append('index') + return __get_tree_and_content(repo_obj, commit, path, startswith) + + tree = sorted(tree_obj, key=lambda x: x.filemode) + return (tree, content) + + +def do_view_wiki(repo, username=None, branchname=None, filename=None): + """ List all issues associated to a repo + """ + repo = progit.lib.get_project(SESSION, repo, user=username) + + if not repo: + flask.abort(404, 'Project not found') + + reponame = os.path.join(APP.config['WIKI_FOLDER'], repo.path) + repo_obj = pygit2.Repository(reponame) + + if branchname in repo_obj.listall_branches(): + branch = repo_obj.lookup_branch(branchname) + commit = branch.get_object() + else: + if not repo_obj.is_empty: + commit = repo_obj[repo_obj.head.target] + else: + commit = None + branchname = 'master' + + content = None + startswith = False + if not filename: + path = ['index'] + startswith = True + else: + path = filename.split('/') + + if commit: + (tree, content ) = __get_tree_and_content( + repo_obj, commit, path, startswith) + + return flask.render_template( + 'wiki.html', + select='wiki', + repo=repo, + username=username, + branchname=branchname, + filename=filename, + tree=tree, + content=content, + ) + + +## URLs + + +@APP.route('//wiki') +@APP.route('//wiki/') +@APP.route('//wiki/') +@APP.route('//wiki//') + +@APP.route('/fork///wiki') +@APP.route('/fork///wiki/') +@APP.route('/fork///wiki/') +@APP.route('/fork///wiki//') +def view_wiki(repo, username=None, branchname=None, filename=None): + """ Display the documentation + """ + status = flask.request.args.get('status', None) + return do_view_wiki( + repo, username=username, branchname=branchname, filename=filename)