tstor/src/host/store/excluded-files.go
2024-01-28 23:22:49 +03:00

94 lines
1.9 KiB
Go

package store
import (
"errors"
"path/filepath"
"sync"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo"
"github.com/philippgille/gokv"
"github.com/philippgille/gokv/badgerdb"
"github.com/philippgille/gokv/encoding"
)
func NewExcludedFiles(metaDir string, storage TorrentFileDeleter) (*ExlcudedFiles, error) {
excludedFilesStore, err := badgerdb.NewStore(badgerdb.Options{
Dir: filepath.Join(metaDir, "excluded-files"),
Codec: encoding.JSON,
})
if err != nil {
return nil, err
}
r := &ExlcudedFiles{
excludedFiles: excludedFilesStore,
storage: storage,
}
return r, nil
}
type ExlcudedFiles struct {
m sync.RWMutex
excludedFiles gokv.Store
storage TorrentFileDeleter
}
var ErrNotFound = errors.New("not found")
type TorrentFileDeleter interface {
DeleteFile(file *torrent.File) error
}
func (r *ExlcudedFiles) ExcludeFile(file *torrent.File) error {
r.m.Lock()
defer r.m.Unlock()
hash := file.Torrent().InfoHash()
var excludedFiles []string
found, err := r.excludedFiles.Get(hash.AsString(), &excludedFiles)
if err != nil {
return err
}
if !found {
excludedFiles = []string{}
}
excludedFiles = unique(append(excludedFiles, file.Path()))
err = r.storage.DeleteFile(file)
if err != nil {
return err
}
return r.excludedFiles.Set(hash.AsString(), excludedFiles)
}
func (r *ExlcudedFiles) ExcludedFiles(hash metainfo.Hash) ([]string, error) {
r.m.Lock()
defer r.m.Unlock()
var excludedFiles []string
found, err := r.excludedFiles.Get(hash.AsString(), &excludedFiles)
if err != nil {
return nil, err
}
if !found {
return nil, nil
}
return excludedFiles, nil
}
func unique[C comparable](intSlice []C) []C {
keys := make(map[C]bool)
list := []C{}
for _, entry := range intSlice {
if _, value := keys[entry]; !value {
keys[entry] = true
list = append(list, entry)
}
}
return list
}