forked from
tangled.org/core
Monorepo for Tangled
1package repo
2
3import (
4 "context"
5 "log"
6 "net/http"
7 "sort"
8 "time"
9
10 "github.com/go-enry/go-enry/v2"
11 "tangled.org/core/appview/db"
12 "tangled.org/core/ogre"
13 "tangled.org/core/orm"
14 "tangled.org/core/types"
15)
16
17func (rp *Repo) Opengraph(w http.ResponseWriter, r *http.Request) {
18 f, err := rp.repoResolver.Resolve(r)
19 if err != nil {
20 log.Println("failed to get repo and knot", err)
21 return
22 }
23
24 var ownerHandle string
25 owner, err := rp.idResolver.ResolveIdent(context.Background(), f.Did)
26 if err != nil {
27 ownerHandle = f.Did
28 } else {
29 ownerHandle = owner.Handle.String()
30 }
31
32 avatarUrl := rp.pages.AvatarUrl(ownerHandle, "256")
33
34 var languageStats []types.RepoLanguageDetails
35 langs, err := db.GetRepoLanguages(
36 rp.db,
37 orm.FilterEq("repo_at", f.RepoAt()),
38 orm.FilterEq("is_default_ref", 1),
39 )
40 if err != nil {
41 log.Printf("failed to get language stats from db: %v", err)
42 } else if len(langs) > 0 {
43 var total int64
44 for _, l := range langs {
45 total += l.Bytes
46 }
47
48 for _, l := range langs {
49 percentage := float32(l.Bytes) / float32(total) * 100
50 color := enry.GetColor(l.Language)
51 languageStats = append(languageStats, types.RepoLanguageDetails{
52 Name: l.Language,
53 Percentage: percentage,
54 Color: color,
55 })
56 }
57
58 sort.Slice(languageStats, func(i, j int) bool {
59 if languageStats[i].Name == enry.OtherLanguage {
60 return false
61 }
62 if languageStats[j].Name == enry.OtherLanguage {
63 return true
64 }
65 if languageStats[i].Percentage != languageStats[j].Percentage {
66 return languageStats[i].Percentage > languageStats[j].Percentage
67 }
68 return languageStats[i].Name < languageStats[j].Name
69 })
70 }
71
72 ogLanguages := []ogre.LanguageData{}
73 for _, lang := range languageStats {
74 if len(ogLanguages) >= 5 {
75 break
76 }
77 ogLanguages = append(ogLanguages, ogre.LanguageData{
78 Color: lang.Color,
79 Percentage: lang.Percentage,
80 })
81 }
82
83 payload := ogre.RepositoryCardPayload{
84 Type: "repository",
85 RepoName: f.Name,
86 OwnerHandle: ownerHandle,
87 Stars: f.RepoStats.StarCount,
88 Pulls: f.RepoStats.PullCount.Open,
89 Issues: f.RepoStats.IssueCount.Open,
90 CreatedAt: f.Created.Format(time.RFC3339),
91 AvatarUrl: avatarUrl,
92 Languages: ogLanguages,
93 }
94
95 imageBytes, err := rp.ogreClient.RenderRepositoryCard(r.Context(), payload)
96 if err != nil {
97 log.Println("failed to render repository card", err)
98 http.Error(w, "failed to render repository card", http.StatusInternalServerError)
99 return
100 }
101
102 w.Header().Set("Content-Type", "image/png")
103 w.Header().Set("Cache-Control", "public, max-age=3600")
104 w.WriteHeader(http.StatusOK)
105 _, err = w.Write(imageBytes)
106 if err != nil {
107 log.Println("failed to write repository card", err)
108 return
109 }
110}