This repository has no description
2.2 kB
86 lines
1package xrpc
2
3import (
4 "context"
5 "fmt"
6 "math"
7 "net/http"
8 "time"
9
10 "github.com/bluesky-social/indigo/atproto/atclient"
11 "github.com/bluesky-social/indigo/atproto/syntax"
12 "tangled.org/core/api/tangled"
13 "tangled.org/core/knotserver/git"
14)
15
16func (x *Xrpc) ListLanguages(w http.ResponseWriter, r *http.Request) {
17 var (
18 repoQuery = r.URL.Query().Get("repo")
19 ref = r.URL.Query().Get("ref")
20 )
21 l := x.logger.With("repo", repoQuery, "ref", ref)
22
23 repo, err := syntax.ParseATURI(repoQuery)
24 if err != nil || repo.RecordKey() == "" {
25 l.Error("invalid repo at-uri", "err", err)
26 writeJson(w, http.StatusBadRequest, atclient.ErrorBody{Name: "BadRequest", Message: fmt.Sprintf("repo parameter invalid: %s", repoQuery)})
27 return
28 }
29
30 out, err := x.listLanguages(r.Context(), repo, ref)
31 if err != nil {
32 l.Error("failed to list languages", "err", err)
33 writeErr(w, err)
34 return
35 }
36
37 writeJson(w, http.StatusOK, out)
38}
39
40func (x *Xrpc) listLanguages(ctx context.Context, repo syntax.ATURI, ref string) (*tangled.GitTempListLanguages_Output, error) {
41 repoPath, err := x.makeRepoPath(ctx, repo)
42 if err != nil {
43 return nil, fmt.Errorf("resolving repo at-uri: %w", err)
44 }
45
46 gr, err := git.Open(repoPath, ref)
47 if err != nil {
48 return nil, &atclient.APIError{StatusCode: http.StatusNotFound, Name: "RepoNotFound", Message: "failed to find git repo"}
49 }
50
51 ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
52 defer cancel()
53
54 sizes, err := gr.AnalyzeLanguages(ctx)
55 if err != nil {
56 return nil, fmt.Errorf("analyzing languages: %w", err)
57 }
58
59 return &tangled.GitTempListLanguages_Output{
60 Ref: ref,
61 Languages: sizesToLanguages(sizes),
62 }, nil
63}
64
65func sizesToLanguages(sizes git.LangBreakdown) []*tangled.GitTempListLanguages_Language {
66 var apiLanguages []*tangled.GitTempListLanguages_Language
67 var totalSize int64
68 for _, size := range sizes {
69 totalSize += size
70 }
71
72 for name, size := range sizes {
73 percentagef64 := float64(size) / float64(totalSize) * 100
74 percentage := math.Round(percentagef64)
75
76 lang := &tangled.GitTempListLanguages_Language{
77 Name: name,
78 Size: size,
79 Percentage: int64(percentage),
80 }
81
82 apiLanguages = append(apiLanguages, lang)
83 }
84
85 return apiLanguages
86}