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