Monorepo for Tangled tangled.org

appview/models: move db.Repo* into models

- move db.{Repo,RepoStats,IssueCount,PullCount} into models
- moe auxilliary funcs like FromRecord into models

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

oppi.li dc802605 6390396d

verified
+1 -1
appview/db/collaborators.go
··· 34 return err 35 } 36 37 - func CollaboratingIn(e Execer, collaborator string) ([]Repo, error) { 38 rows, err := e.Query(`select repo_at from collaborators where subject_did = ?`, collaborator) 39 if err != nil { 40 return nil, err
··· 34 return err 35 } 36 37 + func CollaboratingIn(e Execer, collaborator string) ([]models.Repo, error) { 38 rows, err := e.Query(`select repo_at from collaborators where subject_did = ?`, collaborator) 39 if err != nil { 40 return nil, err
+5 -10
appview/db/issues.go
··· 32 // like comment counts, parent repo etc. 33 Comments []IssueComment 34 Labels models.LabelState 35 - Repo *Repo 36 } 37 38 func (i *Issue) AtUri() syntax.ATURI { ··· 376 return nil, fmt.Errorf("failed to build repo mappings: %w", err) 377 } 378 379 - repoMap := make(map[string]*Repo) 380 for i := range repos { 381 repoMap[string(repos[i].RepoAt())] = &repos[i] 382 } ··· 658 return err 659 } 660 661 - type IssueCount struct { 662 - Open int 663 - Closed int 664 - } 665 - 666 - func GetIssueCount(e Execer, repoAt syntax.ATURI) (IssueCount, error) { 667 row := e.QueryRow(` 668 select 669 count(case when open = 1 then 1 end) as open_count, ··· 673 repoAt, 674 ) 675 676 - var count IssueCount 677 if err := row.Scan(&count.Open, &count.Closed); err != nil { 678 - return IssueCount{0, 0}, err 679 } 680 681 return count, nil
··· 32 // like comment counts, parent repo etc. 33 Comments []IssueComment 34 Labels models.LabelState 35 + Repo *models.Repo 36 } 37 38 func (i *Issue) AtUri() syntax.ATURI { ··· 376 return nil, fmt.Errorf("failed to build repo mappings: %w", err) 377 } 378 379 + repoMap := make(map[string]*models.Repo) 380 for i := range repos { 381 repoMap[string(repos[i].RepoAt())] = &repos[i] 382 } ··· 658 return err 659 } 660 661 + func GetIssueCount(e Execer, repoAt syntax.ATURI) (models.IssueCount, error) { 662 row := e.QueryRow(` 663 select 664 count(case when open = 1 then 1 end) as open_count, ··· 668 repoAt, 669 ) 670 671 + var count models.IssueCount 672 if err := row.Scan(&count.Open, &count.Closed); err != nil { 673 + return models.IssueCount{0, 0}, err 674 } 675 676 return count, nil
+4 -3
appview/db/profile.go
··· 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 "tangled.org/core/api/tangled" 14 ) 15 16 type RepoEvent struct { 17 - Repo *Repo 18 - Source *Repo 19 } 20 21 type ProfileTimeline struct { ··· 162 163 for _, repo := range repos { 164 // TODO: get this in the original query; requires COALESCE because nullable 165 - var sourceRepo *Repo 166 if repo.Source != "" { 167 sourceRepo, err = GetRepoByAtUri(e, repo.Source) 168 if err != nil {
··· 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 "tangled.org/core/api/tangled" 14 + "tangled.org/core/appview/models" 15 ) 16 17 type RepoEvent struct { 18 + Repo *models.Repo 19 + Source *models.Repo 20 } 21 22 type ProfileTimeline struct { ··· 163 164 for _, repo := range repos { 165 // TODO: get this in the original query; requires COALESCE because nullable 166 + var sourceRepo *models.Repo 167 if repo.Source != "" { 168 sourceRepo, err = GetRepoByAtUri(e, repo.Source) 169 if err != nil {
+8 -14
appview/db/pulls.go
··· 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 "tangled.org/core/api/tangled" 14 "tangled.org/core/patchutil" 15 "tangled.org/core/types" 16 ) ··· 79 PullSource *PullSource 80 81 // optionally, populate this when querying for reverse mappings 82 - Repo *Repo 83 } 84 85 func (p Pull) AsRecord() tangled.RepoPull { ··· 109 RepoAt *syntax.ATURI 110 111 // optionally populate this for reverse mappings 112 - Repo *Repo 113 } 114 115 func (p PullSource) AsRecord() tangled.RepoPull_Source { ··· 723 return nil, err 724 } 725 726 - var pullSourceRepo *Repo 727 if pull.PullSource != nil { 728 if pull.PullSource.RepoAt != nil { 729 pullSourceRepo, err = GetRepoByAtUri(e, pull.PullSource.RepoAt.String()) ··· 776 777 for rows.Next() { 778 var pull Pull 779 - var repo Repo 780 var pullCreatedAt, repoCreatedAt string 781 err := rows.Scan( 782 &pull.OwnerDid, ··· 931 return err 932 } 933 934 - type PullCount struct { 935 - Open int 936 - Merged int 937 - Closed int 938 - Deleted int 939 - } 940 - 941 - func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) { 942 row := e.QueryRow(` 943 select 944 count(case when state = ? then 1 end) as open_count, ··· 954 repoAt, 955 ) 956 957 - var count PullCount 958 if err := row.Scan(&count.Open, &count.Merged, &count.Closed, &count.Deleted); err != nil { 959 - return PullCount{0, 0, 0, 0}, err 960 } 961 962 return count, nil
··· 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 "tangled.org/core/api/tangled" 14 + "tangled.org/core/appview/models" 15 "tangled.org/core/patchutil" 16 "tangled.org/core/types" 17 ) ··· 80 PullSource *PullSource 81 82 // optionally, populate this when querying for reverse mappings 83 + Repo *models.Repo 84 } 85 86 func (p Pull) AsRecord() tangled.RepoPull { ··· 110 RepoAt *syntax.ATURI 111 112 // optionally populate this for reverse mappings 113 + Repo *models.Repo 114 } 115 116 func (p PullSource) AsRecord() tangled.RepoPull_Source { ··· 724 return nil, err 725 } 726 727 + var pullSourceRepo *models.Repo 728 if pull.PullSource != nil { 729 if pull.PullSource.RepoAt != nil { 730 pullSourceRepo, err = GetRepoByAtUri(e, pull.PullSource.RepoAt.String()) ··· 777 778 for rows.Next() { 779 var pull Pull 780 + var repo models.Repo 781 var pullCreatedAt, repoCreatedAt string 782 err := rows.Scan( 783 &pull.OwnerDid, ··· 932 return err 933 } 934 935 + func GetPullCount(e Execer, repoAt syntax.ATURI) (models.PullCount, error) { 936 row := e.QueryRow(` 937 select 938 count(case when state = ? then 1 end) as open_count, ··· 948 repoAt, 949 ) 950 951 + var count models.PullCount 952 if err := row.Scan(&count.Open, &count.Merged, &count.Closed, &count.Deleted); err != nil { 953 + return models.PullCount{Open: 0, Merged: 0, Closed: 0, Deleted: 0}, err 954 } 955 956 return count, nil
+20 -86
appview/db/repos.go
··· 10 "time" 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 - securejoin "github.com/cyphar/filepath-securejoin" 14 - "tangled.org/core/api/tangled" 15 ) 16 17 - type Repo struct { 18 - Did string 19 - Name string 20 - Knot string 21 - Rkey string 22 - Created time.Time 23 - Description string 24 - Spindle string 25 - Labels []string 26 - 27 - // optionally, populate this when querying for reverse mappings 28 - RepoStats *RepoStats 29 - 30 - // optional 31 - Source string 32 - } 33 - 34 - func (r *Repo) AsRecord() tangled.Repo { 35 - var source, spindle, description *string 36 - 37 - if r.Source != "" { 38 - source = &r.Source 39 - } 40 - 41 - if r.Spindle != "" { 42 - spindle = &r.Spindle 43 - } 44 - 45 - if r.Description != "" { 46 - description = &r.Description 47 - } 48 - 49 - return tangled.Repo{ 50 - Knot: r.Knot, 51 - Name: r.Name, 52 - Description: description, 53 - CreatedAt: r.Created.Format(time.RFC3339), 54 - Source: source, 55 - Spindle: spindle, 56 - Labels: r.Labels, 57 - } 58 - } 59 - 60 - func (r Repo) RepoAt() syntax.ATURI { 61 - return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", r.Did, tangled.RepoNSID, r.Rkey)) 62 - } 63 - 64 - func (r Repo) DidSlashRepo() string { 65 - p, _ := securejoin.SecureJoin(r.Did, r.Name) 66 - return p 67 - } 68 - 69 - func GetRepos(e Execer, limit int, filters ...filter) ([]Repo, error) { 70 - repoMap := make(map[syntax.ATURI]*Repo) 71 72 var conditions []string 73 var args []any ··· 111 } 112 113 for rows.Next() { 114 - var repo Repo 115 var createdAt string 116 var description, source, spindle sql.NullString 117 ··· 142 repo.Spindle = spindle.String 143 } 144 145 - repo.RepoStats = &RepoStats{} 146 repoMap[repo.RepoAt()] = &repo 147 } 148 ··· 320 return nil, fmt.Errorf("failed to execute pulls-count query: %w ", err) 321 } 322 323 - var repos []Repo 324 for _, r := range repoMap { 325 repos = append(repos, *r) 326 } 327 328 - slices.SortFunc(repos, func(a, b Repo) int { 329 if a.Created.After(b.Created) { 330 return -1 331 } ··· 336 } 337 338 // helper to get exactly one repo 339 - func GetRepo(e Execer, filters ...filter) (*Repo, error) { 340 repos, err := GetRepos(e, 0, filters...) 341 if err != nil { 342 return nil, err ··· 377 return count, nil 378 } 379 380 - func GetRepoByAtUri(e Execer, atUri string) (*Repo, error) { 381 - var repo Repo 382 var nullableDescription sql.NullString 383 384 row := e.QueryRow(`select did, name, knot, created, rkey, description from repos where at_uri = ?`, atUri) ··· 399 return &repo, nil 400 } 401 402 - func AddRepo(e Execer, repo *Repo) error { 403 _, err := e.Exec( 404 `insert into repos 405 (did, name, knot, rkey, at_uri, description, source) ··· 423 return nullableSource.String, nil 424 } 425 426 - func GetForksByDid(e Execer, did string) ([]Repo, error) { 427 - var repos []Repo 428 429 rows, err := e.Query( 430 `select distinct r.did, r.name, r.knot, r.rkey, r.description, r.created, r.source ··· 442 defer rows.Close() 443 444 for rows.Next() { 445 - var repo Repo 446 var createdAt string 447 var nullableDescription sql.NullString 448 var nullableSource sql.NullString ··· 477 return repos, nil 478 } 479 480 - func GetForkByDid(e Execer, did string, name string) (*Repo, error) { 481 - var repo Repo 482 var createdAt string 483 var nullableDescription sql.NullString 484 var nullableSource sql.NullString ··· 525 return err 526 } 527 528 - type RepoStats struct { 529 - Language string 530 - StarCount int 531 - IssueCount IssueCount 532 - PullCount PullCount 533 - } 534 - 535 - type RepoLabel struct { 536 - Id int64 537 - RepoAt syntax.ATURI 538 - LabelAt syntax.ATURI 539 - } 540 - 541 - func SubscribeLabel(e Execer, rl *RepoLabel) error { 542 query := `insert or ignore into repo_labels (repo_at, label_at) values (?, ?)` 543 544 _, err := e.Exec(query, rl.RepoAt.String(), rl.LabelAt.String()) ··· 563 return err 564 } 565 566 - func GetRepoLabels(e Execer, filters ...filter) ([]RepoLabel, error) { 567 var conditions []string 568 var args []any 569 for _, filter := range filters { ··· 584 } 585 defer rows.Close() 586 587 - var labels []RepoLabel 588 for rows.Next() { 589 - var label RepoLabel 590 591 err := rows.Scan(&label.Id, &label.RepoAt, &label.LabelAt) 592 if err != nil {
··· 10 "time" 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 + "tangled.org/core/appview/models" 14 ) 15 16 + func GetRepos(e Execer, limit int, filters ...filter) ([]models.Repo, error) { 17 + repoMap := make(map[syntax.ATURI]*models.Repo) 18 19 var conditions []string 20 var args []any ··· 58 } 59 60 for rows.Next() { 61 + var repo models.Repo 62 var createdAt string 63 var description, source, spindle sql.NullString 64 ··· 89 repo.Spindle = spindle.String 90 } 91 92 + repo.RepoStats = &models.RepoStats{} 93 repoMap[repo.RepoAt()] = &repo 94 } 95 ··· 267 return nil, fmt.Errorf("failed to execute pulls-count query: %w ", err) 268 } 269 270 + var repos []models.Repo 271 for _, r := range repoMap { 272 repos = append(repos, *r) 273 } 274 275 + slices.SortFunc(repos, func(a, b models.Repo) int { 276 if a.Created.After(b.Created) { 277 return -1 278 } ··· 283 } 284 285 // helper to get exactly one repo 286 + func GetRepo(e Execer, filters ...filter) (*models.Repo, error) { 287 repos, err := GetRepos(e, 0, filters...) 288 if err != nil { 289 return nil, err ··· 324 return count, nil 325 } 326 327 + func GetRepoByAtUri(e Execer, atUri string) (*models.Repo, error) { 328 + var repo models.Repo 329 var nullableDescription sql.NullString 330 331 row := e.QueryRow(`select did, name, knot, created, rkey, description from repos where at_uri = ?`, atUri) ··· 346 return &repo, nil 347 } 348 349 + func AddRepo(e Execer, repo *models.Repo) error { 350 _, err := e.Exec( 351 `insert into repos 352 (did, name, knot, rkey, at_uri, description, source) ··· 370 return nullableSource.String, nil 371 } 372 373 + func GetForksByDid(e Execer, did string) ([]models.Repo, error) { 374 + var repos []models.Repo 375 376 rows, err := e.Query( 377 `select distinct r.did, r.name, r.knot, r.rkey, r.description, r.created, r.source ··· 389 defer rows.Close() 390 391 for rows.Next() { 392 + var repo models.Repo 393 var createdAt string 394 var nullableDescription sql.NullString 395 var nullableSource sql.NullString ··· 424 return repos, nil 425 } 426 427 + func GetForkByDid(e Execer, did string, name string) (*models.Repo, error) { 428 + var repo models.Repo 429 var createdAt string 430 var nullableDescription sql.NullString 431 var nullableSource sql.NullString ··· 472 return err 473 } 474 475 + func SubscribeLabel(e Execer, rl *models.RepoLabel) error { 476 query := `insert or ignore into repo_labels (repo_at, label_at) values (?, ?)` 477 478 _, err := e.Exec(query, rl.RepoAt.String(), rl.LabelAt.String()) ··· 497 return err 498 } 499 500 + func GetRepoLabels(e Execer, filters ...filter) ([]models.RepoLabel, error) { 501 var conditions []string 502 var args []any 503 for _, filter := range filters { ··· 518 } 519 defer rows.Close() 520 521 + var labels []models.RepoLabel 522 for rows.Next() { 523 + var label models.RepoLabel 524 525 err := rows.Scan(&label.Id, &label.RepoAt, &label.LabelAt) 526 if err != nil {
+7 -6
appview/db/star.go
··· 9 "time" 10 11 "github.com/bluesky-social/indigo/atproto/syntax" 12 ) 13 14 type Star struct { ··· 18 Rkey string 19 20 // optionally, populate this when querying for reverse mappings 21 - Repo *Repo 22 } 23 24 func (star *Star) ResolveRepo(e Execer) error { ··· 284 285 for rows.Next() { 286 var star Star 287 - var repo Repo 288 var starCreatedAt, repoCreatedAt string 289 290 if err := rows.Scan( ··· 322 } 323 324 // GetTopStarredReposLastWeek returns the top 8 most starred repositories from the last week 325 - func GetTopStarredReposLastWeek(e Execer) ([]Repo, error) { 326 // first, get the top repo URIs by star count from the last week 327 query := ` 328 with recent_starred_repos as ( ··· 366 } 367 368 if len(repoUris) == 0 { 369 - return []Repo{}, nil 370 } 371 372 // get full repo data ··· 376 } 377 378 // sort repos by the original trending order 379 - repoMap := make(map[string]Repo) 380 for _, repo := range repos { 381 repoMap[repo.RepoAt().String()] = repo 382 } 383 384 - orderedRepos := make([]Repo, 0, len(repoUris)) 385 for _, uri := range repoUris { 386 if repo, exists := repoMap[uri]; exists { 387 orderedRepos = append(orderedRepos, repo)
··· 9 "time" 10 11 "github.com/bluesky-social/indigo/atproto/syntax" 12 + "tangled.org/core/appview/models" 13 ) 14 15 type Star struct { ··· 19 Rkey string 20 21 // optionally, populate this when querying for reverse mappings 22 + Repo *models.Repo 23 } 24 25 func (star *Star) ResolveRepo(e Execer) error { ··· 285 286 for rows.Next() { 287 var star Star 288 + var repo models.Repo 289 var starCreatedAt, repoCreatedAt string 290 291 if err := rows.Scan( ··· 323 } 324 325 // GetTopStarredReposLastWeek returns the top 8 most starred repositories from the last week 326 + func GetTopStarredReposLastWeek(e Execer) ([]models.Repo, error) { 327 // first, get the top repo URIs by star count from the last week 328 query := ` 329 with recent_starred_repos as ( ··· 367 } 368 369 if len(repoUris) == 0 { 370 + return []models.Repo{}, nil 371 } 372 373 // get full repo data ··· 377 } 378 379 // sort repos by the original trending order 380 + repoMap := make(map[string]models.Repo) 381 for _, repo := range repos { 382 repoMap[repo.RepoAt().String()] = repo 383 } 384 385 + orderedRepos := make([]models.Repo, 0, len(repoUris)) 386 for _, uri := range repoUris { 387 if repo, exists := repoMap[uri]; exists { 388 orderedRepos = append(orderedRepos, repo)
+8 -8
appview/db/timeline.go
··· 9 ) 10 11 type TimelineEvent struct { 12 - *Repo 13 *models.Follow 14 *Star 15 16 EventAt time.Time 17 18 // optional: populate only if Repo is a fork 19 - Source *Repo 20 21 // optional: populate only if event is Follow 22 *Profile ··· 64 return events, nil 65 } 66 67 - func fetchStarStatuses(e Execer, loggedInUserDid string, repos []Repo) (map[string]bool, error) { 68 if loggedInUserDid == "" { 69 return nil, nil 70 } ··· 77 return GetStarStatuses(e, loggedInUserDid, repoAts) 78 } 79 80 - func getRepoStarInfo(repo *Repo, starStatuses map[string]bool) (bool, int64) { 81 var isStarred bool 82 if starStatuses != nil { 83 isStarred = starStatuses[repo.RepoAt().String()] ··· 105 } 106 } 107 108 - var origRepos []Repo 109 if args != nil { 110 origRepos, err = GetRepos(e, 0, FilterIn("at_uri", args)) 111 } ··· 113 return nil, err 114 } 115 116 - uriToRepo := make(map[string]Repo) 117 for _, r := range origRepos { 118 uriToRepo[r.RepoAt().String()] = r 119 } ··· 125 126 var events []TimelineEvent 127 for _, r := range repos { 128 - var source *Repo 129 if r.Source != "" { 130 if origRepo, ok := uriToRepo[r.Source]; ok { 131 source = &origRepo ··· 162 } 163 stars = stars[:n] 164 165 - var repos []Repo 166 for _, s := range stars { 167 repos = append(repos, *s.Repo) 168 }
··· 9 ) 10 11 type TimelineEvent struct { 12 + *models.Repo 13 *models.Follow 14 *Star 15 16 EventAt time.Time 17 18 // optional: populate only if Repo is a fork 19 + Source *models.Repo 20 21 // optional: populate only if event is Follow 22 *Profile ··· 64 return events, nil 65 } 66 67 + func fetchStarStatuses(e Execer, loggedInUserDid string, repos []models.Repo) (map[string]bool, error) { 68 if loggedInUserDid == "" { 69 return nil, nil 70 } ··· 77 return GetStarStatuses(e, loggedInUserDid, repoAts) 78 } 79 80 + func getRepoStarInfo(repo *models.Repo, starStatuses map[string]bool) (bool, int64) { 81 var isStarred bool 82 if starStatuses != nil { 83 isStarred = starStatuses[repo.RepoAt().String()] ··· 105 } 106 } 107 108 + var origRepos []models.Repo 109 if args != nil { 110 origRepos, err = GetRepos(e, 0, FilterIn("at_uri", args)) 111 } ··· 113 return nil, err 114 } 115 116 + uriToRepo := make(map[string]models.Repo) 117 for _, r := range origRepos { 118 uriToRepo[r.RepoAt().String()] = r 119 } ··· 125 126 var events []TimelineEvent 127 for _, r := range repos { 128 + var source *models.Repo 129 if r.Source != "" { 130 if origRepo, ok := uriToRepo[r.Source]; ok { 131 source = &origRepo ··· 162 } 163 stars = stars[:n] 164 165 + var repos []models.Repo 166 for _, s := range stars { 167 repos = append(repos, *s.Repo) 168 }
+2 -1
appview/knots/knots.go
··· 13 "tangled.org/core/appview/config" 14 "tangled.org/core/appview/db" 15 "tangled.org/core/appview/middleware" 16 "tangled.org/core/appview/oauth" 17 "tangled.org/core/appview/pages" 18 "tangled.org/core/appview/serververify" ··· 119 } 120 121 // organize repos by did 122 - repoMap := make(map[string][]db.Repo) 123 for _, r := range repos { 124 repoMap[r.Did] = append(repoMap[r.Did], r) 125 }
··· 13 "tangled.org/core/appview/config" 14 "tangled.org/core/appview/db" 15 "tangled.org/core/appview/middleware" 16 + "tangled.org/core/appview/models" 17 "tangled.org/core/appview/oauth" 18 "tangled.org/core/appview/pages" 19 "tangled.org/core/appview/serververify" ··· 120 } 121 122 // organize repos by did 123 + repoMap := make(map[string][]models.Repo) 124 for _, r := range repos { 125 repoMap[r.Did] = append(repoMap[r.Did], r) 126 }
+87
appview/models/repo.go
···
··· 1 + package models 2 + 3 + import ( 4 + "fmt" 5 + "time" 6 + 7 + "github.com/bluesky-social/indigo/atproto/syntax" 8 + securejoin "github.com/cyphar/filepath-securejoin" 9 + "tangled.org/core/api/tangled" 10 + ) 11 + 12 + type Repo struct { 13 + Did string 14 + Name string 15 + Knot string 16 + Rkey string 17 + Created time.Time 18 + Description string 19 + Spindle string 20 + Labels []string 21 + 22 + // optionally, populate this when querying for reverse mappings 23 + RepoStats *RepoStats 24 + 25 + // optional 26 + Source string 27 + } 28 + 29 + func (r *Repo) AsRecord() tangled.Repo { 30 + var source, spindle, description *string 31 + 32 + if r.Source != "" { 33 + source = &r.Source 34 + } 35 + 36 + if r.Spindle != "" { 37 + spindle = &r.Spindle 38 + } 39 + 40 + if r.Description != "" { 41 + description = &r.Description 42 + } 43 + 44 + return tangled.Repo{ 45 + Knot: r.Knot, 46 + Name: r.Name, 47 + Description: description, 48 + CreatedAt: r.Created.Format(time.RFC3339), 49 + Source: source, 50 + Spindle: spindle, 51 + Labels: r.Labels, 52 + } 53 + } 54 + 55 + func (r Repo) RepoAt() syntax.ATURI { 56 + return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", r.Did, tangled.RepoNSID, r.Rkey)) 57 + } 58 + 59 + func (r Repo) DidSlashRepo() string { 60 + p, _ := securejoin.SecureJoin(r.Did, r.Name) 61 + return p 62 + } 63 + 64 + type RepoStats struct { 65 + Language string 66 + StarCount int 67 + IssueCount IssueCount 68 + PullCount PullCount 69 + } 70 + 71 + type IssueCount struct { 72 + Open int 73 + Closed int 74 + } 75 + 76 + type PullCount struct { 77 + Open int 78 + Merged int 79 + Closed int 80 + Deleted int 81 + } 82 + 83 + type RepoLabel struct { 84 + Id int64 85 + RepoAt syntax.ATURI 86 + LabelAt syntax.ATURI 87 + }
+1 -1
appview/notify/merged_notifier.go
··· 17 18 var _ Notifier = &mergedNotifier{} 19 20 - func (m *mergedNotifier) NewRepo(ctx context.Context, repo *db.Repo) { 21 for _, notifier := range m.notifiers { 22 notifier.NewRepo(ctx, repo) 23 }
··· 17 18 var _ Notifier = &mergedNotifier{} 19 20 + func (m *mergedNotifier) NewRepo(ctx context.Context, repo *models.Repo) { 21 for _, notifier := range m.notifiers { 22 notifier.NewRepo(ctx, repo) 23 }
+2 -2
appview/notify/notifier.go
··· 8 ) 9 10 type Notifier interface { 11 - NewRepo(ctx context.Context, repo *db.Repo) 12 13 NewStar(ctx context.Context, star *db.Star) 14 DeleteStar(ctx context.Context, star *db.Star) ··· 33 34 var _ Notifier = &BaseNotifier{} 35 36 - func (m *BaseNotifier) NewRepo(ctx context.Context, repo *db.Repo) {} 37 38 func (m *BaseNotifier) NewStar(ctx context.Context, star *db.Star) {} 39 func (m *BaseNotifier) DeleteStar(ctx context.Context, star *db.Star) {}
··· 8 ) 9 10 type Notifier interface { 11 + NewRepo(ctx context.Context, repo *models.Repo) 12 13 NewStar(ctx context.Context, star *db.Star) 14 DeleteStar(ctx context.Context, star *db.Star) ··· 33 34 var _ Notifier = &BaseNotifier{} 35 36 + func (m *BaseNotifier) NewRepo(ctx context.Context, repo *models.Repo) {} 37 38 func (m *BaseNotifier) NewStar(ctx context.Context, star *db.Star) {} 39 func (m *BaseNotifier) DeleteStar(ctx context.Context, star *db.Star) {}
+12 -12
appview/pages/pages.go
··· 284 type TimelineParams struct { 285 LoggedInUser *oauth.User 286 Timeline []db.TimelineEvent 287 - Repos []db.Repo 288 } 289 290 func (p *Pages) Timeline(w io.Writer, params TimelineParams) error { ··· 345 LoggedInUser *oauth.User 346 Registration *db.Registration 347 Members []string 348 - Repos map[string][]db.Repo 349 IsOwner bool 350 } 351 ··· 382 LoggedInUser *oauth.User 383 Spindle db.Spindle 384 Members []string 385 - Repos map[string][]db.Repo 386 } 387 388 func (p *Pages) SpindleDashboard(w io.Writer, params SpindleDashboardParams) error { ··· 439 440 type ProfileOverviewParams struct { 441 LoggedInUser *oauth.User 442 - Repos []db.Repo 443 - CollaboratingRepos []db.Repo 444 ProfileTimeline *db.ProfileTimeline 445 Card *ProfileCard 446 Active string ··· 453 454 type ProfileReposParams struct { 455 LoggedInUser *oauth.User 456 - Repos []db.Repo 457 Card *ProfileCard 458 Active string 459 } ··· 465 466 type ProfileStarredParams struct { 467 LoggedInUser *oauth.User 468 - Repos []db.Repo 469 Card *ProfileCard 470 Active string 471 } ··· 545 546 type PinnedRepo struct { 547 IsPinned bool 548 - db.Repo 549 } 550 551 func (p *Pages) EditPinsFragment(w io.Writer, params EditPinsParams) error { ··· 555 type RepoStarFragmentParams struct { 556 IsStarred bool 557 RepoAt syntax.ATURI 558 - Stats db.RepoStats 559 } 560 561 func (p *Pages) RepoStarFragment(w io.Writer, params RepoStarFragmentParams) error { ··· 1122 1123 type PullCompareForkParams struct { 1124 RepoInfo repoinfo.RepoInfo 1125 - Forks []db.Repo 1126 Selected string 1127 } 1128 ··· 1179 type RepoCompareParams struct { 1180 LoggedInUser *oauth.User 1181 RepoInfo repoinfo.RepoInfo 1182 - Forks []db.Repo 1183 Branches []types.Branch 1184 Tags []*types.TagReference 1185 Base string ··· 1198 type RepoCompareNewParams struct { 1199 LoggedInUser *oauth.User 1200 RepoInfo repoinfo.RepoInfo 1201 - Forks []db.Repo 1202 Branches []types.Branch 1203 Tags []*types.TagReference 1204 Base string
··· 284 type TimelineParams struct { 285 LoggedInUser *oauth.User 286 Timeline []db.TimelineEvent 287 + Repos []models.Repo 288 } 289 290 func (p *Pages) Timeline(w io.Writer, params TimelineParams) error { ··· 345 LoggedInUser *oauth.User 346 Registration *db.Registration 347 Members []string 348 + Repos map[string][]models.Repo 349 IsOwner bool 350 } 351 ··· 382 LoggedInUser *oauth.User 383 Spindle db.Spindle 384 Members []string 385 + Repos map[string][]models.Repo 386 } 387 388 func (p *Pages) SpindleDashboard(w io.Writer, params SpindleDashboardParams) error { ··· 439 440 type ProfileOverviewParams struct { 441 LoggedInUser *oauth.User 442 + Repos []models.Repo 443 + CollaboratingRepos []models.Repo 444 ProfileTimeline *db.ProfileTimeline 445 Card *ProfileCard 446 Active string ··· 453 454 type ProfileReposParams struct { 455 LoggedInUser *oauth.User 456 + Repos []models.Repo 457 Card *ProfileCard 458 Active string 459 } ··· 465 466 type ProfileStarredParams struct { 467 LoggedInUser *oauth.User 468 + Repos []models.Repo 469 Card *ProfileCard 470 Active string 471 } ··· 545 546 type PinnedRepo struct { 547 IsPinned bool 548 + models.Repo 549 } 550 551 func (p *Pages) EditPinsFragment(w io.Writer, params EditPinsParams) error { ··· 555 type RepoStarFragmentParams struct { 556 IsStarred bool 557 RepoAt syntax.ATURI 558 + Stats models.RepoStats 559 } 560 561 func (p *Pages) RepoStarFragment(w io.Writer, params RepoStarFragmentParams) error { ··· 1122 1123 type PullCompareForkParams struct { 1124 RepoInfo repoinfo.RepoInfo 1125 + Forks []models.Repo 1126 Selected string 1127 } 1128 ··· 1179 type RepoCompareParams struct { 1180 LoggedInUser *oauth.User 1181 RepoInfo repoinfo.RepoInfo 1182 + Forks []models.Repo 1183 Branches []types.Branch 1184 Tags []*types.TagReference 1185 Base string ··· 1198 type RepoCompareNewParams struct { 1199 LoggedInUser *oauth.User 1200 RepoInfo repoinfo.RepoInfo 1201 + Forks []models.Repo 1202 Branches []types.Branch 1203 Tags []*types.TagReference 1204 Base string
+3 -3
appview/pages/repoinfo/repoinfo.go
··· 7 "strings" 8 9 "github.com/bluesky-social/indigo/atproto/syntax" 10 - "tangled.org/core/appview/db" 11 "tangled.org/core/appview/state/userutil" 12 ) 13 ··· 60 Spindle string 61 RepoAt syntax.ATURI 62 IsStarred bool 63 - Stats db.RepoStats 64 Roles RolesInRepo 65 - Source *db.Repo 66 SourceHandle string 67 Ref string 68 DisableFork bool
··· 7 "strings" 8 9 "github.com/bluesky-social/indigo/atproto/syntax" 10 + "tangled.org/core/appview/models" 11 "tangled.org/core/appview/state/userutil" 12 ) 13 ··· 60 Spindle string 61 RepoAt syntax.ATURI 62 IsStarred bool 63 + Stats models.RepoStats 64 Roles RolesInRepo 65 + Source *models.Repo 66 SourceHandle string 67 Ref string 68 DisableFork bool
+1 -1
appview/posthog/notifier.go
··· 24 25 var _ notify.Notifier = &posthogNotifier{} 26 27 - func (n *posthogNotifier) NewRepo(ctx context.Context, repo *db.Repo) { 28 err := n.client.Enqueue(posthog.Capture{ 29 DistinctId: repo.Did, 30 Event: "new_repo",
··· 24 25 var _ notify.Notifier = &posthogNotifier{} 26 27 + func (n *posthogNotifier) NewRepo(ctx context.Context, repo *models.Repo) { 28 err := n.client.Enqueue(posthog.Capture{ 29 DistinctId: repo.Did, 30 Event: "new_repo",
+2 -1
appview/pulls/pulls.go
··· 15 "tangled.org/core/api/tangled" 16 "tangled.org/core/appview/config" 17 "tangled.org/core/appview/db" 18 "tangled.org/core/appview/notify" 19 "tangled.org/core/appview/oauth" 20 "tangled.org/core/appview/pages" ··· 500 } 501 502 for _, p := range pulls { 503 - var pullSourceRepo *db.Repo 504 if p.PullSource != nil { 505 if p.PullSource.RepoAt != nil { 506 pullSourceRepo, err = db.GetRepoByAtUri(s.db, p.PullSource.RepoAt.String())
··· 15 "tangled.org/core/api/tangled" 16 "tangled.org/core/appview/config" 17 "tangled.org/core/appview/db" 18 + "tangled.org/core/appview/models" 19 "tangled.org/core/appview/notify" 20 "tangled.org/core/appview/oauth" 21 "tangled.org/core/appview/pages" ··· 501 } 502 503 for _, p := range pulls { 504 + var pullSourceRepo *models.Repo 505 if p.PullSource != nil { 506 if p.PullSource.RepoAt != nil { 507 pullSourceRepo, err = db.GetRepoByAtUri(s.db, p.PullSource.RepoAt.String())
+3 -3
appview/repo/repo.go
··· 1110 return 1111 } 1112 1113 - err = db.SubscribeLabel(tx, &db.RepoLabel{ 1114 RepoAt: f.RepoAt(), 1115 LabelAt: label.AtUri(), 1116 }) ··· 1286 }, 1287 }) 1288 1289 - err = db.SubscribeLabel(rp.db, &db.RepoLabel{ 1290 RepoAt: f.RepoAt(), 1291 LabelAt: syntax.ATURI(labelAt), 1292 }) ··· 2142 2143 // create an atproto record for this fork 2144 rkey := tid.TID() 2145 - repo := &db.Repo{ 2146 Did: user.Did, 2147 Name: forkName, 2148 Knot: targetKnot,
··· 1110 return 1111 } 1112 1113 + err = db.SubscribeLabel(tx, &models.RepoLabel{ 1114 RepoAt: f.RepoAt(), 1115 LabelAt: label.AtUri(), 1116 }) ··· 1286 }, 1287 }) 1288 1289 + err = db.SubscribeLabel(rp.db, &models.RepoLabel{ 1290 RepoAt: f.RepoAt(), 1291 LabelAt: syntax.ATURI(labelAt), 1292 }) ··· 2142 2143 // create an atproto record for this fork 2144 rkey := tid.TID() 2145 + repo := &models.Repo{ 2146 Did: user.Did, 2147 Name: forkName, 2148 Knot: targetKnot,
+5 -4
appview/reporesolver/resolver.go
··· 16 "github.com/go-chi/chi/v5" 17 "tangled.org/core/appview/config" 18 "tangled.org/core/appview/db" 19 "tangled.org/core/appview/oauth" 20 "tangled.org/core/appview/pages" 21 "tangled.org/core/appview/pages/repoinfo" ··· 24 ) 25 26 type ResolvedRepo struct { 27 - db.Repo 28 OwnerId identity.Identity 29 CurrentDir string 30 Ref string ··· 44 } 45 46 func (rr *RepoResolver) Resolve(r *http.Request) (*ResolvedRepo, error) { 47 - repo, ok := r.Context().Value("repo").(*db.Repo) 48 if !ok { 49 log.Println("malformed middleware: `repo` not exist in context") 50 return nil, fmt.Errorf("malformed middleware") ··· 162 log.Println("failed to get repo source for ", repoAt, err) 163 } 164 165 - var sourceRepo *db.Repo 166 if source != "" { 167 sourceRepo, err = db.GetRepoByAtUri(f.rr.execer, source) 168 if err != nil { ··· 191 Knot: knot, 192 Spindle: f.Spindle, 193 Roles: f.RolesInRepo(user), 194 - Stats: db.RepoStats{ 195 StarCount: starCount, 196 IssueCount: issueCount, 197 PullCount: pullCount,
··· 16 "github.com/go-chi/chi/v5" 17 "tangled.org/core/appview/config" 18 "tangled.org/core/appview/db" 19 + "tangled.org/core/appview/models" 20 "tangled.org/core/appview/oauth" 21 "tangled.org/core/appview/pages" 22 "tangled.org/core/appview/pages/repoinfo" ··· 25 ) 26 27 type ResolvedRepo struct { 28 + models.Repo 29 OwnerId identity.Identity 30 CurrentDir string 31 Ref string ··· 45 } 46 47 func (rr *RepoResolver) Resolve(r *http.Request) (*ResolvedRepo, error) { 48 + repo, ok := r.Context().Value("repo").(*models.Repo) 49 if !ok { 50 log.Println("malformed middleware: `repo` not exist in context") 51 return nil, fmt.Errorf("malformed middleware") ··· 163 log.Println("failed to get repo source for ", repoAt, err) 164 } 165 166 + var sourceRepo *models.Repo 167 if source != "" { 168 sourceRepo, err = db.GetRepoByAtUri(f.rr.execer, source) 169 if err != nil { ··· 192 Knot: knot, 193 Spindle: f.Spindle, 194 Roles: f.RolesInRepo(user), 195 + Stats: models.RepoStats{ 196 StarCount: starCount, 197 IssueCount: issueCount, 198 PullCount: pullCount,
+2 -1
appview/spindles/spindles.go
··· 13 "tangled.org/core/appview/config" 14 "tangled.org/core/appview/db" 15 "tangled.org/core/appview/middleware" 16 "tangled.org/core/appview/oauth" 17 "tangled.org/core/appview/pages" 18 "tangled.org/core/appview/serververify" ··· 115 } 116 117 // organize repos by did 118 - repoMap := make(map[string][]db.Repo) 119 for _, r := range repos { 120 repoMap[r.Did] = append(repoMap[r.Did], r) 121 }
··· 13 "tangled.org/core/appview/config" 14 "tangled.org/core/appview/db" 15 "tangled.org/core/appview/middleware" 16 + "tangled.org/core/appview/models" 17 "tangled.org/core/appview/oauth" 18 "tangled.org/core/appview/pages" 19 "tangled.org/core/appview/serververify" ··· 116 } 117 118 // organize repos by did 119 + repoMap := make(map[string][]models.Repo) 120 for _, r := range repos { 121 repoMap[r.Did] = append(repoMap[r.Did], r) 122 }
+4 -4
appview/state/git_http.go
··· 8 9 "github.com/bluesky-social/indigo/atproto/identity" 10 "github.com/go-chi/chi/v5" 11 - "tangled.org/core/appview/db" 12 ) 13 14 func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) { 15 user := r.Context().Value("resolvedId").(identity.Identity) 16 - repo := r.Context().Value("repo").(*db.Repo) 17 18 scheme := "https" 19 if s.config.Core.Dev { ··· 31 http.Error(w, "failed to resolve user", http.StatusInternalServerError) 32 return 33 } 34 - repo := r.Context().Value("repo").(*db.Repo) 35 36 scheme := "https" 37 if s.config.Core.Dev { ··· 48 http.Error(w, "failed to resolve user", http.StatusInternalServerError) 49 return 50 } 51 - repo := r.Context().Value("repo").(*db.Repo) 52 53 scheme := "https" 54 if s.config.Core.Dev {
··· 8 9 "github.com/bluesky-social/indigo/atproto/identity" 10 "github.com/go-chi/chi/v5" 11 + "tangled.org/core/appview/models" 12 ) 13 14 func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) { 15 user := r.Context().Value("resolvedId").(identity.Identity) 16 + repo := r.Context().Value("repo").(*models.Repo) 17 18 scheme := "https" 19 if s.config.Core.Dev { ··· 31 http.Error(w, "failed to resolve user", http.StatusInternalServerError) 32 return 33 } 34 + repo := r.Context().Value("repo").(*models.Repo) 35 36 scheme := "https" 37 if s.config.Core.Dev { ··· 48 http.Error(w, "failed to resolve user", http.StatusInternalServerError) 49 return 50 } 51 + repo := r.Context().Value("repo").(*models.Repo) 52 53 scheme := "https" 54 if s.config.Core.Dev {
+2 -2
appview/state/profile.go
··· 131 } 132 133 // filter out ones that are pinned 134 - pinnedRepos := []db.Repo{} 135 for i, r := range repos { 136 // if this is a pinned repo, add it 137 if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) { ··· 149 l.Error("failed to fetch collaborating repos", "err", err) 150 } 151 152 - pinnedCollaboratingRepos := []db.Repo{} 153 for _, r := range collaboratingRepos { 154 // if this is a pinned repo, add it 155 if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) {
··· 131 } 132 133 // filter out ones that are pinned 134 + pinnedRepos := []models.Repo{} 135 for i, r := range repos { 136 // if this is a pinned repo, add it 137 if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) { ··· 149 l.Error("failed to fetch collaborating repos", "err", err) 150 } 151 152 + pinnedCollaboratingRepos := []models.Repo{} 153 for _, r := range collaboratingRepos { 154 // if this is a pinned repo, add it 155 if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) {
+3 -2
appview/state/star.go
··· 10 lexutil "github.com/bluesky-social/indigo/lex/util" 11 "tangled.org/core/api/tangled" 12 "tangled.org/core/appview/db" 13 "tangled.org/core/appview/pages" 14 "tangled.org/core/tid" 15 ) ··· 77 s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{ 78 IsStarred: true, 79 RepoAt: subjectUri, 80 - Stats: db.RepoStats{ 81 StarCount: starCount, 82 }, 83 }) ··· 119 s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{ 120 IsStarred: false, 121 RepoAt: subjectUri, 122 - Stats: db.RepoStats{ 123 StarCount: starCount, 124 }, 125 })
··· 10 lexutil "github.com/bluesky-social/indigo/lex/util" 11 "tangled.org/core/api/tangled" 12 "tangled.org/core/appview/db" 13 + "tangled.org/core/appview/models" 14 "tangled.org/core/appview/pages" 15 "tangled.org/core/tid" 16 ) ··· 78 s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{ 79 IsStarred: true, 80 RepoAt: subjectUri, 81 + Stats: models.RepoStats{ 82 StarCount: starCount, 83 }, 84 }) ··· 120 s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{ 121 IsStarred: false, 122 RepoAt: subjectUri, 123 + Stats: models.RepoStats{ 124 StarCount: starCount, 125 }, 126 })
+2 -2
appview/state/state.go
··· 23 "tangled.org/core/appview/cache/session" 24 "tangled.org/core/appview/config" 25 "tangled.org/core/appview/db" 26 "tangled.org/core/appview/notify" 27 "tangled.org/core/appview/oauth" 28 "tangled.org/core/appview/pages" ··· 36 tlog "tangled.org/core/log" 37 "tangled.org/core/rbac" 38 "tangled.org/core/tid" 39 - // xrpcerr "tangled.org/core/xrpc/errors" 40 ) 41 42 type State struct { ··· 433 434 // create atproto record for this repo 435 rkey := tid.TID() 436 - repo := &db.Repo{ 437 Did: user.Did, 438 Name: repoName, 439 Knot: domain,
··· 23 "tangled.org/core/appview/cache/session" 24 "tangled.org/core/appview/config" 25 "tangled.org/core/appview/db" 26 + "tangled.org/core/appview/models" 27 "tangled.org/core/appview/notify" 28 "tangled.org/core/appview/oauth" 29 "tangled.org/core/appview/pages" ··· 37 tlog "tangled.org/core/log" 38 "tangled.org/core/rbac" 39 "tangled.org/core/tid" 40 ) 41 42 type State struct { ··· 433 434 // create atproto record for this repo 435 rkey := tid.TID() 436 + repo := &models.Repo{ 437 Did: user.Did, 438 Name: repoName, 439 Knot: domain,