Monorepo for Tangled
1package models
2
3import (
4 "fmt"
5
6 "github.com/bluesky-social/indigo/atproto/syntax"
7 "tangled.org/core/api/tangled"
8)
9
10type Profile struct {
11 // ids
12 ID int
13 Did string
14
15 // data
16 Avatar string // CID of the avatar blob
17 Description string
18 IncludeBluesky bool
19 Location string
20 Links [5]string
21 Stats [2]VanityStat
22 PinnedRepos [6]syntax.ATURI
23 Pronouns string
24}
25
26func (p Profile) IsLinksEmpty() bool {
27 for _, l := range p.Links {
28 if l != "" {
29 return false
30 }
31 }
32 return true
33}
34
35func (p Profile) IsStatsEmpty() bool {
36 for _, s := range p.Stats {
37 if s.Kind != "" {
38 return false
39 }
40 }
41 return true
42}
43
44func (p Profile) IsPinnedReposEmpty() bool {
45 for _, r := range p.PinnedRepos {
46 if r != "" {
47 return false
48 }
49 }
50 return true
51}
52
53type VanityStatKind string
54
55const (
56 VanityStatMergedPRCount VanityStatKind = "merged-pull-request-count"
57 VanityStatClosedPRCount VanityStatKind = "closed-pull-request-count"
58 VanityStatOpenPRCount VanityStatKind = "open-pull-request-count"
59 VanityStatOpenIssueCount VanityStatKind = "open-issue-count"
60 VanityStatClosedIssueCount VanityStatKind = "closed-issue-count"
61 VanityStatRepositoryCount VanityStatKind = "repository-count"
62 VanityStatStarCount VanityStatKind = "star-count"
63)
64
65func (v VanityStatKind) String() string {
66 switch v {
67 case VanityStatMergedPRCount:
68 return "Merged PRs"
69 case VanityStatClosedPRCount:
70 return "Closed PRs"
71 case VanityStatOpenPRCount:
72 return "Open PRs"
73 case VanityStatOpenIssueCount:
74 return "Open Issues"
75 case VanityStatClosedIssueCount:
76 return "Closed Issues"
77 case VanityStatRepositoryCount:
78 return "Repositories"
79 case VanityStatStarCount:
80 return "Stars Received"
81 }
82 return ""
83}
84
85type VanityStat struct {
86 Kind VanityStatKind
87 Value uint64
88}
89
90func (p *Profile) ProfileAt() syntax.ATURI {
91 return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", p.Did, tangled.ActorProfileNSID, "self"))
92}
93
94type RepoEvent struct {
95 Repo *Repo
96 Source *Repo
97}
98
99type ProfileTimeline struct {
100 ByMonth []ByMonth
101}
102
103func (p *ProfileTimeline) IsEmpty() bool {
104 if p == nil {
105 return true
106 }
107
108 for _, m := range p.ByMonth {
109 if !m.IsEmpty() {
110 return false
111 }
112 }
113
114 return true
115}
116
117type ByMonth struct {
118 Commits int
119 RepoEvents []RepoEvent
120 IssueEvents IssueEvents
121 PullEvents PullEvents
122}
123
124func (b ByMonth) IsEmpty() bool {
125 return len(b.RepoEvents) == 0 &&
126 len(b.IssueEvents.Items) == 0 &&
127 len(b.PullEvents.Items) == 0 &&
128 b.Commits == 0
129}
130
131type IssueEvents struct {
132 Items []*Issue
133}
134
135type IssueEventStats struct {
136 Open int
137 Closed int
138}
139
140func (i IssueEvents) Stats() IssueEventStats {
141 var open, closed int
142 for _, issue := range i.Items {
143 if issue.Open {
144 open += 1
145 } else {
146 closed += 1
147 }
148 }
149
150 return IssueEventStats{
151 Open: open,
152 Closed: closed,
153 }
154}
155
156type PullEvents struct {
157 Items []*Pull
158}
159
160func (p PullEvents) Stats() PullEventStats {
161 var open, merged, closed int
162 for _, pull := range p.Items {
163 switch pull.State {
164 case PullOpen:
165 open += 1
166 case PullMerged:
167 merged += 1
168 case PullClosed:
169 closed += 1
170 }
171 }
172
173 return PullEventStats{
174 Open: open,
175 Merged: merged,
176 Closed: closed,
177 }
178}
179
180type PullEventStats struct {
181 Closed int
182 Open int
183 Merged int
184}