Added support for persistent index file
This commit is contained in:
parent
2f92089191
commit
69c4ccfc97
|
@ -92,13 +92,14 @@ Available Commands:
|
||||||
version Print version
|
version Print version
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
-c, --cache only scan directories once, at startup (or when filters are applied)
|
-c, --cache generate directory cache at startup
|
||||||
-d, --debug store list of files served and number of times they were served
|
-d, --debug expose stats endpoint
|
||||||
-f, --filter enable filtering via query parameters
|
-f, --filter enable filtering
|
||||||
-h, --help help for roulette
|
-h, --help help for roulette
|
||||||
|
-i, --index string path to persistent index file
|
||||||
-p, --port uint16 port to listen on (default 8080)
|
-p, --port uint16 port to listen on (default 8080)
|
||||||
-r, --recursive recurse into subdirectories
|
-r, --recursive recurse into subdirectories
|
||||||
-s, --sort enable sorting via query parameters
|
-s, --sort enable sorting
|
||||||
-v, --verbose log accessed files to stdout
|
-v, --verbose log accessed files to stdout
|
||||||
|
|
||||||
Use "roulette [command] --help" for more information about a command.
|
Use "roulette [command] --help" for more information about a command.
|
||||||
|
|
|
@ -15,6 +15,7 @@ var (
|
||||||
cache bool
|
cache bool
|
||||||
debug bool
|
debug bool
|
||||||
filtering bool
|
filtering bool
|
||||||
|
indexFile string
|
||||||
port uint16
|
port uint16
|
||||||
recursive bool
|
recursive bool
|
||||||
sorting bool
|
sorting bool
|
||||||
|
@ -47,6 +48,7 @@ func init() {
|
||||||
rootCmd.Flags().BoolVarP(&cache, "cache", "c", false, "generate directory cache at startup")
|
rootCmd.Flags().BoolVarP(&cache, "cache", "c", false, "generate directory cache at startup")
|
||||||
rootCmd.Flags().BoolVarP(&debug, "debug", "d", false, "expose stats endpoint")
|
rootCmd.Flags().BoolVarP(&debug, "debug", "d", false, "expose stats endpoint")
|
||||||
rootCmd.Flags().BoolVarP(&filtering, "filter", "f", false, "enable filtering")
|
rootCmd.Flags().BoolVarP(&filtering, "filter", "f", false, "enable filtering")
|
||||||
|
rootCmd.Flags().StringVarP(&indexFile, "index", "i", "", "path to persistent index file")
|
||||||
rootCmd.Flags().Uint16VarP(&port, "port", "p", 8080, "port to listen on")
|
rootCmd.Flags().Uint16VarP(&port, "port", "p", 8080, "port to listen on")
|
||||||
rootCmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "recurse into subdirectories")
|
rootCmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "recurse into subdirectories")
|
||||||
rootCmd.Flags().BoolVarP(&sorting, "sort", "s", false, "enable sorting")
|
rootCmd.Flags().BoolVarP(&sorting, "sort", "s", false, "enable sorting")
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "0.34.2"
|
var Version = "0.35.0"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(versionCmd)
|
rootCmd.AddCommand(versionCmd)
|
||||||
|
|
62
cmd/web.go
62
cmd/web.go
|
@ -5,7 +5,9 @@ Copyright © 2023 Seednode <seednode@seedno.de>
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/gob"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
@ -25,6 +27,10 @@ import (
|
||||||
"github.com/yosssi/gohtml"
|
"github.com/yosssi/gohtml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrIndexNotExist = errors.New(`specified index does not exist`)
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LogDate string = `2006-01-02T15:04:05.000-07:00`
|
LogDate string = `2006-01-02T15:04:05.000-07:00`
|
||||||
Prefix string = `/src`
|
Prefix string = `/src`
|
||||||
|
@ -87,6 +93,10 @@ func (i *Index) generateCache(args []string) {
|
||||||
i.mutex.Unlock()
|
i.mutex.Unlock()
|
||||||
|
|
||||||
fileList(args, &Filters{}, "", i)
|
fileList(args, &Filters{}, "", i)
|
||||||
|
|
||||||
|
if indexFile != "" {
|
||||||
|
i.Export(indexFile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Index) IsEmpty() bool {
|
func (i *Index) IsEmpty() bool {
|
||||||
|
@ -97,6 +107,39 @@ func (i *Index) IsEmpty() bool {
|
||||||
return length == 0
|
return length == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Index) Export(path string) error {
|
||||||
|
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
enc := gob.NewEncoder(file)
|
||||||
|
|
||||||
|
enc.Encode(&i.list)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Index) Import(path string) error {
|
||||||
|
file, err := os.OpenFile(path, os.O_RDONLY, 0600)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return ErrIndexNotExist
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
dec := gob.NewDecoder(file)
|
||||||
|
|
||||||
|
err = dec.Decode(&i.list)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type ServeStats struct {
|
type ServeStats struct {
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
list []string
|
list []string
|
||||||
|
@ -577,7 +620,9 @@ func ServePage(args []string) error {
|
||||||
units: regexp.MustCompile(`^[0-9]+(ns|us|µs|ms|s|m|h)$`),
|
units: regexp.MustCompile(`^[0-9]+(ns|us|µs|ms|s|m|h)$`),
|
||||||
}
|
}
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
//NewRand(NewSource(time.Now().UnixNano()))
|
||||||
|
|
||||||
|
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
||||||
index := &Index{
|
index := &Index{
|
||||||
mutex: sync.RWMutex{},
|
mutex: sync.RWMutex{},
|
||||||
|
@ -585,7 +630,22 @@ func ServePage(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cache {
|
if cache {
|
||||||
|
skipIndex := false
|
||||||
|
|
||||||
|
if indexFile != "" {
|
||||||
|
err = index.Import(indexFile)
|
||||||
|
switch err {
|
||||||
|
case ErrIndexNotExist:
|
||||||
|
case nil:
|
||||||
|
skipIndex = true
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !skipIndex {
|
||||||
index.generateCache(args)
|
index.generateCache(args)
|
||||||
|
}
|
||||||
|
|
||||||
http.Handle("/_/clear_cache", serveCacheClearHandler(args, index))
|
http.Handle("/_/clear_cache", serveCacheClearHandler(args, index))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue