forked from
tangled.org/core
Monorepo for Tangled
1package issues
2
3import (
4 "context"
5 "fmt"
6 "log"
7 "net/http"
8 "time"
9
10 "tangled.org/core/api/tangled"
11 "tangled.org/core/appview/db"
12 "tangled.org/core/appview/models"
13 "tangled.org/core/ogre"
14 "tangled.org/core/orm"
15)
16
17func (rp *Issues) IssueOpenGraphSummary(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 issue, ok := r.Context().Value("issue").(*models.Issue)
25 if !ok {
26 log.Println("issue not found in context")
27 http.Error(w, "issue not found", http.StatusNotFound)
28 return
29 }
30
31 labelDefs, err := db.GetLabelDefinitions(
32 rp.db,
33 orm.FilterIn("at_uri", f.Labels),
34 orm.FilterContains("scope", tangled.RepoIssueNSID),
35 )
36 if err != nil {
37 log.Println("failed to fetch label definitions")
38 http.Error(w, "label definitions not found", http.StatusInternalServerError)
39 return
40 }
41
42 defs := make(map[string]*models.LabelDefinition)
43 for _, l := range labelDefs {
44 defs[l.AtUri().String()] = &l
45 }
46
47 labels := []ogre.LabelData{}
48 for _, def := range defs {
49 for val := range issue.Labels.GetValSet(def.AtUri().String()) {
50 name := def.Name
51 value := ""
52
53 if !def.ValueType.IsNull() {
54 name = fmt.Sprintf("%s/", def.Name)
55 value = val
56
57 if def.ValueType.IsDidFormat() {
58 if o, err := rp.idResolver.ResolveIdent(context.Background(), val); err == nil {
59 value = o.Handle.String()
60 }
61 }
62 }
63 labels = append(labels, ogre.LabelData{
64 Color: def.GetColor(),
65 Name: fmt.Sprintf("%s%s", name, value),
66 })
67 }
68 }
69
70 var ownerHandle string
71 owner, err := rp.idResolver.ResolveIdent(context.Background(), f.Did)
72 if err != nil {
73 ownerHandle = f.Did
74 } else {
75 ownerHandle = owner.Handle.String()
76 }
77
78 avatarUrl := rp.pages.AvatarUrl(ownerHandle, "256")
79
80 status := "closed"
81 if issue.Open {
82 status = "open"
83 }
84
85 commentCount := len(issue.Comments)
86
87 reactionCount, _ := db.GetReactionCount(rp.db, issue.AtUri())
88
89 payload := ogre.IssueCardPayload{
90 Type: "issue",
91 RepoName: f.Name,
92 OwnerHandle: ownerHandle,
93 AvatarUrl: avatarUrl,
94 Title: issue.Title,
95 IssueNumber: issue.IssueId,
96 Status: status,
97 Labels: labels,
98 CommentCount: commentCount,
99 ReactionCount: reactionCount,
100 CreatedAt: issue.Created.Format(time.RFC3339),
101 }
102
103 imageBytes, err := rp.ogreClient.RenderIssueCard(r.Context(), payload)
104 if err != nil {
105 log.Println("failed to render issue card", err)
106 http.Error(w, "failed to render issue card", http.StatusInternalServerError)
107 return
108 }
109
110 w.Header().Set("Content-Type", "image/png")
111 w.Header().Set("Cache-Control", "public, max-age=3600")
112 w.WriteHeader(http.StatusOK)
113 _, err = w.Write(imageBytes)
114 if err != nil {
115 log.Println("failed to write issue card", err)
116 return
117 }
118}