2023-09-13 04:35:17 +00:00
|
|
|
/*
|
|
|
|
Copyright © 2023 Seednode <seednode@seedno.de>
|
|
|
|
*/
|
|
|
|
|
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/gob"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
|
|
"github.com/klauspost/compress/zstd"
|
|
|
|
"seedno.de/seednode/roulette/types"
|
|
|
|
)
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
type fileCache struct {
|
2023-09-13 04:35:17 +00:00
|
|
|
mutex sync.RWMutex
|
|
|
|
list []string
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func (cache *fileCache) List() []string {
|
|
|
|
cache.mutex.RLock()
|
|
|
|
val := cache.list
|
|
|
|
cache.mutex.RUnlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
return val
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func (cache *fileCache) remove(path string) {
|
|
|
|
cache.mutex.RLock()
|
|
|
|
tempIndex := make([]string, len(cache.list))
|
|
|
|
copy(tempIndex, cache.list)
|
|
|
|
cache.mutex.RUnlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
var position int
|
|
|
|
|
|
|
|
for k, v := range tempIndex {
|
|
|
|
if path == v {
|
|
|
|
position = k
|
|
|
|
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tempIndex[position] = tempIndex[len(tempIndex)-1]
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
cache.mutex.Lock()
|
|
|
|
cache.list = make([]string, len(tempIndex)-1)
|
|
|
|
copy(cache.list, tempIndex[:len(tempIndex)-1])
|
|
|
|
cache.mutex.Unlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func (cache *fileCache) set(val []string) {
|
|
|
|
cache.mutex.Lock()
|
|
|
|
cache.list = val
|
|
|
|
cache.mutex.Unlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func (cache *fileCache) generate(args []string, formats *types.Types) {
|
|
|
|
cache.mutex.Lock()
|
|
|
|
cache.list = []string{}
|
|
|
|
cache.mutex.Unlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
fileList(args, &filters{}, "", cache, formats)
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
if Cache && CacheFile != "" {
|
2023-09-13 14:26:15 +00:00
|
|
|
cache.Export(CacheFile)
|
2023-09-13 04:35:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func (cache *fileCache) isEmpty() bool {
|
|
|
|
cache.mutex.RLock()
|
|
|
|
length := len(cache.list)
|
|
|
|
cache.mutex.RUnlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
return length == 0
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func (cache *fileCache) Export(path string) error {
|
2023-09-13 04:35:17 +00:00
|
|
|
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)
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
cache.mutex.RLock()
|
|
|
|
enc.Encode(&cache.list)
|
|
|
|
cache.mutex.RUnlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func (cache *fileCache) Import(path string) error {
|
2023-09-13 04:35:17 +00:00
|
|
|
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)
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
cache.mutex.Lock()
|
2023-09-13 04:35:17 +00:00
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
err = dec.Decode(&cache.list)
|
2023-09-13 04:35:17 +00:00
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
cache.mutex.Unlock()
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-13 14:26:15 +00:00
|
|
|
func serveCacheClear(args []string, cache *fileCache, formats *types.Types) httprouter.Handle {
|
2023-09-13 04:35:17 +00:00
|
|
|
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
2023-09-13 14:26:15 +00:00
|
|
|
cache.generate(args, formats)
|
2023-09-13 04:35:17 +00:00
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "text/plain")
|
|
|
|
|
|
|
|
w.Write([]byte("Ok"))
|
|
|
|
}
|
|
|
|
}
|
2023-09-13 17:00:24 +00:00
|
|
|
|
|
|
|
func registerCacheHandlers(mux *httprouter.Router, args []string, cache *fileCache, formats *types.Types) {
|
|
|
|
skipIndex := false
|
|
|
|
|
|
|
|
if CacheFile != "" {
|
|
|
|
err := cache.Import(CacheFile)
|
|
|
|
if err == nil {
|
|
|
|
skipIndex = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !skipIndex {
|
|
|
|
cache.generate(args, formats)
|
|
|
|
}
|
|
|
|
|
|
|
|
mux.GET("/clear_cache", serveCacheClear(args, cache, formats))
|
|
|
|
}
|