Add support for adding torrent file
This commit is contained in:
@@ -94,5 +94,4 @@ The documentation includes:
|
|||||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
||||||
This project is licensed under the [License Name] - see the LICENSE file for details.
|
|
||||||
@@ -25,21 +25,38 @@ type Magnet struct {
|
|||||||
InfoHash string
|
InfoHash string
|
||||||
Size int64
|
Size int64
|
||||||
Link string
|
Link string
|
||||||
|
File []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Magnet) IsTorrent() bool {
|
||||||
|
return m.File != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMagnetFromFile(file io.Reader, filePath string) (*Magnet, error) {
|
func GetMagnetFromFile(file io.Reader, filePath string) (*Magnet, error) {
|
||||||
|
var (
|
||||||
|
m *Magnet
|
||||||
|
err error
|
||||||
|
)
|
||||||
if filepath.Ext(filePath) == ".torrent" {
|
if filepath.Ext(filePath) == ".torrent" {
|
||||||
torrentData, err := io.ReadAll(file)
|
torrentData, err := io.ReadAll(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return GetMagnetFromBytes(torrentData)
|
m, err = GetMagnetFromBytes(torrentData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// .magnet file
|
// .magnet file
|
||||||
magnetLink := ReadMagnetFile(file)
|
magnetLink := ReadMagnetFile(file)
|
||||||
return GetMagnetInfo(magnetLink)
|
m, err = GetMagnetInfo(magnetLink)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m.Name = strings.TrimSuffix(filePath, filepath.Ext(filePath))
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetMagnetFromUrl(url string) (*Magnet, error) {
|
func GetMagnetFromUrl(url string) (*Magnet, error) {
|
||||||
if strings.HasPrefix(url, "magnet:") {
|
if strings.HasPrefix(url, "magnet:") {
|
||||||
@@ -68,6 +85,7 @@ func GetMagnetFromBytes(torrentData []byte) (*Magnet, error) {
|
|||||||
Name: info.Name,
|
Name: info.Name,
|
||||||
Size: info.Length,
|
Size: info.Length,
|
||||||
Link: mi.Magnet(&hash, &info).String(),
|
Link: mi.Magnet(&hash, &info).String(),
|
||||||
|
File: torrentData,
|
||||||
}
|
}
|
||||||
return magnet, nil
|
return magnet, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package realdebrid
|
package realdebrid
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
@@ -211,6 +212,35 @@ func (r *RealDebrid) IsAvailable(hashes []string) map[string]bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RealDebrid) SubmitMagnet(t *types.Torrent) (*types.Torrent, error) {
|
func (r *RealDebrid) SubmitMagnet(t *types.Torrent) (*types.Torrent, error) {
|
||||||
|
if t.Magnet.IsTorrent() {
|
||||||
|
return r.addTorrent(t)
|
||||||
|
}
|
||||||
|
return r.addMagnet(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RealDebrid) addTorrent(t *types.Torrent) (*types.Torrent, error) {
|
||||||
|
url := fmt.Sprintf("%s/torrents/addTorrent", r.Host)
|
||||||
|
var data AddMagnetSchema
|
||||||
|
req, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(t.Magnet.File))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Type", "application/x-bittorrent")
|
||||||
|
resp, err := r.client.MakeRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(resp, &data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
t.Id = data.Id
|
||||||
|
t.Debrid = r.Name
|
||||||
|
t.MountPath = r.MountPath
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RealDebrid) addMagnet(t *types.Torrent) (*types.Torrent, error) {
|
||||||
url := fmt.Sprintf("%s/torrents/addMagnet", r.Host)
|
url := fmt.Sprintf("%s/torrents/addMagnet", r.Host)
|
||||||
payload := gourl.Values{
|
payload := gourl.Values{
|
||||||
"magnet": {t.Magnet.Link},
|
"magnet": {t.Magnet.Link},
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
type ImportRequest struct {
|
type ImportRequest struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
URI string `json:"uri"`
|
Magnet *utils.Magnet `json:"magnet"`
|
||||||
Arr *arr.Arr `json:"arr"`
|
Arr *arr.Arr `json:"arr"`
|
||||||
IsSymlink bool `json:"isSymlink"`
|
IsSymlink bool `json:"isSymlink"`
|
||||||
SeriesId int `json:"series"`
|
SeriesId int `json:"series"`
|
||||||
@@ -41,10 +41,10 @@ type ManualImportResponseSchema struct {
|
|||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImportRequest(uri string, arr *arr.Arr, isSymlink, downloadUncached bool) *ImportRequest {
|
func NewImportRequest(magnet *utils.Magnet, arr *arr.Arr, isSymlink, downloadUncached bool) *ImportRequest {
|
||||||
return &ImportRequest{
|
return &ImportRequest{
|
||||||
ID: uuid.NewString(),
|
ID: uuid.NewString(),
|
||||||
URI: uri,
|
Magnet: magnet,
|
||||||
Arr: arr,
|
Arr: arr,
|
||||||
Failed: false,
|
Failed: false,
|
||||||
Completed: false,
|
Completed: false,
|
||||||
@@ -69,12 +69,8 @@ func (i *ImportRequest) Process(q *QBit) (err error) {
|
|||||||
// Use this for now.
|
// Use this for now.
|
||||||
// This sends the torrent to the arr
|
// This sends the torrent to the arr
|
||||||
svc := service.GetService()
|
svc := service.GetService()
|
||||||
magnet, err := utils.GetMagnetFromUrl(i.URI)
|
torrent := createTorrentFromMagnet(i.Magnet, i.Arr.Name, "manual")
|
||||||
if err != nil {
|
debridTorrent, err := debrid.ProcessTorrent(svc.Debrid, i.Magnet, i.Arr, i.IsSymlink, i.DownloadUncached)
|
||||||
return fmt.Errorf("error parsing magnet link: %w", err)
|
|
||||||
}
|
|
||||||
torrent := CreateTorrentFromMagnet(magnet, i.Arr.Name, "manual")
|
|
||||||
debridTorrent, err := debrid.ProcessTorrent(svc.Debrid, magnet, i.Arr, i.IsSymlink, i.DownloadUncached)
|
|
||||||
if err != nil || debridTorrent == nil {
|
if err != nil || debridTorrent == nil {
|
||||||
if debridTorrent != nil {
|
if debridTorrent != nil {
|
||||||
dbClient := service.GetDebrid().GetByName(debridTorrent.Debrid)
|
dbClient := service.GetDebrid().GetByName(debridTorrent.Debrid)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateTorrentFromMagnet(magnet *utils.Magnet, category, source string) *Torrent {
|
func createTorrentFromMagnet(magnet *utils.Magnet, category, source string) *Torrent {
|
||||||
torrent := &Torrent{
|
torrent := &Torrent{
|
||||||
ID: uuid.NewString(),
|
ID: uuid.NewString(),
|
||||||
Hash: strings.ToLower(magnet.InfoHash),
|
Hash: strings.ToLower(magnet.InfoHash),
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (q *QBit) AddTorrent(ctx context.Context, fileHeader *multipart.FileHeader,
|
|||||||
|
|
||||||
func (q *QBit) Process(ctx context.Context, magnet *utils.Magnet, category string) error {
|
func (q *QBit) Process(ctx context.Context, magnet *utils.Magnet, category string) error {
|
||||||
svc := service.GetService()
|
svc := service.GetService()
|
||||||
torrent := CreateTorrentFromMagnet(magnet, category, "auto")
|
torrent := createTorrentFromMagnet(magnet, category, "auto")
|
||||||
a, ok := ctx.Value("arr").(*arr.Arr)
|
a, ok := ctx.Value("arr").(*arr.Arr)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("arr not found in context")
|
return fmt.Errorf("arr not found in context")
|
||||||
|
|||||||
@@ -322,9 +322,13 @@ func (ui *Handler) handleAddContent(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, url := range urlList {
|
for _, url := range urlList {
|
||||||
importReq := qbit.NewImportRequest(url, _arr, !notSymlink, downloadUncached)
|
magnet, err := utils.GetMagnetFromUrl(url)
|
||||||
err := importReq.Process(ui.qbit)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("Failed to parse URL %s: %v", url, err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
importReq := qbit.NewImportRequest(magnet, _arr, !notSymlink, downloadUncached)
|
||||||
|
if err := importReq.Process(ui.qbit); err != nil {
|
||||||
errs = append(errs, fmt.Sprintf("URL %s: %v", url, err))
|
errs = append(errs, fmt.Sprintf("URL %s: %v", url, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -347,7 +351,7 @@ func (ui *Handler) handleAddContent(w http.ResponseWriter, r *http.Request) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
importReq := qbit.NewImportRequest(magnet.Link, _arr, !notSymlink, downloadUncached)
|
importReq := qbit.NewImportRequest(magnet, _arr, !notSymlink, downloadUncached)
|
||||||
err = importReq.Process(ui.qbit)
|
err = importReq.Process(ui.qbit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Sprintf("File %s: %v", fileHeader.Filename, err))
|
errs = append(errs, fmt.Sprintf("File %s: %v", fileHeader.Filename, err))
|
||||||
|
|||||||
Reference in New Issue
Block a user