repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
13803bd
parent
77553f3
author
Eric Bower
date
2024-06-16 18:25:47 +0000 UTC
chore: formatting analytics
3 files changed,  +101, -3
M pgs/cli.go
+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 {
M prose/cli.go
+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)
M tui/common/tbl.go
+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+}