···1010 "time"11111212 "github.com/bluesky-social/indigo/atproto/syntax"1313- "tangled.org/core/api/tangled"1413 "tangled.org/core/appview/models"1514)16151717-type RepoEvent struct {1818- Repo *models.Repo1919- Source *models.Repo2020-}2121-2222-type ProfileTimeline struct {2323- ByMonth []ByMonth2424-}2525-2626-func (p *ProfileTimeline) IsEmpty() bool {2727- if p == nil {2828- return true2929- }3030-3131- for _, m := range p.ByMonth {3232- if !m.IsEmpty() {3333- return false3434- }3535- }3636-3737- return true3838-}3939-4040-type ByMonth struct {4141- RepoEvents []RepoEvent4242- IssueEvents IssueEvents4343- PullEvents PullEvents4444-}4545-4646-func (b ByMonth) IsEmpty() bool {4747- return len(b.RepoEvents) == 0 &&4848- len(b.IssueEvents.Items) == 0 &&4949- len(b.PullEvents.Items) == 05050-}5151-5252-type IssueEvents struct {5353- Items []*models.Issue5454-}5555-5656-type IssueEventStats struct {5757- Open int5858- Closed int5959-}6060-6161-func (i IssueEvents) Stats() IssueEventStats {6262- var open, closed int6363- for _, issue := range i.Items {6464- if issue.Open {6565- open += 16666- } else {6767- closed += 16868- }6969- }7070-7171- return IssueEventStats{7272- Open: open,7373- Closed: closed,7474- }7575-}7676-7777-type PullEvents struct {7878- Items []*models.Pull7979-}8080-8181-func (p PullEvents) Stats() PullEventStats {8282- var open, merged, closed int8383- for _, pull := range p.Items {8484- switch pull.State {8585- case models.PullOpen:8686- open += 18787- case models.PullMerged:8888- merged += 18989- case models.PullClosed:9090- closed += 19191- }9292- }9393-9494- return PullEventStats{9595- Open: open,9696- Merged: merged,9797- Closed: closed,9898- }9999-}100100-101101-type PullEventStats struct {102102- Closed int103103- Open int104104- Merged int105105-}106106-10716const TimeframeMonths = 710817109109-func MakeProfileTimeline(e Execer, forDid string) (*ProfileTimeline, error) {110110- timeline := ProfileTimeline{111111- ByMonth: make([]ByMonth, TimeframeMonths),1818+func MakeProfileTimeline(e Execer, forDid string) (*models.ProfileTimeline, error) {1919+ timeline := models.ProfileTimeline{2020+ ByMonth: make([]models.ByMonth, TimeframeMonths),11221 }11322 currentMonth := time.Now().Month()11423 timeframe := fmt.Sprintf("-%d months", TimeframeMonths)···90181 idx := currentMonth - repoMonth9118292183 items := &timeline.ByMonth[idx].RepoEvents9393- *items = append(*items, RepoEvent{184184+ *items = append(*items, models.RepoEvent{94185 Repo: &repo,95186 Source: sourceRepo,96187 })···99190 return &timeline, nil100191}101192102102-type Profile struct {103103- // ids104104- ID int105105- Did string106106-107107- // data108108- Description string109109- IncludeBluesky bool110110- Location string111111- Links [5]string112112- Stats [2]VanityStat113113- PinnedRepos [6]syntax.ATURI114114-}115115-116116-func (p Profile) IsLinksEmpty() bool {117117- for _, l := range p.Links {118118- if l != "" {119119- return false120120- }121121- }122122- return true123123-}124124-125125-func (p Profile) IsStatsEmpty() bool {126126- for _, s := range p.Stats {127127- if s.Kind != "" {128128- return false129129- }130130- }131131- return true132132-}133133-134134-func (p Profile) IsPinnedReposEmpty() bool {135135- for _, r := range p.PinnedRepos {136136- if r != "" {137137- return false138138- }139139- }140140- return true141141-}142142-143143-type VanityStatKind string144144-145145-const (146146- VanityStatMergedPRCount VanityStatKind = "merged-pull-request-count"147147- VanityStatClosedPRCount VanityStatKind = "closed-pull-request-count"148148- VanityStatOpenPRCount VanityStatKind = "open-pull-request-count"149149- VanityStatOpenIssueCount VanityStatKind = "open-issue-count"150150- VanityStatClosedIssueCount VanityStatKind = "closed-issue-count"151151- VanityStatRepositoryCount VanityStatKind = "repository-count"152152-)153153-154154-func (v VanityStatKind) String() string {155155- switch v {156156- case VanityStatMergedPRCount:157157- return "Merged PRs"158158- case VanityStatClosedPRCount:159159- return "Closed PRs"160160- case VanityStatOpenPRCount:161161- return "Open PRs"162162- case VanityStatOpenIssueCount:163163- return "Open Issues"164164- case VanityStatClosedIssueCount:165165- return "Closed Issues"166166- case VanityStatRepositoryCount:167167- return "Repositories"168168- }169169- return ""170170-}171171-172172-type VanityStat struct {173173- Kind VanityStatKind174174- Value uint64175175-}176176-177177-func (p *Profile) ProfileAt() syntax.ATURI {178178- return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", p.Did, tangled.ActorProfileNSID, "self"))179179-}180180-181181-func UpsertProfile(tx *sql.Tx, profile *Profile) error {193193+func UpsertProfile(tx *sql.Tx, profile *models.Profile) error {182194 defer tx.Rollback()183195184196 // update links···197367 return tx.Commit()198368}199369200200-func GetProfiles(e Execer, filters ...filter) (map[string]*Profile, error) {370370+func GetProfiles(e Execer, filters ...filter) (map[string]*models.Profile, error) {201371 var conditions []string202372 var args []any203373 for _, filter := range filters {···227397 return nil, err228398 }229399230230- profileMap := make(map[string]*Profile)400400+ profileMap := make(map[string]*models.Profile)231401 for rows.Next() {232232- var profile Profile402402+ var profile models.Profile233403 var includeBluesky int234404235405 err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location)···300470 return profileMap, nil301471}302472303303-func GetProfile(e Execer, did string) (*Profile, error) {304304- var profile Profile473473+func GetProfile(e Execer, did string) (*models.Profile, error) {474474+ var profile models.Profile305475 profile.Did = did306476307477 includeBluesky := 0···310480 did,311481 ).Scan(&profile.Description, &includeBluesky, &profile.Location)312482 if err == sql.ErrNoRows {313313- profile := Profile{}483483+ profile := models.Profile{}314484 profile.Did = did315485 return &profile, nil316486 }···370540 return &profile, nil371541}372542373373-func GetVanityStat(e Execer, did string, stat VanityStatKind) (uint64, error) {543543+func GetVanityStat(e Execer, did string, stat models.VanityStatKind) (uint64, error) {374544 query := ""375545 var args []any376546 switch stat {377377- case VanityStatMergedPRCount:547547+ case models.VanityStatMergedPRCount:378548 query = `select count(id) from pulls where owner_did = ? and state = ?`379549 args = append(args, did, models.PullMerged)380380- case VanityStatClosedPRCount:550550+ case models.VanityStatClosedPRCount:381551 query = `select count(id) from pulls where owner_did = ? and state = ?`382552 args = append(args, did, models.PullClosed)383383- case VanityStatOpenPRCount:553553+ case models.VanityStatOpenPRCount:384554 query = `select count(id) from pulls where owner_did = ? and state = ?`385555 args = append(args, did, models.PullOpen)386386- case VanityStatOpenIssueCount:556556+ case models.VanityStatOpenIssueCount:387557 query = `select count(id) from issues where did = ? and open = 1`388558 args = append(args, did)389389- case VanityStatClosedIssueCount:559559+ case models.VanityStatClosedIssueCount:390560 query = `select count(id) from issues where did = ? and open = 0`391561 args = append(args, did)392392- case VanityStatRepositoryCount:562562+ case models.VanityStatRepositoryCount:393563 query = `select count(id) from repos where did = ?`394564 args = append(args, did)395565 }···403573 return result, nil404574}405575406406-func ValidateProfile(e Execer, profile *Profile) error {576576+func ValidateProfile(e Execer, profile *models.Profile) error {407577 // ensure description is not too long408578 if len(profile.Description) > 256 {409579 return fmt.Errorf("Entered bio is too long.")···451621 return nil452622}453623454454-func validateLinks(profile *Profile) error {624624+func validateLinks(profile *models.Profile) error {455625 for i, link := range profile.Links {456626 if link == "" {457627 continue
+1-1
appview/db/timeline.go
···1919 Source *models.Repo20202121 // optional: populate only if event is Follow2222- *Profile2222+ *models.Profile2323 *models.FollowStats2424 *models.FollowStatus2525
+3-3
appview/ingester.go
···299299 }300300 }301301302302- var stats [2]db.VanityStat302302+ var stats [2]models.VanityStat303303 for i, s := range record.Stats {304304 if i < 2 {305305- stats[i].Kind = db.VanityStatKind(s)305305+ stats[i].Kind = models.VanityStatKind(s)306306 }307307 }308308···313313 }314314 }315315316316- profile := db.Profile{316316+ profile := models.Profile{317317 Did: did,318318 Description: description,319319 IncludeBluesky: includeBluesky,
+177
appview/models/profile.go
···11+package models22+33+import (44+ "fmt"55+66+ "github.com/bluesky-social/indigo/atproto/syntax"77+ "tangled.org/core/api/tangled"88+)99+1010+type Profile struct {1111+ // ids1212+ ID int1313+ Did string1414+1515+ // data1616+ Description string1717+ IncludeBluesky bool1818+ Location string1919+ Links [5]string2020+ Stats [2]VanityStat2121+ PinnedRepos [6]syntax.ATURI2222+}2323+2424+func (p Profile) IsLinksEmpty() bool {2525+ for _, l := range p.Links {2626+ if l != "" {2727+ return false2828+ }2929+ }3030+ return true3131+}3232+3333+func (p Profile) IsStatsEmpty() bool {3434+ for _, s := range p.Stats {3535+ if s.Kind != "" {3636+ return false3737+ }3838+ }3939+ return true4040+}4141+4242+func (p Profile) IsPinnedReposEmpty() bool {4343+ for _, r := range p.PinnedRepos {4444+ if r != "" {4545+ return false4646+ }4747+ }4848+ return true4949+}5050+5151+type VanityStatKind string5252+5353+const (5454+ VanityStatMergedPRCount VanityStatKind = "merged-pull-request-count"5555+ VanityStatClosedPRCount VanityStatKind = "closed-pull-request-count"5656+ VanityStatOpenPRCount VanityStatKind = "open-pull-request-count"5757+ VanityStatOpenIssueCount VanityStatKind = "open-issue-count"5858+ VanityStatClosedIssueCount VanityStatKind = "closed-issue-count"5959+ VanityStatRepositoryCount VanityStatKind = "repository-count"6060+)6161+6262+func (v VanityStatKind) String() string {6363+ switch v {6464+ case VanityStatMergedPRCount:6565+ return "Merged PRs"6666+ case VanityStatClosedPRCount:6767+ return "Closed PRs"6868+ case VanityStatOpenPRCount:6969+ return "Open PRs"7070+ case VanityStatOpenIssueCount:7171+ return "Open Issues"7272+ case VanityStatClosedIssueCount:7373+ return "Closed Issues"7474+ case VanityStatRepositoryCount:7575+ return "Repositories"7676+ }7777+ return ""7878+}7979+8080+type VanityStat struct {8181+ Kind VanityStatKind8282+ Value uint648383+}8484+8585+func (p *Profile) ProfileAt() syntax.ATURI {8686+ return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", p.Did, tangled.ActorProfileNSID, "self"))8787+}8888+8989+type RepoEvent struct {9090+ Repo *Repo9191+ Source *Repo9292+}9393+9494+type ProfileTimeline struct {9595+ ByMonth []ByMonth9696+}9797+9898+func (p *ProfileTimeline) IsEmpty() bool {9999+ if p == nil {100100+ return true101101+ }102102+103103+ for _, m := range p.ByMonth {104104+ if !m.IsEmpty() {105105+ return false106106+ }107107+ }108108+109109+ return true110110+}111111+112112+type ByMonth struct {113113+ RepoEvents []RepoEvent114114+ IssueEvents IssueEvents115115+ PullEvents PullEvents116116+}117117+118118+func (b ByMonth) IsEmpty() bool {119119+ return len(b.RepoEvents) == 0 &&120120+ len(b.IssueEvents.Items) == 0 &&121121+ len(b.PullEvents.Items) == 0122122+}123123+124124+type IssueEvents struct {125125+ Items []*Issue126126+}127127+128128+type IssueEventStats struct {129129+ Open int130130+ Closed int131131+}132132+133133+func (i IssueEvents) Stats() IssueEventStats {134134+ var open, closed int135135+ for _, issue := range i.Items {136136+ if issue.Open {137137+ open += 1138138+ } else {139139+ closed += 1140140+ }141141+ }142142+143143+ return IssueEventStats{144144+ Open: open,145145+ Closed: closed,146146+ }147147+}148148+149149+type PullEvents struct {150150+ Items []*Pull151151+}152152+153153+func (p PullEvents) Stats() PullEventStats {154154+ var open, merged, closed int155155+ for _, pull := range p.Items {156156+ switch pull.State {157157+ case PullOpen:158158+ open += 1159159+ case PullMerged:160160+ merged += 1161161+ case PullClosed:162162+ closed += 1163163+ }164164+ }165165+166166+ return PullEventStats{167167+ Open: open,168168+ Merged: merged,169169+ Closed: closed,170170+ }171171+}172172+173173+type PullEventStats struct {174174+ Closed int175175+ Open int176176+ Merged int177177+}