forked from tangled.org/core
Monorepo for Tangled

appview/models: move db.Profile* into models

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li faf3fc63 1b61bb16

verified
Changed files
+217 -210
appview
+20 -190
appview/db/profile.go
··· 10 10 "time" 11 11 12 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 - "tangled.org/core/api/tangled" 14 13 "tangled.org/core/appview/models" 15 14 ) 16 15 17 - type RepoEvent struct { 18 - Repo *models.Repo 19 - Source *models.Repo 20 - } 21 - 22 - type ProfileTimeline struct { 23 - ByMonth []ByMonth 24 - } 25 - 26 - func (p *ProfileTimeline) IsEmpty() bool { 27 - if p == nil { 28 - return true 29 - } 30 - 31 - for _, m := range p.ByMonth { 32 - if !m.IsEmpty() { 33 - return false 34 - } 35 - } 36 - 37 - return true 38 - } 39 - 40 - type ByMonth struct { 41 - RepoEvents []RepoEvent 42 - IssueEvents IssueEvents 43 - PullEvents PullEvents 44 - } 45 - 46 - func (b ByMonth) IsEmpty() bool { 47 - return len(b.RepoEvents) == 0 && 48 - len(b.IssueEvents.Items) == 0 && 49 - len(b.PullEvents.Items) == 0 50 - } 51 - 52 - type IssueEvents struct { 53 - Items []*models.Issue 54 - } 55 - 56 - type IssueEventStats struct { 57 - Open int 58 - Closed int 59 - } 60 - 61 - func (i IssueEvents) Stats() IssueEventStats { 62 - var open, closed int 63 - for _, issue := range i.Items { 64 - if issue.Open { 65 - open += 1 66 - } else { 67 - closed += 1 68 - } 69 - } 70 - 71 - return IssueEventStats{ 72 - Open: open, 73 - Closed: closed, 74 - } 75 - } 76 - 77 - type PullEvents struct { 78 - Items []*models.Pull 79 - } 80 - 81 - func (p PullEvents) Stats() PullEventStats { 82 - var open, merged, closed int 83 - for _, pull := range p.Items { 84 - switch pull.State { 85 - case models.PullOpen: 86 - open += 1 87 - case models.PullMerged: 88 - merged += 1 89 - case models.PullClosed: 90 - closed += 1 91 - } 92 - } 93 - 94 - return PullEventStats{ 95 - Open: open, 96 - Merged: merged, 97 - Closed: closed, 98 - } 99 - } 100 - 101 - type PullEventStats struct { 102 - Closed int 103 - Open int 104 - Merged int 105 - } 106 - 107 16 const TimeframeMonths = 7 108 17 109 - func MakeProfileTimeline(e Execer, forDid string) (*ProfileTimeline, error) { 110 - timeline := ProfileTimeline{ 111 - ByMonth: make([]ByMonth, TimeframeMonths), 18 + func MakeProfileTimeline(e Execer, forDid string) (*models.ProfileTimeline, error) { 19 + timeline := models.ProfileTimeline{ 20 + ByMonth: make([]models.ByMonth, TimeframeMonths), 112 21 } 113 22 currentMonth := time.Now().Month() 114 23 timeframe := fmt.Sprintf("-%d months", TimeframeMonths) ··· 181 90 idx := currentMonth - repoMonth 182 91 183 92 items := &timeline.ByMonth[idx].RepoEvents 184 - *items = append(*items, RepoEvent{ 93 + *items = append(*items, models.RepoEvent{ 185 94 Repo: &repo, 186 95 Source: sourceRepo, 187 96 }) ··· 190 99 return &timeline, nil 191 100 } 192 101 193 - type Profile struct { 194 - // ids 195 - ID int 196 - Did string 197 - 198 - // data 199 - Description string 200 - IncludeBluesky bool 201 - Location string 202 - Links [5]string 203 - Stats [2]VanityStat 204 - PinnedRepos [6]syntax.ATURI 205 - } 206 - 207 - func (p Profile) IsLinksEmpty() bool { 208 - for _, l := range p.Links { 209 - if l != "" { 210 - return false 211 - } 212 - } 213 - return true 214 - } 215 - 216 - func (p Profile) IsStatsEmpty() bool { 217 - for _, s := range p.Stats { 218 - if s.Kind != "" { 219 - return false 220 - } 221 - } 222 - return true 223 - } 224 - 225 - func (p Profile) IsPinnedReposEmpty() bool { 226 - for _, r := range p.PinnedRepos { 227 - if r != "" { 228 - return false 229 - } 230 - } 231 - return true 232 - } 233 - 234 - type VanityStatKind string 235 - 236 - const ( 237 - VanityStatMergedPRCount VanityStatKind = "merged-pull-request-count" 238 - VanityStatClosedPRCount VanityStatKind = "closed-pull-request-count" 239 - VanityStatOpenPRCount VanityStatKind = "open-pull-request-count" 240 - VanityStatOpenIssueCount VanityStatKind = "open-issue-count" 241 - VanityStatClosedIssueCount VanityStatKind = "closed-issue-count" 242 - VanityStatRepositoryCount VanityStatKind = "repository-count" 243 - ) 244 - 245 - func (v VanityStatKind) String() string { 246 - switch v { 247 - case VanityStatMergedPRCount: 248 - return "Merged PRs" 249 - case VanityStatClosedPRCount: 250 - return "Closed PRs" 251 - case VanityStatOpenPRCount: 252 - return "Open PRs" 253 - case VanityStatOpenIssueCount: 254 - return "Open Issues" 255 - case VanityStatClosedIssueCount: 256 - return "Closed Issues" 257 - case VanityStatRepositoryCount: 258 - return "Repositories" 259 - } 260 - return "" 261 - } 262 - 263 - type VanityStat struct { 264 - Kind VanityStatKind 265 - Value uint64 266 - } 267 - 268 - func (p *Profile) ProfileAt() syntax.ATURI { 269 - return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", p.Did, tangled.ActorProfileNSID, "self")) 270 - } 271 - 272 - func UpsertProfile(tx *sql.Tx, profile *Profile) error { 102 + func UpsertProfile(tx *sql.Tx, profile *models.Profile) error { 273 103 defer tx.Rollback() 274 104 275 105 // update links ··· 367 197 return tx.Commit() 368 198 } 369 199 370 - func GetProfiles(e Execer, filters ...filter) (map[string]*Profile, error) { 200 + func GetProfiles(e Execer, filters ...filter) (map[string]*models.Profile, error) { 371 201 var conditions []string 372 202 var args []any 373 203 for _, filter := range filters { ··· 397 227 return nil, err 398 228 } 399 229 400 - profileMap := make(map[string]*Profile) 230 + profileMap := make(map[string]*models.Profile) 401 231 for rows.Next() { 402 - var profile Profile 232 + var profile models.Profile 403 233 var includeBluesky int 404 234 405 235 err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location) ··· 470 300 return profileMap, nil 471 301 } 472 302 473 - func GetProfile(e Execer, did string) (*Profile, error) { 474 - var profile Profile 303 + func GetProfile(e Execer, did string) (*models.Profile, error) { 304 + var profile models.Profile 475 305 profile.Did = did 476 306 477 307 includeBluesky := 0 ··· 480 310 did, 481 311 ).Scan(&profile.Description, &includeBluesky, &profile.Location) 482 312 if err == sql.ErrNoRows { 483 - profile := Profile{} 313 + profile := models.Profile{} 484 314 profile.Did = did 485 315 return &profile, nil 486 316 } ··· 540 370 return &profile, nil 541 371 } 542 372 543 - func GetVanityStat(e Execer, did string, stat VanityStatKind) (uint64, error) { 373 + func GetVanityStat(e Execer, did string, stat models.VanityStatKind) (uint64, error) { 544 374 query := "" 545 375 var args []any 546 376 switch stat { 547 - case VanityStatMergedPRCount: 377 + case models.VanityStatMergedPRCount: 548 378 query = `select count(id) from pulls where owner_did = ? and state = ?` 549 379 args = append(args, did, models.PullMerged) 550 - case VanityStatClosedPRCount: 380 + case models.VanityStatClosedPRCount: 551 381 query = `select count(id) from pulls where owner_did = ? and state = ?` 552 382 args = append(args, did, models.PullClosed) 553 - case VanityStatOpenPRCount: 383 + case models.VanityStatOpenPRCount: 554 384 query = `select count(id) from pulls where owner_did = ? and state = ?` 555 385 args = append(args, did, models.PullOpen) 556 - case VanityStatOpenIssueCount: 386 + case models.VanityStatOpenIssueCount: 557 387 query = `select count(id) from issues where did = ? and open = 1` 558 388 args = append(args, did) 559 - case VanityStatClosedIssueCount: 389 + case models.VanityStatClosedIssueCount: 560 390 query = `select count(id) from issues where did = ? and open = 0` 561 391 args = append(args, did) 562 - case VanityStatRepositoryCount: 392 + case models.VanityStatRepositoryCount: 563 393 query = `select count(id) from repos where did = ?` 564 394 args = append(args, did) 565 395 } ··· 573 403 return result, nil 574 404 } 575 405 576 - func ValidateProfile(e Execer, profile *Profile) error { 406 + func ValidateProfile(e Execer, profile *models.Profile) error { 577 407 // ensure description is not too long 578 408 if len(profile.Description) > 256 { 579 409 return fmt.Errorf("Entered bio is too long.") ··· 621 451 return nil 622 452 } 623 453 624 - func validateLinks(profile *Profile) error { 454 + func validateLinks(profile *models.Profile) error { 625 455 for i, link := range profile.Links { 626 456 if link == "" { 627 457 continue
+1 -1
appview/db/timeline.go
··· 19 19 Source *models.Repo 20 20 21 21 // optional: populate only if event is Follow 22 - *Profile 22 + *models.Profile 23 23 *models.FollowStats 24 24 *models.FollowStatus 25 25
+3 -3
appview/ingester.go
··· 299 299 } 300 300 } 301 301 302 - var stats [2]db.VanityStat 302 + var stats [2]models.VanityStat 303 303 for i, s := range record.Stats { 304 304 if i < 2 { 305 - stats[i].Kind = db.VanityStatKind(s) 305 + stats[i].Kind = models.VanityStatKind(s) 306 306 } 307 307 } 308 308 ··· 313 313 } 314 314 } 315 315 316 - profile := db.Profile{ 316 + profile := models.Profile{ 317 317 Did: did, 318 318 Description: description, 319 319 IncludeBluesky: includeBluesky,
+177
appview/models/profile.go
··· 1 + package models 2 + 3 + import ( 4 + "fmt" 5 + 6 + "github.com/bluesky-social/indigo/atproto/syntax" 7 + "tangled.org/core/api/tangled" 8 + ) 9 + 10 + type 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 + } 23 + 24 + func (p Profile) IsLinksEmpty() bool { 25 + for _, l := range p.Links { 26 + if l != "" { 27 + return false 28 + } 29 + } 30 + return true 31 + } 32 + 33 + func (p Profile) IsStatsEmpty() bool { 34 + for _, s := range p.Stats { 35 + if s.Kind != "" { 36 + return false 37 + } 38 + } 39 + return true 40 + } 41 + 42 + func (p Profile) IsPinnedReposEmpty() bool { 43 + for _, r := range p.PinnedRepos { 44 + if r != "" { 45 + return false 46 + } 47 + } 48 + return true 49 + } 50 + 51 + type VanityStatKind string 52 + 53 + const ( 54 + VanityStatMergedPRCount VanityStatKind = "merged-pull-request-count" 55 + VanityStatClosedPRCount VanityStatKind = "closed-pull-request-count" 56 + VanityStatOpenPRCount VanityStatKind = "open-pull-request-count" 57 + VanityStatOpenIssueCount VanityStatKind = "open-issue-count" 58 + VanityStatClosedIssueCount VanityStatKind = "closed-issue-count" 59 + VanityStatRepositoryCount VanityStatKind = "repository-count" 60 + ) 61 + 62 + func (v VanityStatKind) String() string { 63 + switch v { 64 + case VanityStatMergedPRCount: 65 + return "Merged PRs" 66 + case VanityStatClosedPRCount: 67 + return "Closed PRs" 68 + case VanityStatOpenPRCount: 69 + return "Open PRs" 70 + case VanityStatOpenIssueCount: 71 + return "Open Issues" 72 + case VanityStatClosedIssueCount: 73 + return "Closed Issues" 74 + case VanityStatRepositoryCount: 75 + return "Repositories" 76 + } 77 + return "" 78 + } 79 + 80 + type VanityStat struct { 81 + Kind VanityStatKind 82 + Value uint64 83 + } 84 + 85 + func (p *Profile) ProfileAt() syntax.ATURI { 86 + return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", p.Did, tangled.ActorProfileNSID, "self")) 87 + } 88 + 89 + type RepoEvent struct { 90 + Repo *Repo 91 + Source *Repo 92 + } 93 + 94 + type ProfileTimeline struct { 95 + ByMonth []ByMonth 96 + } 97 + 98 + func (p *ProfileTimeline) IsEmpty() bool { 99 + if p == nil { 100 + return true 101 + } 102 + 103 + for _, m := range p.ByMonth { 104 + if !m.IsEmpty() { 105 + return false 106 + } 107 + } 108 + 109 + return true 110 + } 111 + 112 + type ByMonth struct { 113 + RepoEvents []RepoEvent 114 + IssueEvents IssueEvents 115 + PullEvents PullEvents 116 + } 117 + 118 + func (b ByMonth) IsEmpty() bool { 119 + return len(b.RepoEvents) == 0 && 120 + len(b.IssueEvents.Items) == 0 && 121 + len(b.PullEvents.Items) == 0 122 + } 123 + 124 + type IssueEvents struct { 125 + Items []*Issue 126 + } 127 + 128 + type IssueEventStats struct { 129 + Open int 130 + Closed int 131 + } 132 + 133 + func (i IssueEvents) Stats() IssueEventStats { 134 + var open, closed int 135 + for _, issue := range i.Items { 136 + if issue.Open { 137 + open += 1 138 + } else { 139 + closed += 1 140 + } 141 + } 142 + 143 + return IssueEventStats{ 144 + Open: open, 145 + Closed: closed, 146 + } 147 + } 148 + 149 + type PullEvents struct { 150 + Items []*Pull 151 + } 152 + 153 + func (p PullEvents) Stats() PullEventStats { 154 + var open, merged, closed int 155 + for _, pull := range p.Items { 156 + switch pull.State { 157 + case PullOpen: 158 + open += 1 159 + case PullMerged: 160 + merged += 1 161 + case PullClosed: 162 + closed += 1 163 + } 164 + } 165 + 166 + return PullEventStats{ 167 + Open: open, 168 + Merged: merged, 169 + Closed: closed, 170 + } 171 + } 172 + 173 + type PullEventStats struct { 174 + Closed int 175 + Open int 176 + Merged int 177 + }
+1 -1
appview/notify/merged_notifier.go
··· 62 62 } 63 63 } 64 64 65 - func (m *mergedNotifier) UpdateProfile(ctx context.Context, profile *db.Profile) { 65 + func (m *mergedNotifier) UpdateProfile(ctx context.Context, profile *models.Profile) { 66 66 for _, notifier := range m.notifiers { 67 67 notifier.UpdateProfile(ctx, profile) 68 68 }
+2 -2
appview/notify/notifier.go
··· 21 21 NewPull(ctx context.Context, pull *models.Pull) 22 22 NewPullComment(ctx context.Context, comment *models.PullComment) 23 23 24 - UpdateProfile(ctx context.Context, profile *db.Profile) 24 + UpdateProfile(ctx context.Context, profile *models.Profile) 25 25 26 26 NewString(ctx context.Context, s *db.String) 27 27 EditString(ctx context.Context, s *db.String) ··· 46 46 func (m *BaseNotifier) NewPull(ctx context.Context, pull *models.Pull) {} 47 47 func (m *BaseNotifier) NewPullComment(ctx context.Context, models *models.PullComment) {} 48 48 49 - func (m *BaseNotifier) UpdateProfile(ctx context.Context, profile *db.Profile) {} 49 + func (m *BaseNotifier) UpdateProfile(ctx context.Context, profile *models.Profile) {} 50 50 51 51 func (m *BaseNotifier) NewString(ctx context.Context, s *db.String) {} 52 52 func (m *BaseNotifier) EditString(ctx context.Context, s *db.String) {}
+5 -5
appview/pages/pages.go
··· 413 413 UserHandle string 414 414 FollowStatus models.FollowStatus 415 415 Punchcard *db.Punchcard 416 - Profile *db.Profile 416 + Profile *models.Profile 417 417 Stats ProfileStats 418 418 Active string 419 419 } ··· 441 441 LoggedInUser *oauth.User 442 442 Repos []models.Repo 443 443 CollaboratingRepos []models.Repo 444 - ProfileTimeline *db.ProfileTimeline 444 + ProfileTimeline *models.ProfileTimeline 445 445 Card *ProfileCard 446 446 Active string 447 447 } ··· 492 492 FollowStatus models.FollowStatus 493 493 FollowersCount int64 494 494 FollowingCount int64 495 - Profile *db.Profile 495 + Profile *models.Profile 496 496 } 497 497 498 498 type ProfileFollowersParams struct { ··· 530 530 531 531 type EditBioParams struct { 532 532 LoggedInUser *oauth.User 533 - Profile *db.Profile 533 + Profile *models.Profile 534 534 } 535 535 536 536 func (p *Pages) EditBioFragment(w io.Writer, params EditBioParams) error { ··· 539 539 540 540 type EditPinsParams struct { 541 541 LoggedInUser *oauth.User 542 - Profile *db.Profile 542 + Profile *models.Profile 543 543 AllRepos []PinnedRepo 544 544 } 545 545
+1 -1
appview/posthog/notifier.go
··· 121 121 } 122 122 } 123 123 124 - func (n *posthogNotifier) UpdateProfile(ctx context.Context, profile *db.Profile) { 124 + func (n *posthogNotifier) UpdateProfile(ctx context.Context, profile *models.Profile) { 125 125 err := n.client.Enqueue(posthog.Capture{ 126 126 DistinctId: profile.Did, 127 127 Event: "edit_profile",
+7 -7
appview/state/profile.go
··· 337 337 followStatus = models.IsSelf 338 338 } 339 339 340 - var profile *db.Profile 340 + var profile *models.Profile 341 341 if p, exists := profiles[did]; exists { 342 342 profile = p 343 343 } else { 344 - profile = &db.Profile{} 344 + profile = &models.Profile{} 345 345 profile.Did = did 346 346 } 347 347 followCards[i] = pages.FollowCard{ ··· 479 479 return nil 480 480 } 481 481 482 - func (s *State) addRepoItems(ctx context.Context, feed *feeds.Feed, repos []db.RepoEvent, author *feeds.Author) error { 482 + func (s *State) addRepoItems(ctx context.Context, feed *feeds.Feed, repos []models.RepoEvent, author *feeds.Author) error { 483 483 for _, repo := range repos { 484 484 item, err := s.createRepoItem(ctx, repo, author) 485 485 if err != nil { ··· 508 508 } 509 509 } 510 510 511 - func (s *State) createRepoItem(ctx context.Context, repo db.RepoEvent, author *feeds.Author) (*feeds.Item, error) { 511 + func (s *State) createRepoItem(ctx context.Context, repo models.RepoEvent, author *feeds.Author) (*feeds.Item, error) { 512 512 var title string 513 513 if repo.Source != nil { 514 514 sourceOwner, err := s.idResolver.ResolveIdent(ctx, repo.Source.Did) ··· 559 559 stat1 := r.FormValue("stat1") 560 560 561 561 if stat0 != "" { 562 - profile.Stats[0].Kind = db.VanityStatKind(stat0) 562 + profile.Stats[0].Kind = models.VanityStatKind(stat0) 563 563 } 564 564 565 565 if stat1 != "" { 566 - profile.Stats[1].Kind = db.VanityStatKind(stat1) 566 + profile.Stats[1].Kind = models.VanityStatKind(stat1) 567 567 } 568 568 569 569 if err := db.ValidateProfile(s.db, profile); err != nil { ··· 614 614 s.updateProfile(profile, w, r) 615 615 } 616 616 617 - func (s *State) updateProfile(profile *db.Profile, w http.ResponseWriter, r *http.Request) { 617 + func (s *State) updateProfile(profile *models.Profile, w http.ResponseWriter, r *http.Request) { 618 618 user := s.oauth.GetUser(r) 619 619 tx, err := s.db.BeginTx(r.Context(), nil) 620 620 if err != nil {