diff --git a/progit/static/progit.css b/progit/static/progit.css
index 3873ec5..d4c6d51 100644
--- a/progit/static/progit.css
+++ b/progit/static/progit.css
@@ -379,7 +379,7 @@ table.list .open_by {
width: 9em;
}
-td.noresult {
+.noresult {
text-align: center;
font-weight: bold;
}
@@ -408,9 +408,10 @@ td.noresult {
}
.issue_comment > header,
-.issue_comment > form > header {
+.issue_comment > form > header,
+.file_content > .buttons
+{
border-radius: 10px 10px 0 0;
- background: #ccc;
padding: .5em;
border-bottom: 1px solid rgba(237, 237, 237, 0.4);
@@ -454,3 +455,43 @@ td.noresult {
width: 100%;
padding: .5em;
}
+
+.buttons {
+ padding: 0;
+ list-style-type: none;
+ text-align: right;
+ /*padding: .2em .5em 1em;*/
+ margin: 0;
+}
+
+.buttons li {
+ display: inline-block;
+ padding-left: .5em;
+}
+
+.button {
+ display: inline-block;
+ color: white;
+ background: #0066cc;
+ border-radius: 3px;
+ padding: .2em .5em;
+ background-image: -webkit-linear-gradient(top, #0066cc, #34609f);
+ background-image: -moz-linear-gradient(top, #0066cc, #34609f);
+ background-image: -o-linear-gradient(top, #0066cc, #34609f);
+ background-image: linear-gradient(to bottom, #0066cc, #34609f);
+ -webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
+ box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
+}
+
+.button:hover {
+ background-image: linear-gradient(to bottom, #34609f, #0066cc);
+}
+
+a.button:visited, a.button:hover {
+ color: white;
+}
+
+.file_content {
+ border: 1px solid rgba(237, 237, 237, 0.4);
+ border-radius: 10px 10px 0 0;
+}
diff --git a/progit/templates/file.html b/progit/templates/file.html
index 09e6af0..cf691b5 100644
--- a/progit/templates/file.html
+++ b/progit/templates/file.html
@@ -25,10 +25,26 @@
{% if content %}
- {% if output_type=='file' %}
- {% autoescape false %}
- {{ content | format_loc}}
- {% endautoescape %}
+ {% if output_type == 'file' or output_type == 'binary' or output_type == 'image' %}
+
+
+ {% if output_type=='file' %}
+ {% autoescape false %}
+ {{ content | format_loc}}
+ {% endautoescape %}
+ {% elif output_type == 'binary' or output_type == 'image' %}
+
Binary files cannot be rendered.
Please view the raw version
+ {% endif %}
+
{% else %}
Tree
diff --git a/progit/ui/repo.py b/progit/ui/repo.py
index f01c152..c43b781 100644
--- a/progit/ui/repo.py
+++ b/progit/ui/repo.py
@@ -20,6 +20,9 @@ from pygments.lexers import guess_lexer
from pygments.lexers.text import DiffLexer
from pygments.formatters import HtmlFormatter
+import mimetypes
+import chardet
+
import progit.exceptions
import progit.lib
import progit.forms
@@ -283,8 +286,6 @@ def view_log(repo, branchname=None, username=None):
@APP.route('//blob//')
-@APP.route('//blob//')
-@APP.route('/fork///blob//')
@APP.route('/fork///blob//')
def view_file(repo, identifier, filename, username=None):
""" Displays the content of a file or a tree for the specified repo.
@@ -318,14 +319,22 @@ def view_file(repo, identifier, filename, username=None):
content = repo_obj[content.oid]
if isinstance(content, pygit2.Blob):
- content = highlight(
- content.data,
- guess_lexer(content.data),
- HtmlFormatter(
- noclasses=True,
- style="tango",)
- )
- output_type = 'file'
+ if content.is_binary:
+ ext = filename[filename.rfind('.'):]
+ if ext in ('.gif', '.png', '.bmp', '.tif', '.tiff', '.jpg',
+ '.jpeg', '.ppm', '.pnm', '.pbm', '.pgm', '.webp', '.ico'):
+ output_type = 'image'
+ else:
+ output_type = 'binary'
+ else:
+ content = highlight(
+ content.data,
+ guess_lexer(content.data),
+ HtmlFormatter(
+ noclasses=True,
+ style="tango",)
+ )
+ output_type = 'file'
else:
content = sorted(content, key=lambda x: x.filemode)
output_type = 'tree'
@@ -342,6 +351,57 @@ def view_file(repo, identifier, filename, username=None):
)
+@APP.route('//raw//')
+@APP.route('/fork///raw//')
+def view_raw_file(repo, identifier, filename, username=None):
+ """ Displays the raw content of a file for the specified 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['GIT_FOLDER'], repo.path)
+ if repo.is_fork:
+ reponame = os.path.join(APP.config['FORK_FOLDER'], repo.path)
+ repo_obj = pygit2.Repository(reponame)
+
+ if identifier in repo_obj.listall_branches():
+ branch = repo_obj.lookup_branch(identifier)
+ commit = branch.get_object()
+ else:
+ try:
+ commit = repo_obj.get(identifier)
+ except ValueError:
+ # If it's not a commit id then it's part of the filename
+ commit = repo_obj[repo_obj.head.target]
+
+ content = __get_file_in_tree(repo_obj, commit.tree, filename.split('/'))
+ if not content:
+ flask.abort(404, 'File not found')
+
+ mimetype, encoding = mimetypes.guess_type(filename)
+ data = repo_obj[content.oid].data
+
+ if not mimetype and data[:2] == '#!':
+ mimetype = 'text/plain'
+
+ if not mimetype:
+ if '\0' in data:
+ mimetype = 'application/octet-stream'
+ else:
+ mimetype = 'text/plain'
+
+ if mimetype.startswith('text/') and not encoding:
+ encoding = chardet.detect(data)['encoding']
+
+ headers = {'Content-Type': mimetype}
+ if encoding:
+ headers['Content-Encoding'] = encoding
+
+ return (data, 200, headers)
+
+
@APP.route('//')
@APP.route('/fork///')
def view_commit(repo, commitid, username=None):