~edwargix/git.sr.ht

00c7ddced5cd820c54420ad785eed21918bf7eba — Drew DeVault 6 years ago 3e413e7
Make repo summary page real
5 files changed, 111 insertions(+), 33 deletions(-)

M gitsrht/app.py
M gitsrht/blueprints/repo.py
A gitsrht/git.py
A gitsrht/redis.py
M gitsrht/templates/summary.html
M gitsrht/app.py => gitsrht/app.py +3 -0
@@ 10,6 10,7 @@ from gitsrht.types import User
db.init()

import gitsrht.oauth
from gitsrht.git import commit_time, trim_commit

class GitApp(SrhtFlask):
    def __init__(self):


@@ 39,6 40,8 @@ class GitApp(SrhtFlask):
            if notice:
                del session["notice"]
            return {
                "trim_commit": trim_commit,
                "commit_time": commit_time,
                "notice": notice
            }


M gitsrht/blueprints/repo.py => gitsrht/blueprints/repo.py +52 -4
@@ 1,17 1,65 @@
import pygit2
from jinja2 import Markup
from flask import Blueprint, render_template, abort
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
from gitsrht.types import User, Repository
from srht.config import cfg
from srht.markdown import markdown
from datetime import datetime, timedelta

repo = Blueprint('repo', __name__)

# TODO: !! SECURITY !!
def get_readme(repo, tip):
    if not tip or not "README.md" in tip.tree:
        return None
    readme = tip.tree["README.md"]
    if readme.type != "blob":
        return None
    html = redis.get(readme.id.hex)
    if html:
        return Markup(html.decode())
    try:
        md = repo.get(readme.id).data.decode()
    except:
        pass
    html = markdown(md, ["h1", "h2", "h3", "h4", "h5"])
    redis.setex(readme.id.hex, html, timedelta(days=30))
    return Markup(html)

@repo.route("/<owner>/<repo>")
def summary(owner, repo):
    owner, repo = get_repo(owner, repo)
    if not has_access(repo, UserAccess.read):
        abort(401)
    with open("/home/sircmpwn/sources/wlroots/README.md") as f:
        rm = f.read()
    return render_template("summary.html", owner=owner, repo=repo, rm=rm)
    git_repo = CachedRepository(repo.path)
    master = git_repo.branches.get("master")
    if not master:
        master = list(git_repo.branches.local)[0]
        master = git_repo.branches.get(master)
    # TODO: Test on empty repos
    tip = git_repo.get(master.target)
    commits = list()
    for commit in git_repo.walk(tip.id, pygit2.GIT_SORT_TIME):
        commits.append(commit)
        if len(commits) >= 3:
            break
    readme = get_readme(git_repo, tip)
    base = (cfg("git.sr.ht", "origin")
        .replace("http://", "")
        .replace("https://", ""))
    clone_urls = [
        url.format(base, owner.canonical_name, repo.name)
        for url in ["https://{}/{}/{}", "git@{}:{}/{}"]
    ]
    tags = [(ref, git_repo.get(git_repo.references[ref].target))
        for ref in git_repo.listall_references()
        if ref.startswith("refs/tags/")]
    tags = sorted(tags, key=lambda c: commit_time(c[1]), reverse=True)
    latest_tag = tags[0] if len(tags) else None
    default_branch = master
    return render_template("summary.html", owner=owner, repo=repo,
            readme=readme, commits=commits, clone_urls=clone_urls,
            latest_tag=latest_tag, default_branch=master)

A gitsrht/git.py => gitsrht/git.py +34 -0
@@ 0,0 1,34 @@
from datetime import datetime, timedelta, timezone
from pygit2 import Repository, Tag
from functools import lru_cache

def trim_commit(msg):
    if "\n" not in msg:
        return msg
    return msg[:msg.index("\n")]

def commit_time(commit):
    author = commit.author if hasattr(commit, 'author') else commit.tagger
    # Time handling in python is so dumb
    tzinfo = timezone(timedelta(minutes=author.offset))
    tzaware = datetime.fromtimestamp(float(author.time), tzinfo)
    diff = datetime.now(timezone.utc) - tzaware
    return datetime.utcnow() - diff

@lru_cache(maxsize=256)
def CachedRepository(path):
    return _CachedRepository(path)

@lru_cache(maxsize=1024)
def _get_ref(repo, ref):
    return repo._get(ref)

class _CachedRepository(Repository):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def get(self, ref):
        return _get_ref(self, ref)

    def _get(self, ref):
        return super().get(ref)

A gitsrht/redis.py => gitsrht/redis.py +3 -0
@@ 0,0 1,3 @@
from redis import Redis

redis = Redis()

M gitsrht/templates/summary.html => gitsrht/templates/summary.html +19 -29
@@ 4,67 4,57 @@
  <div class="row" style="margin-bottom: 1rem">
    <div class="col-md-6">
      <div class="event-list" style="margin-bottom: 0.5rem">
        {% for c in commits %}
        <div class="event">
          <div>
            <a href="#">emersion</a>
            <a href="#">&lt;contact@emersion.fr&gt;</a>
            <span class="text-muted">committed</span>
            <a href="#">ac28d701c</a>
            <span class="text-muted">14 hours ago</span>
            <a href="#">{{c.id.hex[:8]}}</a> &mdash;
            <a href="#">{{c.author.name}}</a>
            <span class="text-muted pull-right">
              {{ commit_time(c) | date }}
            </span>
          </div>
          <pre
            style="padding-left: 0; padding-right: 0; background: transparent"
          >buffer: disconnect clients that commit an unknown buffer type</pre>
        </div>
        <div class="event">
          <div>
            <a href="#">emersion</a>
            <a href="#">&lt;contact@emersion.fr&gt;</a>
            <span class="text-muted">committed</span>
            <a href="#">ac28d701c</a>
            <span class="text-muted">14 hours ago</span>
          </div>
        </div>
        <div class="event">
          <div>
            <a href="#">emersion</a>
            <a href="#">&lt;contact@emersion.fr&gt;</a>
            <span class="text-muted">committed</span>
            <a href="#">ac28d701c</a>
            <span class="text-muted">14 hours ago</span>
          </div>
          >{{ trim_commit(c.message) }}</pre>
        </div>
        {% endfor %}
      </div>
    </div>
    <div class="col-md-2">
      <h3>refs</h3>
      <dl>
        <dt>master</dt>
        {% if default_branch %}
        <dt>{{default_branch.name[len("refs/heads/"):]}}</dt>
        <dd>
          <a href="#">log {{icon("caret-right")}}</a>
          <a href="#">browse {{icon("caret-right")}}</a>
        </dd>
        <dt>v1.0</dt>
        {% endif %}
        {% if latest_tag %}
        <dt>{{ latest_tag[0][len("refs/tags/"):] }}</dt>
        <dd>
          <a href="#">log {{icon("caret-right")}}</a>
          <a href="#">.tar.gz {{icon("caret-right")}}</a>
        </dd>
        {% endif %}
      </dl>
    </div>
    <div class="col-md-4">
      <h3>clone</h3>
      <dl>
        <dt>read-only</dt>
        <dd><a href="#">https://git.sr.ht/~sircmpwn/wlroots</a></dd>
        <dd><a href="{{clone_urls[0]}}">{{clone_urls[0]}}</a></dd>
        <dt>read/write</dt>
        <dd>git@git.sr.ht/~sircmpwn/wlroots</dd>
        <dd>{{clone_urls[1]}}</dd>
      </dl>
    </div>
  </div>
  {% if readme %}
  <div class="row">
    <div class="col-md-10">
      {{ rm | extended_md }}
      {{ readme }}
    </div>
  </div>
  {% endif %}
</div>
{% endblock %}