From 8616f09c97b99c81ca4142869721aab86fc00063 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 22 Sep 2018 13:15:41 -0400 Subject: [PATCH] Add blob view --- gitsrht/blueprints/repo.py | 34 +++++++++++++++++++++++++---- gitsrht/git.py | 9 +++++--- gitsrht/templates/blob.html | 39 +++++++++++++++++++++++++++++++++ scss/main.scss | 43 +++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 gitsrht/templates/blob.html diff --git a/gitsrht/blueprints/repo.py b/gitsrht/blueprints/repo.py index b0f90cd..d4e4f94 100644 --- a/gitsrht/blueprints/repo.py +++ b/gitsrht/blueprints/repo.py @@ -1,4 +1,6 @@ import pygit2 +import pygments +from datetime import datetime, timedelta from jinja2 import Markup from flask import Blueprint, render_template, abort from flask_login import current_user @@ -6,9 +8,11 @@ from gitsrht.access import get_repo, has_access, UserAccess from gitsrht.redis import redis from gitsrht.git import CachedRepository, commit_time, annotate_tree from gitsrht.types import User, Repository +from pygments import highlight +from pygments.lexers import guess_lexer_for_filename, TextLexer +from pygments.formatters import HtmlFormatter from srht.config import cfg from srht.markdown import markdown -from datetime import datetime, timedelta repo = Blueprint('repo', __name__) @@ -30,6 +34,21 @@ def get_readme(repo, tip): redis.setex(key, html, timedelta(days=30)) return Markup(html) +def _highlight_file(name, data, blob_id): + key = f"git.sr.ht:git:highlight:{blob_id}" + html = redis.get(key) + if html: + return Markup(html.decode()) + try: + lexer = guess_lexer_for_filename(name, data) + except pygments.util.ClassNotFound: + lexer = TextLexer() + formatter = HtmlFormatter() + style = formatter.get_style_defs('.highlight') + html = f"" + highlight(data, lexer, formatter) + redis.setex(key, html, timedelta(days=30)) + return Markup(html) + @repo.route("//") def summary(owner, repo): owner, repo = get_repo(owner, repo) @@ -82,6 +101,7 @@ def tree(owner, repo, branch, path): branch = git_repo.branches.get(branch) if not branch: abort(404) + branch_name = branch.name[len("refs/heads/"):] commit = git_repo.get(branch.target) tree = commit.tree @@ -93,13 +113,19 @@ def tree(owner, repo, branch, path): abort(404) entry = tree[part] if entry.type == "blob": - return "TODO: render blobs" + tree = annotate_tree(git_repo, tree, commit) + commit = next(e.commit for e in tree if e.name == entry.name) + blob = git_repo.get(entry.id) + data = blob.data.decode() + return render_template("blob.html", view="tree", + owner=owner, repo=repo, branch=branch, path=path, + branch_name=branch_name, entry=entry, blob=blob, data=data, + commit=commit, highlight_file=_highlight_file) tree = git_repo.get(entry.id) tree = annotate_tree(git_repo, tree, commit) tree = sorted(tree, key=lambda e: e.name) return render_template("tree.html", view="tree", - owner=owner, repo=repo, branch=branch, - branch_name=branch.name[len("refs/heads/"):], + owner=owner, repo=repo, branch=branch, branch_name=branch_name, commit=commit, tree=tree, path=path) diff --git a/gitsrht/git.py b/gitsrht/git.py index 40ae3b3..b254360 100644 --- a/gitsrht/git.py +++ b/gitsrht/git.py @@ -95,9 +95,12 @@ def annotate_tree(repo, tree, commit): key = f"git.sr.ht:git:tree:{tree.id.hex}" cache = redis.get(key) if cache: - cache = json.loads(cache.decode()) - return [AnnotatedTreeEntry.deserialize( - e, repo).fetch_blob() for e in cache.values()] + try: + cache = json.loads(cache.decode()) + return [AnnotatedTreeEntry.deserialize( + e, repo).fetch_blob() for e in cache.values()] + except: + redis.delete(key) tree = { entry.id.hex: AnnotatedTreeEntry( repo, entry) for entry in tree } diff --git a/gitsrht/templates/blob.html b/gitsrht/templates/blob.html new file mode 100644 index 0000000..00d0f90 --- /dev/null +++ b/gitsrht/templates/blob.html @@ -0,0 +1,39 @@ +{% extends "repo.html" %} +{% block content %} +
+
+ + {% if path != [''] %} + {{repo.name}}{% endif %}/{% for part in path%}{% + if loop.last %}{{part}}{% else %}{{part}}/{% + endif %}{% endfor %} + +
+ {{commit.id.hex[:8]}} — + {{commit.author.name}}: + {{trim_commit(commit.message)}} + + {{ commit_time(commit) | date }} + +
+
+
+
+
+
+
{% for i in range(80) %} {% endfor %}
+
{% for line in data.split("\n") %}{{loop.index}}{% if not loop.last %}
+{% endif %}{% endfor %}
+ {{ highlight_file(entry.name, data, blob.id.hex) }} +
+
+{% endblock %} diff --git a/scss/main.scss b/scss/main.scss index 9b44c8e..abd3a8d 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -61,3 +61,46 @@ } } } + +.code-view { + display: grid; + grid-template-columns: auto 1fr; + grid-template-rows: auto; + + .lines { + grid-column-start: 1; + grid-row-start: 1; + border-right: 1px solid #444; + } + + .highlight { + grid-column-start: 2; + grid-row-start: 1; + padding-left: 1rem; + background: transparent; + overflow-x: hidden; + + pre { + background: transparent; + } + } + + .ruler { + background: transparent; + grid-column-start: 2; + grid-row-start: 1; + display: block; + padding-left: calc(1rem + 4px); + height: 100%; + + pre { + background: transparent; + } + + & > span { + height: 100%; + display: inline-block; + border-right: 1px solid $gray-200; + } + } +} -- 2.38.4