This commit is contained in:
royalcat 2024-01-01 21:17:32 +03:00
parent 49444bd70d
commit 7d9f1a437c
6 changed files with 49 additions and 14 deletions

View file

@ -176,7 +176,7 @@ func run(configPath string) error {
go func() { go func() {
logFilename := filepath.Join(conf.Log.Path, dlog.FileName) logFilename := filepath.Join(conf.Log.Path, dlog.FileName)
err = http.New(nil, nil, ts, logFilename, conf) err = http.New(nil, service.NewStats(), ts, logFilename, conf)
log.Error().Err(err).Msg("error initializing HTTP server") log.Error().Err(err).Msg("error initializing HTTP server")
}() }()

View file

@ -7,6 +7,7 @@ import (
"github.com/anacrolix/torrent" "github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
atstorage "github.com/anacrolix/torrent/storage"
"github.com/philippgille/gokv" "github.com/philippgille/gokv"
"github.com/philippgille/gokv/badgerdb" "github.com/philippgille/gokv/badgerdb"
"github.com/philippgille/gokv/encoding" "github.com/philippgille/gokv/encoding"
@ -17,7 +18,7 @@ type TorrentsRepository interface {
ExcludedFiles(hash metainfo.Hash) ([]string, error) ExcludedFiles(hash metainfo.Hash) ([]string, error)
} }
func NewTorrentMetaRepository(metaDir string, storage *FileStorage) (TorrentsRepository, error) { func NewTorrentMetaRepository(metaDir string, storage atstorage.ClientImplCloser) (TorrentsRepository, error) {
excludedFilesStore, err := badgerdb.NewStore(badgerdb.Options{ excludedFilesStore, err := badgerdb.NewStore(badgerdb.Options{
Dir: filepath.Join(metaDir, "excluded-files"), Dir: filepath.Join(metaDir, "excluded-files"),
Codec: encoding.JSON, Codec: encoding.JSON,
@ -38,7 +39,7 @@ func NewTorrentMetaRepository(metaDir string, storage *FileStorage) (TorrentsRep
type torrentRepositoryImpl struct { type torrentRepositoryImpl struct {
m sync.RWMutex m sync.RWMutex
excludedFiles gokv.Store excludedFiles gokv.Store
storage *FileStorage storage atstorage.ClientImplCloser
} }
var ErrNotFound = errors.New("not found") var ErrNotFound = errors.New("not found")
@ -58,10 +59,12 @@ func (r *torrentRepositoryImpl) ExcludeFile(file *torrent.File) error {
} }
excludedFiles = unique(append(excludedFiles, file.Path())) excludedFiles = unique(append(excludedFiles, file.Path()))
err = r.storage.DeleteFile(file) if storage, ok := r.storage.(FileStorageDeleter); ok {
err = storage.DeleteFile(file)
if err != nil { if err != nil {
return err return err
} }
}
return r.excludedFiles.Set(hash.AsString(), excludedFiles) return r.excludedFiles.Set(hash.AsString(), excludedFiles)
} }

View file

@ -9,7 +9,7 @@ import (
"github.com/anacrolix/torrent/storage" "github.com/anacrolix/torrent/storage"
) )
func SetupStorage(cfg config.TorrentClient) (*FileStorage, storage.PieceCompletion, error) { func SetupStorage(cfg config.TorrentClient) (storage.ClientImplCloser, storage.PieceCompletion, error) {
pcp := filepath.Join(cfg.DataFolder, "piece-completion") pcp := filepath.Join(cfg.DataFolder, "piece-completion")
if err := os.MkdirAll(pcp, 0744); err != nil { if err := os.MkdirAll(pcp, 0744); err != nil {
return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err) return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err)
@ -39,13 +39,19 @@ func SetupStorage(cfg config.TorrentClient) (*FileStorage, storage.PieceCompleti
// rp := storage.NewResourcePieces(fc.AsResourceProvider()) // rp := storage.NewResourcePieces(fc.AsResourceProvider())
// st := &stc{rp} // st := &stc{rp}
filesDir := filepath.Join(cfg.DataFolder, "files") // filesDir := filepath.Join(cfg.DataFolder, "files")
if err := os.MkdirAll(pcp, 0744); err != nil { // if err := os.MkdirAll(filesDir, 0744); err != nil {
// return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err)
// }
//st := NewFileStorage(filesDir, pc)
piecesDir := filepath.Join(cfg.DataFolder, "pieces")
if err := os.MkdirAll(piecesDir, 0744); err != nil {
return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err) return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err)
} }
// st := storage.NewMMapWithCompletion(filesDir, pc) st := storage.NewMMapWithCompletion(piecesDir, pc)
st := NewFileStorage(filesDir, pc)
return st, pc, nil return st, pc, nil
} }

View file

@ -17,8 +17,13 @@ import (
"github.com/anacrolix/torrent/storage" "github.com/anacrolix/torrent/storage"
) )
type FileStorageDeleter interface {
storage.ClientImplCloser
DeleteFile(file *torrent.File) error
}
// NewFileStorage creates a new ClientImplCloser that stores files using the OS native filesystem. // NewFileStorage creates a new ClientImplCloser that stores files using the OS native filesystem.
func NewFileStorage(baseDir string, pc storage.PieceCompletion) *FileStorage { func NewFileStorage(baseDir string, pc storage.PieceCompletion) FileStorageDeleter {
return &FileStorage{baseDir: baseDir, pieceCompletion: pc} return &FileStorage{baseDir: baseDir, pieceCompletion: pc}
} }
@ -46,6 +51,13 @@ func (fs *FileStorage) DeleteFile(file *torrent.File) error {
torrentDir := fs.torrentDir(info, infoHash) torrentDir := fs.torrentDir(info, infoHash)
relFilePath := fs.filePath(file.FileInfo()) relFilePath := fs.filePath(file.FileInfo())
filePath := path.Join(torrentDir, relFilePath) filePath := path.Join(torrentDir, relFilePath)
for i := file.BeginPieceIndex(); i < file.EndPieceIndex(); i++ {
pk := metainfo.PieceKey{InfoHash: infoHash, Index: i}
err := fs.pieceCompletion.Set(pk, false)
if err != nil {
return err
}
}
return os.Remove(filePath) return os.Remove(filePath)
} }

View file

@ -204,6 +204,9 @@ func listDirFromFiles[F File](m map[string]F, name string) ([]fs.DirEntry, error
} }
} }
slices.SortStableFunc(out, func(de1, de2 fs.DirEntry) int {
return strings.Compare(de1.Name(), de2.Name())
})
out = slices.CompactFunc(out, func(de1, de2 fs.DirEntry) bool { out = slices.CompactFunc(out, func(de1, de2 fs.DirEntry) bool {
return de1.Name() == de2.Name() return de1.Name() == de2.Name()
}) })

View file

@ -6,6 +6,7 @@ import (
"io/fs" "io/fs"
"path" "path"
"slices" "slices"
"strings"
"sync" "sync"
"time" "time"
@ -54,11 +55,21 @@ func (fs *TorrentFs) files() (map[string]*torrentFile, error) {
fs.filesCache = make(map[string]*torrentFile) fs.filesCache = make(map[string]*torrentFile)
for _, file := range files { for _, file := range files {
if slices.Contains(excludedFiles, file.Path()) { p := file.Path()
if slices.Contains(excludedFiles, p) {
continue
}
if strings.Contains(p, "/.pad/") {
continue continue
} }
p := AbsPath(file.Path()) p = AbsPath(file.Path())
// TODO make optional
// removing the torrent root directory of same name as torrent
p, _ = strings.CutPrefix(p, "/"+fs.t.Name()+"/")
p = AbsPath(p)
fs.filesCache[p] = &torrentFile{ fs.filesCache[p] = &torrentFile{
name: path.Base(p), name: path.Base(p),