From 65b77f33cc1343f09f192f4048229ec9e517c861 Mon Sep 17 00:00:00 2001 From: Seednode Date: Wed, 13 Sep 2023 12:30:24 -0500 Subject: [PATCH] Attempt to rework stats handling, add support for '~' in paths --- cmd/files.go | 14 ++++- cmd/root.go | 2 +- cmd/stats.go | 143 +++++++++++++++++++++++---------------------------- cmd/web.go | 25 +++++++++ 4 files changed, 104 insertions(+), 80 deletions(-) diff --git a/cmd/files.go b/cmd/files.go index 15c6845..4d09bf7 100644 --- a/cmd/files.go +++ b/cmd/files.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "math/big" + "os/user" "regexp" "crypto/rand" @@ -603,7 +604,18 @@ func pickFile(args []string, filters *filters, sort string, cache *fileCache, fo } func normalizePath(path string) (string, error) { - path, err := filepath.EvalSymlinks(path) + usr, err := user.Current() + if err != nil { + return "", err + } + + if path == "~" { + path = usr.HomeDir + } else if strings.HasPrefix(path, "~/") { + path = filepath.Join(usr.HomeDir, path[2:]) + } + + path, err = filepath.EvalSymlinks(path) if err != nil { return "", err } diff --git a/cmd/root.go b/cmd/root.go index 4737cea..650f2fa 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,7 +12,7 @@ import ( ) const ( - ReleaseVersion string = "0.78.0" + ReleaseVersion string = "0.78.1" ) var ( diff --git a/cmd/stats.go b/cmd/stats.go index e1a32ea..8b001e4 100644 --- a/cmd/stats.go +++ b/cmd/stats.go @@ -10,12 +10,10 @@ import ( "fmt" "net/http" "os" - "os/signal" "sort" "strconv" "strings" "sync" - "syscall" "time" "github.com/julienschmidt/httprouter" @@ -69,14 +67,18 @@ func (stats *serveStats) Import(source *publicServeStats) { copy(stats.list, source.List) for k, v := range source.Count { + fmt.Printf("Setting count[%s] to %d\n", k, v) stats.count[k] = v } for k, v := range source.Size { + fmt.Printf("Setting size[%s] to %v\n", k, v) + stats.size[k] = v } for k, v := range source.Times { + fmt.Printf("Setting times[%s] to %v\n", k, v) stats.times[k] = v } @@ -84,6 +86,8 @@ func (stats *serveStats) Import(source *publicServeStats) { } func (source *serveStats) Export() *publicServeStats { + source.mutex.RLock() + stats := &publicServeStats{ List: make([]string, len(source.list)), Count: make(map[string]uint32, len(source.count)), @@ -91,8 +95,6 @@ func (source *serveStats) Export() *publicServeStats { Times: make(map[string][]string, len(source.times)), } - source.mutex.RLock() - copy(stats.List, source.list) for k, v := range source.count { @@ -112,6 +114,61 @@ func (source *serveStats) Export() *publicServeStats { return stats } +func (stats *serveStats) exportFile(path string) error { + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + defer file.Close() + + z, err := zstd.NewWriter(file) + if err != nil { + return err + } + defer z.Close() + + enc := gob.NewEncoder(z) + + err = enc.Encode(stats.Export()) + if err != nil { + return err + } + + return nil +} + +func (stats *serveStats) importFile(path string) error { + file, err := os.OpenFile(path, os.O_RDONLY, 0600) + if err != nil { + return err + } + defer file.Close() + + z, err := zstd.NewReader(file) + if err != nil { + return err + } + defer z.Close() + + dec := gob.NewDecoder(z) + + source := &publicServeStats{ + List: []string{}, + Count: make(map[string]uint32), + Size: make(map[string]string), + Times: make(map[string][]string), + } + + err = dec.Decode(source) + if err != nil { + return err + } + + stats.Import(source) + + return nil +} + func (source *serveStats) listFiles(page int) ([]byte, error) { stats := source.Export() @@ -151,61 +208,6 @@ func (source *serveStats) listFiles(page int) ([]byte, error) { return r, nil } -func (stats *serveStats) ExportFile(path string) error { - file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return err - } - defer file.Close() - - z, err := zstd.NewWriter(file) - if err != nil { - return err - } - defer z.Close() - - enc := gob.NewEncoder(z) - - err = enc.Encode(stats.Export()) - if err != nil { - return err - } - - return nil -} - -func (stats *serveStats) ImportFile(path string) error { - file, err := os.OpenFile(path, os.O_RDONLY, 0600) - if err != nil { - return err - } - defer file.Close() - - z, err := zstd.NewReader(file) - if err != nil { - return err - } - defer z.Close() - - dec := gob.NewDecoder(z) - - source := &publicServeStats{ - List: []string{}, - Count: make(map[string]uint32), - Size: make(map[string]string), - Times: make(map[string][]string), - } - - err = dec.Decode(source) - if err != nil { - return err - } - - stats.Import(source) - - return nil -} - func serveStatsPage(args []string, stats *serveStats) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { startTime := time.Now() @@ -238,29 +240,14 @@ func serveStatsPage(args []string, stats *serveStats) httprouter.Handle { } if StatisticsFile != "" { - stats.ExportFile(StatisticsFile) + stats.exportFile(StatisticsFile) } } } func registerStatsHandlers(mux *httprouter.Router, args []string, stats *serveStats) { - if StatisticsFile != "" { - stats.ImportFile(StatisticsFile) - - gracefulShutdown := make(chan os.Signal, 1) - signal.Notify(gracefulShutdown, syscall.SIGINT, syscall.SIGTERM) - - go func() { - <-gracefulShutdown - - stats.ExportFile(StatisticsFile) - - os.Exit(0) - }() - - mux.GET("/stats", serveStatsPage(args, stats)) - if PageLength != 0 { - mux.GET("/stats/:page", serveStatsPage(args, stats)) - } + mux.GET("/stats", serveStatsPage(args, stats)) + if PageLength != 0 { + mux.GET("/stats/:page", serveStatsPage(args, stats)) } } diff --git a/cmd/web.go b/cmd/web.go index c9bc3b5..68574b4 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -12,12 +12,14 @@ import ( "net" "net/http" "os" + "os/signal" "path/filepath" "regexp" "runtime" "strconv" "strings" "sync" + "syscall" "time" "github.com/julienschmidt/httprouter" @@ -405,6 +407,29 @@ func ServePage(args []string) error { } if Statistics { + if StatisticsFile != "" { + StatisticsFile, err = normalizePath(StatisticsFile) + if err != nil { + return err + } + + err := stats.importFile(StatisticsFile) + if err != nil { + return err + } + + gracefulShutdown := make(chan os.Signal, 1) + signal.Notify(gracefulShutdown, syscall.SIGINT, syscall.SIGTERM) + + go func() { + <-gracefulShutdown + + stats.exportFile(StatisticsFile) + + os.Exit(0) + }() + } + registerStatsHandlers(mux, args, stats) }