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