~edwargix/git.sr.ht

368a8bca05aea9aa5ca9c3ea888fa9390c14e0d4 — Drew DeVault 5 years ago c95a349
API: add list of artifacts associated with each ref
3 files changed, 39 insertions(+), 7 deletions(-)

M gitsrht/blueprints/api.py
M gitsrht/blueprints/artifacts.py
M gitsrht/types/artifact.py
M gitsrht/blueprints/api.py => gitsrht/blueprints/api.py +21 -5
@@ 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/<reponame>/refs", defaults={"username": None})
@data.route("/api/<username>/repos/<reponame>/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),

M gitsrht/blueprints/artifacts.py => gitsrht/blueprints/artifacts.py +0 -1
@@ 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)

M gitsrht/types/artifact.py => gitsrht/types/artifact.py +18 -1
@@ 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 '<Artifact {} {}>'.format(self.id, self.fingerprint)
        return '<Artifact {} {}>'.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,
        }