~edwargix/git.sr.ht

8616f09c97b99c81ca4142869721aab86fc00063 — Drew DeVault 6 years ago cfff448
Add blob view
4 files changed, 118 insertions(+), 7 deletions(-)

M gitsrht/blueprints/repo.py
M gitsrht/git.py
A gitsrht/templates/blob.html
M scss/main.scss
M gitsrht/blueprints/repo.py => gitsrht/blueprints/repo.py +30 -4
@@ 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"<style>{style}</style>" + highlight(data, lexer, formatter)
    redis.setex(key, html, timedelta(days=30))
    return Markup(html)

@repo.route("/<owner>/<repo>")
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)

M gitsrht/git.py => gitsrht/git.py +6 -3
@@ 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 }

A gitsrht/templates/blob.html => gitsrht/templates/blob.html +39 -0
@@ 0,0 1,39 @@
{% extends "repo.html" %}
{% block content %}
<div class="header-extension">
  <div class="container-fluid">
    <span style="padding-left: 1rem">
      {% if path != [''] %}
      <a href="{{url_for("repo.tree",
        owner=repo.owner.canonical_name, repo=repo.name, branch=branch_name)}}"
      >{{repo.name}}</a>{% endif %}/{% for part in path%}{%
        if loop.last %}{{part}}{% else %}<a
          href="{{url_for("repo.tree", owner=repo.owner.canonical_name,
            repo=repo.name, branch=branch_name,
            path=path_join(*path[:loop.index]))}}"
        >{{part}}</a>/{%
      endif %}{% endfor %}
    </span>
    <div class="pull-right">
      <a href="#">{{commit.id.hex[:8]}}</a> &mdash;
      <a href="#">{{commit.author.name}}</a>:
      {{trim_commit(commit.message)}}
      <span class="text-muted">
        {{ commit_time(commit) | date }}
      </span>
    </div>
  </div>
</div>
<div class="container-fluid">
  <div class="row" style="margin-bottom: 1rem">
    <div class="col-md-12 code-view">
      <pre class="ruler"><span>{% for i in range(80) %} {% endfor %}</span></pre>
      <pre class="lines">{% for line in data.split("\n") %}<a
        href="#L{{loop.index}}"
        id="L{{loop.index}}"
        >{{loop.index}}</a>{% if not loop.last %}
{% endif %}{% endfor %}</pre>
      {{ highlight_file(entry.name, data, blob.id.hex) }}
    </div>
</div>
{% endblock %}

M scss/main.scss => scss/main.scss +43 -0
@@ 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;
    }
  }
}