internal/httpd/activity.go

93b38a063b3b4b161a1baf976e92f53d02b1a221
gitbay/internal/httpd/activity.go history · blame · raw

66 lines · 1719 bytes

 1package httpd
 2
 3import (
 4	"time"
 5
 6	"gitbay.org/gitbay/internal/control"
 7)
 8
 9// activityDay is one cell of the graph; Level buckets Count into the five
10// intensity classes the stylesheet colors.
11type activityDay struct {
12	Date  string
13	Count int
14	Level int  // 0..4
15	Pad   bool // before the range start / after today
16}
17
18type activityWeek []activityDay // 7 days, Sunday first
19
20// activityGrid lays a day->count map into 53 week columns ending today,
21// GitHub-style: columns are weeks, rows Sunday..Saturday.
22func activityGrid(counts map[string]int) ([]activityWeek, int) {
23	today := time.Now().UTC()
24	// End the grid on the Saturday of the current week.
25	end := today.AddDate(0, 0, int(time.Saturday-today.Weekday()))
26	start := end.AddDate(0, 0, -53*7+1) // a Sunday, 53 columns back
27
28	total := 0
29	var weeks []activityWeek
30	for d := start; !d.After(end); d = d.AddDate(0, 0, 7) {
31		var week activityWeek
32		for i := 0; i < 7; i++ {
33			day := d.AddDate(0, 0, i)
34			key := day.Format("2006-01-02")
35			if day.After(today) {
36				week = append(week, activityDay{Date: key, Pad: true})
37				continue
38			}
39			n := counts[key]
40			total += n
41			week = append(week, activityDay{Date: key, Count: n, Level: activityLevel(n)})
42		}
43		weeks = append(weeks, week)
44	}
45	return weeks, total
46}
47
48func activityLevel(n int) int {
49	switch {
50	case n == 0:
51		return 0
52	case n <= 2:
53		return 1
54	case n <= 5:
55		return 2
56	case n <= 9:
57		return 3
58	default:
59		return 4
60	}
61}
62
63// activitySince is the first day the grid can show, for the query bound.
64// activitySince is control.ActivityWindow: the profile command and the
65// web must report the same year, so the span has one definition.
66func activitySince() string { return control.ActivityWindow() }