Monorepo for Tangled
tangled.org
1package pages
2
3import (
4 "context"
5 "database/sql"
6 "fmt"
7 "path"
8 "strconv"
9
10 "github.com/bluesky-social/indigo/atproto/syntax"
11 "tangled.org/core/api/tangled"
12 "tangled.org/core/appview/db"
13 "tangled.org/core/appview/models"
14 "tangled.org/core/orm"
15)
16
17func (p *Pages) MakeCommentUrl(ctx context.Context, uri syntax.ATURI) (string, error) {
18 comment, err := db.GetComment(p.db, orm.FilterEq("at_uri", uri))
19 if err != nil {
20 return "", fmt.Errorf("failed to get comment: %w", err)
21 }
22 subjectUri := syntax.ATURI(comment.Subject.Uri)
23 switch subjectUri.Collection() {
24 case tangled.RepoIssueNSID:
25 issueUrl, err := p.MakeIssueUrl(ctx, subjectUri)
26 if err != nil {
27 return "", fmt.Errorf("failed to make issue url: %w", err)
28 }
29 return issueUrl + fmt.Sprintf("#comment-%s", comment.Rkey), nil
30 case tangled.RepoPullNSID:
31 if comment.PullRoundIdx == nil {
32 return "", fmt.Errorf("comment.pullRoundIdx is missing")
33 }
34 pullUrl, err := p.MakePullUrl(ctx, subjectUri, *comment.PullRoundIdx)
35 if err != nil {
36 return "", fmt.Errorf("failed to make pull url: %w", err)
37 }
38 return pullUrl + fmt.Sprintf("#comment-%s", comment.Rkey), nil
39 case tangled.StringNSID:
40 stringUrl, err := p.MakeStringUrl(ctx, subjectUri)
41 if err != nil {
42 return "", fmt.Errorf("failed to make string url: %w", err)
43 }
44 return stringUrl + fmt.Sprintf("#comment-%s", comment.Rkey), nil
45 default:
46 return "", fmt.Errorf("unknown subject collection '%s'", subjectUri.Collection())
47 }
48}
49
50func (p *Pages) MakeIssueUrl(ctx context.Context, uri syntax.ATURI) (string, error) {
51 issue, err := func(uri syntax.ATURI) (*models.Issue, error) {
52 issues, err := db.GetIssues(p.db, orm.FilterEq("at_uri", uri))
53 if err != nil {
54 return nil, err
55 }
56 if len(issues) != 1 {
57 return nil, sql.ErrNoRows
58 }
59 return &issues[0], nil
60 }(uri)
61 if err != nil {
62 return "", fmt.Errorf("failed to get issue: %w", err)
63 }
64 repoUrl, err := p.makeRepoUrlInner(ctx, issue.Repo)
65 if err != nil {
66 return "", fmt.Errorf("failed to make repo url: %w", err)
67 }
68 return path.Join(repoUrl, "issues", strconv.FormatInt(issue.Id, 10)), nil
69}
70
71func (p *Pages) MakePullUrl(ctx context.Context, uri syntax.ATURI, roundIdx int) (string, error) {
72 pull, err := db.GetPull(p.db, orm.FilterEq("at_uri", uri))
73 if err != nil {
74 return "", fmt.Errorf("failed to get pull: %w", err)
75 }
76 repoUrl, err := p.makeRepoUrlInner(ctx, pull.Repo)
77 if err != nil {
78 return "", fmt.Errorf("failed to make repo url: %w", err)
79 }
80 return path.Join(repoUrl, "pulls", strconv.Itoa(pull.ID), "rounds", strconv.Itoa(roundIdx)), nil
81}
82
83func (p *Pages) makeRepoUrlInner(ctx context.Context, repo *models.Repo) (string, error) {
84 owner := repo.Did
85 ownerIdentity, err := p.resolver.Directory().LookupDID(ctx, syntax.DID(repo.Did))
86 if err == nil && !ownerIdentity.Handle.IsInvalidHandle() {
87 owner = ownerIdentity.Handle.String()
88 }
89 return path.Join("/", owner, repo.Slug()), nil
90}
91
92func (p *Pages) MakeStringUrl(ctx context.Context, uri syntax.ATURI) (string, error) {
93 string_, err := func(uri syntax.ATURI) (*models.String, error) {
94 strings, err := db.GetStrings(p.db, 1, orm.FilterEq("at_uri", uri))
95 if err != nil {
96 return nil, err
97 }
98 if len(strings) != 1 {
99 return nil, sql.ErrNoRows
100 }
101 return &strings[0], nil
102 }(uri)
103 if err != nil {
104 return "", fmt.Errorf("failed to get string: %w", err)
105 }
106
107 owner := string_.Did.String()
108 ownerIdentity, err := p.resolver.Directory().LookupDID(ctx, string_.Did)
109 if err == nil && !ownerIdentity.Handle.IsInvalidHandle() {
110 owner = ownerIdentity.Handle.String()
111 }
112 return path.Join("/strings", owner, string_.Rkey.String()), nil
113}