From 368a8bca05aea9aa5ca9c3ea888fa9390c14e0d4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 14 Feb 2020 17:09:32 -0500 Subject: [PATCH] API: add list of artifacts associated with each ref --- gitsrht/blueprints/api.py | 26 +++++++++++++++++++++----- gitsrht/blueprints/artifacts.py | 1 - gitsrht/types/artifact.py | 19 ++++++++++++++++++- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/gitsrht/blueprints/api.py b/gitsrht/blueprints/api.py index b6b40b4..f85b8e4 100644 --- a/gitsrht/blueprints/api.py +++ b/gitsrht/blueprints/api.py @@ -4,10 +4,12 @@ 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, collect_refs +from gitsrht.types import Artifact from gitsrht.git import Repository as GitRepository, commit_time, annotate_tree from gitsrht.git import get_log from gitsrht.webhooks import RepoWebhook from io import BytesIO +from itertools import groupby from scmsrht.access import UserAccess from scmsrht.blueprints.api import get_user, get_repo from srht.api import paginated_response @@ -54,6 +56,14 @@ def tree_to_dict(t): ] } +def ref_to_dict(artifacts, ref): + target = ref.target.hex + return { + "target": target, + "name": ref.name, + "artifacts": [a.to_dict() for a in artifacts.get(target, [])], + } + @data.route("/api/repos//refs", defaults={"username": None}) @data.route("/api//repos//refs") @oauth("data:read") @@ -62,15 +72,21 @@ def repo_refs_GET(username, reponame): repo = get_repo(user, reponame) with GitRepository(repo.path) as git_repo: - refs = list(git_repo.references) # TODO: pagination + refs = list(git_repo.references) + targets = [git_repo.references[ref].target.hex for ref in refs] + artifacts = (Artifact.query + .filter(Artifact.user_id == repo.owner_id) + .filter(Artifact.repo_id == repo.id) + .filter(Artifact.commit.in_(targets))).all() + artifacts = { + key: list(value) for key, value in + groupby(artifacts, key=lambda a: a.commit) + } return { "next": None, "results": [ - { - "target": str(git_repo.references[ref].target), - "name": ref, - } for ref in refs + ref_to_dict(artifacts, git_repo.references[ref]) for ref in refs ], "total": len(refs), "results_per_page": len(refs), diff --git a/gitsrht/blueprints/artifacts.py b/gitsrht/blueprints/artifacts.py index 8bc63fb..c382084 100644 --- a/gitsrht/blueprints/artifacts.py +++ b/gitsrht/blueprints/artifacts.py @@ -17,7 +17,6 @@ from werkzeug.utils import secure_filename artifacts = Blueprint('artifacts', __name__) -# TODO: Make S3 support optional s3_upstream = cfg("objects", "s3-upstream", default=None) s3_access_key = cfg("objects", "s3-access-key", default=None) s3_secret_key = cfg("objects", "s3-secret-key", default=None) diff --git a/gitsrht/types/artifact.py b/gitsrht/types/artifact.py index a1efc63..e49254c 100644 --- a/gitsrht/types/artifact.py +++ b/gitsrht/types/artifact.py @@ -1,5 +1,7 @@ +import os import sqlalchemy as sa import sqlalchemy_utils as sau +from srht.config import cfg from srht.database import Base class Artifact(Base): @@ -16,4 +18,19 @@ class Artifact(Base): size = sa.Column(sa.Integer, nullable=False) def __repr__(self): - return ''.format(self.id, self.fingerprint) + return ''.format(self.id, self.filename) + + def to_dict(self): + s3_upstream = cfg("objects", "s3-upstream") + s3_bucket = cfg("git.sr.ht", "s3-bucket") + s3_prefix = cfg("git.sr.ht", "s3-prefix") + prefix = os.path.join(s3_prefix, "artifacts", + self.repo.owner.canonical_name, self.repo.name) + url = f"https://{s3_upstream}/{s3_bucket}/{prefix}/{self.filename}" + return { + "created": self.created, + "checksum": self.checksum, + "size": self.size, + "filename": self.filename, + "url": url, + } -- 2.38.4