/* Copyright © 2023 Seednode */ package cmd import ( "encoding/gob" "net/http" "os" "sync" "github.com/julienschmidt/httprouter" "github.com/klauspost/compress/zstd" "seedno.de/seednode/roulette/types" ) type FileIndex struct { mutex sync.RWMutex list []string } func (i *FileIndex) Index() []string { i.mutex.RLock() val := i.list i.mutex.RUnlock() return val } func (i *FileIndex) Remove(path string) { i.mutex.RLock() tempIndex := make([]string, len(i.list)) copy(tempIndex, i.list) i.mutex.RUnlock() var position int for k, v := range tempIndex { if path == v { position = k break } } tempIndex[position] = tempIndex[len(tempIndex)-1] i.mutex.Lock() i.list = make([]string, len(tempIndex)-1) copy(i.list, tempIndex[:len(tempIndex)-1]) i.mutex.Unlock() } func (i *FileIndex) setIndex(val []string) { i.mutex.Lock() i.list = val i.mutex.Unlock() } func (i *FileIndex) generateCache(args []string, formats *types.Types) { i.mutex.Lock() i.list = []string{} i.mutex.Unlock() fileList(args, &Filters{}, "", i, formats) if Cache && CacheFile != "" { i.Export(CacheFile) } } func (i *FileIndex) IsEmpty() bool { i.mutex.RLock() length := len(i.list) i.mutex.RUnlock() return length == 0 } func (i *FileIndex) Export(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) i.mutex.RLock() enc.Encode(&i.list) i.mutex.RUnlock() return nil } func (i *FileIndex) Import(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) i.mutex.Lock() err = dec.Decode(&i.list) i.mutex.Unlock() if err != nil { return err } return nil } func serveCacheClear(args []string, index *FileIndex, formats *types.Types) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { index.generateCache(args, formats) w.Header().Set("Content-Type", "text/plain") w.Write([]byte("Ok")) } }