diff options
Diffstat (limited to 'gitsrht/blueprints')
-rw-r--r-- | gitsrht/blueprints/api.py | 30 | ||||
-rw-r--r-- | gitsrht/blueprints/repo.py | 14 |
2 files changed, 41 insertions, 3 deletions
diff --git a/gitsrht/blueprints/api.py b/gitsrht/blueprints/api.py index 58bcb8b..fa223ab 100644 --- a/gitsrht/blueprints/api.py +++ b/gitsrht/blueprints/api.py @@ -1,13 +1,17 @@ import base64 +import json import pygit2 from flask import Blueprint, current_app, request, send_file, abort +from gitsrht.annotations import validate_annotation from gitsrht.blueprints.repo import lookup_ref, get_log, collect_refs from gitsrht.git import Repository as GitRepository, commit_time, annotate_tree from gitsrht.webhooks import RepoWebhook from io import BytesIO from scmsrht.blueprints.api import get_user, get_repo +from scmsrht.redis import redis from srht.api import paginated_response from srht.oauth import current_token, oauth +from srht.validation import Validation data = Blueprint("api.data", __name__) @@ -133,6 +137,32 @@ def repo_tree_GET(username, reponame, ref, path): abort(404) return tree_to_dict(tree) +@data.route("/api/repos/<reponame>/annotate", methods=["PUT"]) +@data.route("/api/<username>/repos/<reponame>/annotate", methods=["PUT"]) +@oauth("data:read") +def repo_annotate_PUT(username, reponame): + user = get_user(username) + repo = get_repo(user, reponame) + + valid = Validation(request) + + for oid, annotations in valid.source.items(): + valid.expect(isinstance(oid, str), "blob keys must be strings") + valid.expect(isinstance(annotations, list), + "blob values must be lists of annotations") + if not valid.ok: + return valid.response + for anno in annotations: + validate_annotation(valid, anno) + if not valid.ok: + return valid.response + # TODO: more validation on annotation structure + redis.set(f"git.sr.ht:git:annotations:{oid}", json.dumps(annotations)) + # Invalidate rendered markup cache + redis.delete(f"git.sr.ht:git:highlight:{oid}") + + return { }, 200 + @data.route("/api/repos/<reponame>/blob/<path:ref>", defaults={"username": None, "path": ""}) @data.route("/api/repos/<reponame>/blob/<ref>/<path:path>", diff --git a/gitsrht/blueprints/repo.py b/gitsrht/blueprints/repo.py index fe9e068..a12bf8e 100644 --- a/gitsrht/blueprints/repo.py +++ b/gitsrht/blueprints/repo.py @@ -1,13 +1,15 @@ import binascii +import json import os import pygit2 import pygments -import sys import subprocess +import sys from datetime import timedelta from jinja2 import Markup from flask import Blueprint, render_template, abort, send_file, request from flask import Response, url_for +from gitsrht.annotations import AnnotatedFormatter from gitsrht.editorconfig import EditorConfig from gitsrht.git import Repository as GitRepository, commit_time, annotate_tree from gitsrht.git import diffstat @@ -45,8 +47,14 @@ def get_readme(repo, tip, link_prefix=None): return get_formatted_readme("git.sr.ht:git", file_finder, content_getter, link_prefix=link_prefix) -def _highlight_file(name, data, blob_id): - return get_highlighted_file("git.sr.ht:git", name, blob_id, data) +def _highlight_file(repo, ref, name, data, blob_id): + annotations = redis.get(f"git.sr.ht:git:annotations:{blob_id}") + if annotations: + annotations = json.loads(annotations.decode()) + link_prefix = url_for( + 'repo.tree', owner=repo.owner, repo=repo.name, ref=ref) + return get_highlighted_file("git.sr.ht:git", name, blob_id, data, + formatter=AnnotatedFormatter(annotations, link_prefix)) def render_empty_repo(owner, repo): origin = cfg("git.sr.ht", "origin") |