feat: self calculate required torrent hash

This commit is contained in:
Simon Ding
2024-10-10 09:01:51 +08:00
parent 37ad1391db
commit 19f21ddd6e
5 changed files with 47 additions and 77 deletions

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"polaris/pkg" "polaris/pkg"
"polaris/pkg/go-qbittorrent/qbt" "polaris/pkg/go-qbittorrent/qbt"
"time" "polaris/pkg/utils"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -39,14 +39,14 @@ func NewClient(url, user, pass string) (*Client, error) {
} }
func (c *Client) GetAll() ([]pkg.Torrent, error) { func (c *Client) GetAll() ([]pkg.Torrent, error) {
tt, err :=c.c.Torrents(qbt.TorrentsOptions{}) tt, err := c.c.Torrents(qbt.TorrentsOptions{})
if err != nil { if err != nil {
return nil, errors.Wrap(err, "get torrents") return nil, errors.Wrap(err, "get torrents")
} }
var res []pkg.Torrent var res []pkg.Torrent
for _, t := range tt { for _, t := range tt {
t1 := &Torrent{ t1 := &Torrent{
c: c.c, c: c.c,
Hash: t.Hash, Hash: t.Hash,
Info: c.Info, Info: c.Info,
} }
@@ -56,40 +56,15 @@ func (c *Client) GetAll() ([]pkg.Torrent, error) {
} }
func (c *Client) Download(link, dir string) (pkg.Torrent, error) { func (c *Client) Download(link, dir string) (pkg.Torrent, error) {
all, err := c.c.Torrents(qbt.TorrentsOptions{}) hash, err := utils.MagnetHash(link)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "get old torrents") return nil, errors.Wrap(err, "get hash")
}
allHash := make(map[string]bool, len(all))
for _, t := range all {
allHash[t.Hash] = true
} }
err = c.c.DownloadLinks([]string{link}, qbt.DownloadOptions{Savepath: &dir}) err = c.c.DownloadLinks([]string{link}, qbt.DownloadOptions{Savepath: &dir})
if err != nil { if err != nil {
return nil, errors.Wrap(err, "qbt download") return nil, errors.Wrap(err, "qbt download")
} }
var newHash string return &Torrent{Hash: hash, c: c.c, Info: c.Info}, nil
loop:
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
all, err = c.c.Torrents(qbt.TorrentsOptions{})
if err != nil {
return nil, errors.Wrap(err, "get new torrents")
}
for _, t := range all {
if !allHash[t.Hash] {
newHash = t.Hash
break loop
}
}
}
if newHash == "" {
return nil, fmt.Errorf("download torrent fail: timeout")
}
return &Torrent{Hash: newHash, c: c.c, Info: c.Info}, nil
} }

View File

@@ -9,6 +9,7 @@ import (
"net/url" "net/url"
"polaris/db" "polaris/db"
"polaris/log" "polaris/log"
"polaris/pkg/utils"
"slices" "slices"
"strconv" "strconv"
"time" "time"
@@ -80,9 +81,14 @@ func (r *Response) ToResults(indexer *db.TorznabInfo) []Result {
if slices.Contains(item.Category, "3000") { //exclude audio files if slices.Contains(item.Category, "3000") { //exclude audio files
continue continue
} }
link, err := utils.Link2Magnet(item.Link)
if err != nil {
log.Warnf("converting link to magnet error, error: %v, link: %v", err, item.Link)
continue
}
r := Result{ r := Result{
Name: item.Title, Name: item.Title,
Link: item.Link, Link: link,
Size: mustAtoI(item.Size), Size: mustAtoI(item.Size),
Seeders: mustAtoI(item.GetAttr("seeders")), Seeders: mustAtoI(item.GetAttr("seeders")),
Peers: mustAtoI(item.GetAttr("peers")), Peers: mustAtoI(item.GetAttr("peers")),

View File

@@ -4,11 +4,10 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http"
"net/url" "net/url"
"polaris/log" "polaris/log"
"polaris/pkg" "polaris/pkg"
"strings" "polaris/pkg/utils"
"github.com/hekmon/transmissionrpc/v3" "github.com/hekmon/transmissionrpc/v3"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -54,7 +53,7 @@ func (c *Client) GetAll() ([]pkg.Torrent, error) {
var torrents []pkg.Torrent var torrents []pkg.Torrent
for _, t := range all { for _, t := range all {
torrents = append(torrents, &Torrent{ torrents = append(torrents, &Torrent{
Hash: *t.HashString, Hash: *t.HashString,
c: c.c, c: c.c,
Config: c.cfg, Config: c.cfg,
}) })
@@ -63,36 +62,19 @@ func (c *Client) GetAll() ([]pkg.Torrent, error) {
} }
func (c *Client) Download(link, dir string) (pkg.Torrent, error) { func (c *Client) Download(link, dir string) (pkg.Torrent, error) {
if strings.HasPrefix(link, "http") { hash, err := utils.MagnetHash(link)
client := &http.Client{ if err != nil {
CheckRedirect: func(req *http.Request, via []*http.Request) error { return nil, errors.Wrap(err, "get hash")
return http.ErrUseLastResponse
},
}
resp, err:=client.Get(link)
if err == nil {
if resp.StatusCode == http.StatusFound {
loc, err := resp.Location()
if err == nil {
link = loc.String()
log.Warnf("transimision redirect to url: %v", link)
}
}
}
} }
t, err := c.c.TorrentAdd(context.TODO(), transmissionrpc.TorrentAddPayload{ t, err := c.c.TorrentAdd(context.TODO(), transmissionrpc.TorrentAddPayload{
Filename: &link, Filename: &link,
DownloadDir: &dir, DownloadDir: &dir,
}) })
log.Infof("get torrent info: %+v", t) log.Debugf("get torrent info: %+v", t)
if t.HashString == nil {
return nil, fmt.Errorf("download torrent error: %v", link)
}
return &Torrent{ return &Torrent{
Hash: *t.HashString, Hash: hash,
c: c.c, c: c.c,
Config: c.cfg, Config: c.cfg,
}, err }, err
@@ -100,7 +82,7 @@ func (c *Client) Download(link, dir string) (pkg.Torrent, error) {
type Torrent struct { type Torrent struct {
//t *transmissionrpc.Torrent //t *transmissionrpc.Torrent
c *transmissionrpc.Client c *transmissionrpc.Client
Hash string `json:"hash"` Hash string `json:"hash"`
Config Config
} }
@@ -136,7 +118,6 @@ func (t *Torrent) Exists() bool {
return len(r) > 0 return len(r) > 0
} }
func (t *Torrent) Name() (string, error) { func (t *Torrent) Name() (string, error) {
tt, err := t.getTorrent() tt, err := t.getTorrent()
if err != nil { if err != nil {

View File

@@ -251,3 +251,24 @@ func Link2Magnet(link string) (string, error) {
} }
return mg.String(), nil return mg.String(), nil
} }
func MagnetHash(link string) (string, error) {
if mi, err := metainfo.ParseMagnetV2Uri(link); err != nil {
return "", errors.Errorf("magnet link is not valid: %v", err)
} else {
hash := ""
if mi.InfoHash.Unwrap().HexString() != "" {
hash = mi.InfoHash.Unwrap().HexString()
} else {
btmh := mi.V2InfoHash.Unwrap()
if btmh.HexString() != "" {
hash = btmh.HexString()
}
}
if hash == "" {
return "", errors.Errorf("magnet has no info hash: %v", link)
}
return hash, nil
}
}

View File

@@ -11,7 +11,6 @@ import (
"polaris/pkg/utils" "polaris/pkg/utils"
"strconv" "strconv"
"github.com/anacrolix/torrent/metainfo"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -123,21 +122,9 @@ func (s *Server) addTorrent2Blacklist(link string) error {
if link == "" { if link == "" {
return nil return nil
} }
if mi, err := metainfo.ParseMagnetV2Uri(link); err != nil { if hash, err := utils.MagnetHash(link); err != nil {
return errors.Errorf("magnet link is not valid: %v", err) return err
} else { } else {
hash := ""
if mi.InfoHash.Unwrap().HexString() != "" {
hash = mi.InfoHash.Unwrap().HexString()
} else {
btmh := mi.V2InfoHash.Unwrap()
if btmh.HexString() != "" {
hash = btmh.HexString()
}
}
if hash == "" {
return errors.Errorf("magnet has no info hash: %v", link)
}
item := ent.Blacklist{ item := ent.Blacklist{
Type: blacklist.TypeTorrent, Type: blacklist.TypeTorrent,
Value: schema.BlacklistValue{ Value: schema.BlacklistValue{