Add and remove torrents from web interface (#84)
This commit is contained in:
parent
02842b1917
commit
2f18213660
49 changed files with 996 additions and 1170 deletions
torrent/loader
45
torrent/loader/config.go
Normal file
45
torrent/loader/config.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package loader
|
||||
|
||||
import "github.com/distribyted/distribyted/config"
|
||||
|
||||
var _ Loader = &Config{}
|
||||
|
||||
type Config struct {
|
||||
c []*config.Route
|
||||
}
|
||||
|
||||
func NewConfig(r []*config.Route) *Config {
|
||||
return &Config{
|
||||
c: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Config) ListMagnets() (map[string][]string, error) {
|
||||
out := make(map[string][]string)
|
||||
for _, r := range l.c {
|
||||
for _, t := range r.Torrents {
|
||||
if t.MagnetURI == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
out[r.Name] = append(out[r.Name], t.MagnetURI)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (l *Config) ListTorrentPaths() (map[string][]string, error) {
|
||||
out := make(map[string][]string)
|
||||
for _, r := range l.c {
|
||||
for _, t := range r.Torrents {
|
||||
if t.TorrentPath == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
out[r.Name] = append(out[r.Name], t.TorrentPath)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
107
torrent/loader/db.go
Normal file
107
torrent/loader/db.go
Normal file
|
@ -0,0 +1,107 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
"path"
|
||||
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"github.com/dgraph-io/badger/v3"
|
||||
dlog "github.com/distribyted/distribyted/log"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var _ LoaderAdder = &DB{}
|
||||
|
||||
const routeRootKey = "/route/"
|
||||
|
||||
type DB struct {
|
||||
db *badger.DB
|
||||
}
|
||||
|
||||
func NewDB(path string) (*DB, error) {
|
||||
l := log.Logger.With().Str("component", "torrent-store").Logger()
|
||||
db, err := badger.Open(badger.DefaultOptions(path).WithLogger(&dlog.Badger{L: l}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = db.RunValueLogGC(0.5)
|
||||
if err != nil && err != badger.ErrNoRewrite {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &DB{
|
||||
db: db,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *DB) AddMagnet(r, m string) error {
|
||||
err := l.db.Update(func(txn *badger.Txn) error {
|
||||
spec, err := metainfo.ParseMagnetUri(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ih := spec.InfoHash.HexString()
|
||||
|
||||
rp := path.Join(routeRootKey, ih, r)
|
||||
return txn.Set([]byte(rp), []byte(m))
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return l.db.Sync()
|
||||
}
|
||||
|
||||
func (l *DB) RemoveFromHash(r, h string) (bool, error) {
|
||||
tx := l.db.NewTransaction(true)
|
||||
defer tx.Discard()
|
||||
|
||||
var mh metainfo.Hash
|
||||
if err := mh.FromHexString(h); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
rp := path.Join(routeRootKey, h, r)
|
||||
if _, err := tx.Get([]byte(rp)); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := tx.Delete([]byte(rp)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, tx.Commit()
|
||||
}
|
||||
|
||||
func (l *DB) ListMagnets() (map[string][]string, error) {
|
||||
tx := l.db.NewTransaction(false)
|
||||
defer tx.Discard()
|
||||
|
||||
it := tx.NewIterator(badger.DefaultIteratorOptions)
|
||||
defer it.Close()
|
||||
|
||||
prefix := []byte(routeRootKey)
|
||||
out := make(map[string][]string)
|
||||
for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
|
||||
_, r := path.Split(string(it.Item().Key()))
|
||||
i := it.Item()
|
||||
if err := i.Value(func(v []byte) error {
|
||||
out[r] = append(out[r], string(v))
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (l *DB) ListTorrentPaths() (map[string][]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (l *DB) Close() error {
|
||||
return l.db.Close()
|
||||
}
|
62
torrent/loader/db_test.go
Normal file
62
torrent/loader/db_test.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/anacrolix/torrent/storage"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const m1 = "magnet:?xt=urn:btih:c9e15763f722f23e98a29decdfae341b98d53056"
|
||||
|
||||
func TestDB(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
tmpService, err := os.MkdirTemp("", "service")
|
||||
require.NoError(err)
|
||||
tmpStorage, err := os.MkdirTemp("", "storage")
|
||||
require.NoError(err)
|
||||
|
||||
cs := storage.NewFile(tmpStorage)
|
||||
defer cs.Close()
|
||||
|
||||
s, err := NewDB(tmpService)
|
||||
require.NoError(err)
|
||||
defer s.Close()
|
||||
|
||||
err = s.AddMagnet("route1", "WRONG MAGNET")
|
||||
require.Error(err)
|
||||
|
||||
err = s.AddMagnet("route1", m1)
|
||||
require.NoError(err)
|
||||
|
||||
err = s.AddMagnet("route2", m1)
|
||||
require.NoError(err)
|
||||
|
||||
l, err := s.ListMagnets()
|
||||
require.NoError(err)
|
||||
require.Len(l, 2)
|
||||
require.Len(l["route1"], 1)
|
||||
require.Equal(l["route1"][0], m1)
|
||||
require.Len(l["route2"], 1)
|
||||
require.Equal(l["route2"][0], m1)
|
||||
|
||||
removed, err := s.RemoveFromHash("other", "c9e15763f722f23e98a29decdfae341b98d53056")
|
||||
require.NoError(err)
|
||||
require.False(removed)
|
||||
|
||||
removed, err = s.RemoveFromHash("route1", "c9e15763f722f23e98a29decdfae341b98d53056")
|
||||
require.NoError(err)
|
||||
require.True(removed)
|
||||
|
||||
l, err = s.ListMagnets()
|
||||
require.NoError(err)
|
||||
require.Len(l, 1)
|
||||
require.Len(l["route2"], 1)
|
||||
require.Equal(l["route2"][0], m1)
|
||||
|
||||
require.NoError(s.Close())
|
||||
require.NoError(cs.Close())
|
||||
|
||||
}
|
13
torrent/loader/loader.go
Normal file
13
torrent/loader/loader.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package loader
|
||||
|
||||
type Loader interface {
|
||||
ListMagnets() (map[string][]string, error)
|
||||
ListTorrentPaths() (map[string][]string, error)
|
||||
}
|
||||
|
||||
type LoaderAdder interface {
|
||||
Loader
|
||||
|
||||
RemoveFromHash(r, h string) (bool, error)
|
||||
AddMagnet(r, m string) error
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue