Files
ghstats/internal/github/model.go
T
tiennm99 208629cf8f feat: add all-time variants of productive, language, contribution cards
Four time-bounded cards ("last year") now have all-time counterparts, and
the stats card gains a lifetime commits row.

New cards:
- 6-most-commit-language-all-time.svg (byte-weighted, all lifetime commits)
- 7-productive-time-all-time.svg       (hour histogram over all lifetime commits)
- 8-contributions-all-time.svg         (area chart spanning every active year)

Data pipeline:
- Drop the "since" filter from commitHistoryQuery; FetchProductive now
  paginates unbounded commits and splits each commit into last-year and
  all-time buckets in a single pass — no extra API calls.
- New contributionYearQuery iterates user.contributionYears to
  concatenate calendar data and accumulate TotalCommitsAllTime.
- -commits-per-repo default bumped 100 → 500 to give all-time depth.

Polish:
- Productive-time title embeds the configured tz as "UTC±N.NN" (e.g.
  UTC+7.00) on both last-year and all-time cards.
- Contribution x-axis flipped to mm/yy with an "mm/yy" footer caption
  paralleling productive-time's "hour of day".
- Contribution x-axis label stride now targets ~6 labels regardless of
  bucket count so the all-time chart (~100 months) stays readable while
  the underlying curve still samples every month.
2026-04-18 21:40:46 +07:00

127 lines
3.9 KiB
Go

package github
import "time"
// Profile is the aggregate of data other packages render into cards.
type Profile struct {
ID string
Login string
Name string
Bio string
AvatarURL string
Company string
Location string
Website string
CreatedAt time.Time
Followers int
Following int
PublicRepos int
// Totals for the stats card.
TotalStars int
TotalForks int
TotalCommits int // last year, from contributionsCollection
TotalCommitsAllTime int // sum across contributionYears
TotalPRs int
TotalIssues int
TotalReviews int
TotalContributedTo int
TotalContributions int // lifetime contributions from calendar + restricted
// Count of owned repos grouped by primary language, sorted desc by Value.
ReposByLanguage []LangStat
// Count of commits (last year, by this user) attributed to each repo's
// primary language, sorted desc. Populated by FetchProductive.
CommitsByLanguage []LangStat
// Commit counts grouped by hour-of-day (0-23) in the configured timezone.
// Productive is the last-year slice; ProductiveAllTime is the lifetime
// slice derived from the same paginated commit history so we pay for
// pagination once.
Productive [24]int
ProductiveAllTime [24]int
// CommitsByLanguageAllTime is the lifetime counterpart of
// CommitsByLanguage, computed from the same commit stream.
CommitsByLanguageAllTime []LangStat
// DailyContributions is the raw per-day contribution calendar covering
// the most recent year. The area chart aggregates it into monthly
// buckets; kept granular here so any downstream card can re-bin freely.
DailyContributions []DailyContribution
// DailyContributionsAllTime concatenates contribution calendars across
// every year the user has been active (user.contributionYears), so the
// all-time area chart can show history beyond the default 1-year window.
DailyContributionsAllTime []DailyContribution
// TopRepos are owned repos sorted by stargazer count desc. Populated by
// FetchProfile and consumed by FetchProductive.
TopRepos []RepoInfo
// ContributionYears lists every calendar year the user has been active
// on GitHub, newest first. Used by FetchContributionsAllTime to iterate
// per-year contributionsCollection queries.
ContributionYears []int
// UTCOffsetLabel is the configured timezone rendered as "UTC±N.NN" for
// display on time-based cards (e.g. "UTC+7.00" for Asia/Saigon). Filled
// by the CLI after loading -tz.
UTCOffsetLabel string
}
// DailyContribution is a single day in the contributions calendar.
type DailyContribution struct {
Date time.Time
Count int
}
// LangStat is one row in a language breakdown card. Value is repo count or
// commit count depending on which slice holds it.
type LangStat struct {
Name string
Color string
Value int64
}
// RepoInfo is the minimal owned-repo summary used for downstream fetches.
type RepoInfo struct {
Name string
PrimaryLanguage string
PrimaryColor string
// Languages is the repo's language byte breakdown as reported by GitHub
// linguist. Used to attribute each commit fractionally across all
// languages the repo contains, rather than crediting only the primary.
Languages []LangEdge
}
// LangEdge is a single entry in a repo's language-bytes breakdown.
type LangEdge struct {
Name string
Color string
Bytes int64
}
// repoNode is the GraphQL shape of one repository node; kept here because
// it's shared by the profile fetcher and the productive-time fetcher.
type repoNode struct {
Name string `json:"name"`
StargazerCount int `json:"stargazerCount"`
ForkCount int `json:"forkCount"`
PrimaryLanguage *struct {
Name string `json:"name"`
Color string `json:"color"`
} `json:"primaryLanguage"`
Languages struct {
Edges []struct {
Size int64 `json:"size"`
Node struct {
Name string `json:"name"`
Color string `json:"color"`
} `json:"node"`
} `json:"edges"`
} `json:"languages"`
}