- commit
- 13803bd
- parent
- 77553f3
- author
- Eric Bower
- date
- 2024-06-16 18:25:47 +0000 UTC
chore: formatting analytics
3 files changed,
+101,
-3
+69,
-1
1@@ -1,10 +1,12 @@
2 package pgs
3
4 import (
5+ "cmp"
6 "errors"
7 "fmt"
8 "log/slog"
9 "path/filepath"
10+ "slices"
11 "strings"
12
13 "github.com/charmbracelet/lipgloss"
14@@ -228,6 +230,72 @@ func (c *Cmd) statsByProject(projectName string) error {
15 return nil
16 }
17
18+func (c *Cmd) statsSites() error {
19+ opts := &db.SummaryOpts{
20+ FkID: c.User.ID,
21+ By: "user_id",
22+ Interval: "day",
23+ Origin: shared.StartOfMonth(),
24+ }
25+
26+ summary, err := c.Dbpool.VisitSummary(opts)
27+ if err != nil {
28+ return err
29+ }
30+
31+ projects, err := c.Dbpool.FindProjectsByUser(c.User.ID)
32+ if err != nil {
33+ return err
34+ }
35+
36+ c.output("\nVisitor Analytics this Month\n")
37+
38+ c.output("Top URLs")
39+ topUrlsTbl := common.VisitUrlsWithProjectTbl(projects, summary.TopUrls)
40+
41+ c.output(topUrlsTbl.Width(c.Width).String())
42+
43+ c.output("Top Referers")
44+ topRefsTbl := common.VisitUrlsTbl(summary.TopReferers)
45+ c.output(topRefsTbl.Width(c.Width).String())
46+
47+ mapper := map[string]*db.VisitInterval{}
48+ result := []*db.VisitUrl{}
49+ // combine visitors by project_id
50+ for _, interval := range summary.Intervals {
51+ if interval.ProjectID == "" {
52+ continue
53+ }
54+ if _, ok := mapper[interval.ProjectID]; !ok {
55+ mapper[interval.ProjectID] = interval
56+ }
57+ mapper[interval.ProjectID].Visitors += interval.Visitors
58+ }
59+
60+ for _, val := range mapper {
61+ projectName := ""
62+ for _, project := range projects {
63+ if project.ID == val.ProjectID {
64+ projectName = project.Name
65+ }
66+ }
67+ result = append(result, &db.VisitUrl{
68+ Url: projectName,
69+ Count: val.Visitors,
70+ })
71+ }
72+
73+ slices.SortFunc(result, func(a, b *db.VisitUrl) int {
74+ return cmp.Compare(b.Count, a.Count)
75+ })
76+
77+ uniqueTbl := common.VisitUrlsTbl(result)
78+ c.output("Unique Visitors by Site")
79+ c.output(uniqueTbl.Width(c.Width).String())
80+
81+ return nil
82+}
83+
84 func (c *Cmd) stats(cfgMaxSize uint64) error {
85 ff, err := c.Dbpool.FindFeatureForUser(c.User.ID, "plus")
86 if err != nil {
87@@ -268,7 +336,7 @@ func (c *Cmd) stats(cfgMaxSize uint64) error {
88 Rows(data)
89 c.output(t.String())
90
91- return nil
92+ return c.statsSites()
93 }
94
95 func (c *Cmd) ls() error {
+4,
-1
1@@ -165,7 +165,10 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
2 opts.help()
3 return
4 } else if cmd == "stats" {
5- opts.stats()
6+ err := opts.stats()
7+ if err != nil {
8+ wish.Fatalln(sesh, err)
9+ }
10 return
11 } else {
12 next(sesh)
+28,
-1
1@@ -27,7 +27,7 @@ func UniqueVisitorsTbl(intervals []*db.VisitInterval) *table.Table {
2 }
3
4 func VisitUrlsTbl(urls []*db.VisitUrl) *table.Table {
5- headers := []string{"Site", "Count"}
6+ headers := []string{"URL", "Count"}
7 data := [][]string{}
8 for _, d := range urls {
9 data = append(data, []string{
10@@ -42,3 +42,30 @@ func VisitUrlsTbl(urls []*db.VisitUrl) *table.Table {
11 Rows(data...)
12 return t
13 }
14+
15+func VisitUrlsWithProjectTbl(projects []*db.Project, urls []*db.VisitUrl) *table.Table {
16+ headers := []string{"Project", "URL", "Count"}
17+ data := [][]string{}
18+ for _, d := range urls {
19+ if d.ProjectID == "" {
20+ continue
21+ }
22+ projectName := ""
23+ for _, project := range projects {
24+ if project.ID == d.ProjectID {
25+ projectName = project.Name
26+ }
27+ }
28+ data = append(data, []string{
29+ projectName,
30+ d.Url,
31+ fmt.Sprintf("%d", d.Count),
32+ })
33+ }
34+
35+ t := table.New().
36+ Border(lipgloss.RoundedBorder()).
37+ Headers(headers...).
38+ Rows(data...)
39+ return t
40+}