~edwargix/git.sr.ht

4981524c9215359a5667a676a679ae1bc699921d — Drew DeVault 6 years ago 8616f09
Add raw blob downloads
2 files changed, 78 insertions(+), 2 deletions(-)

M gitsrht/blueprints/repo.py
M gitsrht/templates/blob.html
M gitsrht/blueprints/repo.py => gitsrht/blueprints/repo.py +48 -2
@@ 2,12 2,13 @@ import pygit2
import pygments
from datetime import datetime, timedelta
from jinja2 import Markup
from flask import Blueprint, render_template, abort
from flask import Blueprint, render_template, abort, send_file
from flask_login import current_user
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 io import BytesIO
from pygments import highlight
from pygments.lexers import guess_lexer_for_filename, TextLexer
from pygments.formatters import HtmlFormatter


@@ 116,7 117,12 @@ def tree(owner, repo, branch, path):
            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()
            data = None
            if not blob.is_binary:
                try:
                    data = blob.data.decode()
                except:
                    pass
            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,


@@ 129,3 135,43 @@ def tree(owner, repo, branch, path):
    return render_template("tree.html", view="tree",
            owner=owner, repo=repo, branch=branch, branch_name=branch_name,
            commit=commit, tree=tree, path=path)

@repo.route("/<owner>/<repo>/blob/<branch>/<path:path>")
def raw_blob(owner, repo, branch, path):
    owner, repo = get_repo(owner, repo)
    if not repo:
        abort(404)
    if not has_access(repo, UserAccess.read):
        abort(401)
    git_repo = CachedRepository(repo.path)
    if branch is None:
        branch = git_repo.default_branch()
    else:
        branch = git_repo.branches.get(branch)
    if not branch:
        abort(404)
    branch_name = branch.name[len("refs/heads/"):]
    commit = git_repo.get(branch.target)

    blob = None
    entry = None
    tree = commit.tree
    path = path.split("/")
    for part in path:
        if part == "":
            continue
        if part not in tree:
            abort(404)
        entry = tree[part]
        if entry.type == "blob":
            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)
            break
        tree = git_repo.get(entry.id)

    if not blob:
        abort(404)

    return send_file(BytesIO(blob.data),
            as_attachment=blob.is_binary, attachment_filename=entry.name)

M gitsrht/templates/blob.html => gitsrht/templates/blob.html +30 -0
@@ 13,6 13,20 @@
            path=path_join(*path[:loop.index]))}}"
        >{{part}}</a>/{%
      endif %}{% endfor %}
      <span class="text-muted" style="margin-left: 1rem">
        {{stat.filemode(entry.filemode)}}
      </span>
      <span class="text-muted" style="margin-left: 1rem">
        {{humanize.naturalsize(blob.size,
          binary=True).replace("Byte", "byte")}}
      </span>
      <span class="text-muted" style="margin-left: 1rem">
        <a href="{{url_for("repo.raw_blob", owner=repo.owner.canonical_name,
            repo=repo.name, branch=branch_name,
            path=path_join(*path))}}">
          View raw
        </a>
      </span>
    </span>
    <div class="pull-right">
      <a href="#">{{commit.id.hex[:8]}}</a> &mdash;


@@ 26,6 40,7 @@
</div>
<div class="container-fluid">
  <div class="row" style="margin-bottom: 1rem">
    {% if not blob.is_binary %}
    <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


@@ 35,5 50,20 @@
{% endif %}{% endfor %}</pre>
      {{ highlight_file(entry.name, data, blob.id.hex) }}
    </div>
    {% else %}
    <div class="col-md-12">
      <p>
        {{humanize.naturalsize(blob.size,
          binary=True).replace("Byte", "byte")}} binary file not shown.
      </p>
      <p>
        <a href="{{url_for("repo.raw_blob", owner=repo.owner.canonical_name,
            repo=repo.name, branch=branch_name,
            path=path_join(*path))}}" class="btn btn-primary">
          Download {{icon("caret-right")}}
        </a>
      </p>
    </div>
    {% endif %}
</div>
{% endblock %}