94 lines
1.9 KiB
Go
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
|
|
}
|