wrappd.sh/internal/web/utils.go

164 lines
3.4 KiB
Go
Raw Normal View History

2024-12-05 14:00:58 +01:00
package web
import (
"bufio"
"encoding/json"
"fmt"
"html/template"
"log"
"net/http"
"os"
"path/filepath"
"sort"
"strings"
"github.com/go-echarts/go-echarts/v2/charts"
"github.com/go-echarts/go-echarts/v2/opts"
)
func loadTemplates(name string) (*template.Template, error) {
funcs := template.FuncMap{
"safeHTML": func(s string) interface{} { return template.HTML(s) },
}
templates, err := loadTemplatesFromDir("internal/web/templates")
if err != nil {
log.Printf("Error loading templates: %v", err)
return nil, err
}
return template.New(name).Funcs(funcs).ParseFiles(templates...)
}
func ConvertAndSort[K comparable](data map[K]int, limit int) []CommandStat {
var result []CommandStat
for key, count := range data {
result = append(result, CommandStat{
Command: fmt.Sprintf("%v", key),
Count: count,
})
}
sort.Slice(result, func(i, j int) bool {
return result[i].Count > result[j].Count
})
if len(result) > limit {
result = result[:limit]
}
return result
}
func parseHistoryFile(file http.File) (map[string]int, error) {
commandCounts := make(map[string]int)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
command := strings.Fields(line)[0]
commandCounts[command]++
}
if err := scanner.Err(); err != nil {
return nil, err
}
return commandCounts, nil
}
func generateTopCommands(commandCounts map[string]int, topN int) []CommandStat {
stats := make([]CommandStat, 0, len(commandCounts))
for cmd, count := range commandCounts {
stats = append(stats, CommandStat{Command: cmd, Count: count})
}
sort.Slice(stats, func(i, j int) bool {
return stats[i].Count > stats[j].Count
})
if topN < len(stats) {
stats = stats[:topN]
}
return stats
}
func createBarChart(stats []CommandStat) *charts.Bar {
bar := charts.NewBar()
bar.SetGlobalOptions(
charts.WithTitleOpts(opts.Title{
Title: "Top Commands",
2024-12-05 14:12:41 +01:00
Subtitle: "Most used commands",
2024-12-05 14:00:58 +01:00
}),
2024-12-05 17:42:15 +01:00
charts.WithXAxisOpts(opts.XAxis{
AxisLabel: &opts.AxisLabel{
Show: opts.Bool(true),
Interval: "0",
Rotate: 45,
},
}),
2024-12-05 14:00:58 +01:00
)
commands := make([]string, len(stats))
counts := make([]int, len(stats))
for i, stat := range stats {
commands[i] = stat.Command
counts[i] = stat.Count
}
bar.SetXAxis(commands).
2024-12-05 17:42:15 +01:00
AddSeries("Freq", generateBarItems(counts))
2024-12-05 14:00:58 +01:00
return bar
}
func generateBarItems(data []int) []opts.BarData {
items := make([]opts.BarData, len(data))
for i, v := range data {
items[i] = opts.BarData{Value: v}
}
return items
}
func saveResults(uniqueID string, stats map[string]interface{}) {
filename := "results/" + uniqueID + ".json"
file, err := os.Create(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
json.NewEncoder(file).Encode(stats)
}
func loadResults(uniqueID string) (map[string]interface{}, error) {
filename := "results/" + uniqueID + ".json"
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
var stats map[string]interface{}
err = json.NewDecoder(file).Decode(&stats)
return stats, err
}
func loadTemplatesFromDir(dir string) ([]string, error) {
var templates []string
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && filepath.Ext(path) == ".html" {
templates = append(templates, path)
}
return nil
})
return templates, err
}