diff --git a/LICENCE b/LICENSE similarity index 100% rename from LICENCE rename to LICENSE diff --git a/README.md b/README.md index 7db958b..54fcf84 100644 --- a/README.md +++ b/README.md @@ -94,5 +94,4 @@ The documentation includes: Contributions are welcome! Please feel free to submit a Pull Request. ## License - -This project is licensed under the [License Name] - see the LICENSE file for details. \ No newline at end of file +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/internal/utils/magnet.go b/internal/utils/magnet.go index 29a45b9..044b95e 100644 --- a/internal/utils/magnet.go +++ b/internal/utils/magnet.go @@ -25,20 +25,37 @@ type Magnet struct { InfoHash string Size int64 Link string + File []byte +} + +func (m *Magnet) IsTorrent() bool { + return m.File != nil } func GetMagnetFromFile(file io.Reader, filePath string) (*Magnet, error) { + var ( + m *Magnet + err error + ) if filepath.Ext(filePath) == ".torrent" { torrentData, err := io.ReadAll(file) if err != nil { return nil, err } - return GetMagnetFromBytes(torrentData) + m, err = GetMagnetFromBytes(torrentData) + if err != nil { + return nil, err + } } else { // .magnet 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) { @@ -68,6 +85,7 @@ func GetMagnetFromBytes(torrentData []byte) (*Magnet, error) { Name: info.Name, Size: info.Length, Link: mi.Magnet(&hash, &info).String(), + File: torrentData, } return magnet, nil } diff --git a/pkg/debrid/realdebrid/realdebrid.go b/pkg/debrid/realdebrid/realdebrid.go index cc1eb54..63f347e 100644 --- a/pkg/debrid/realdebrid/realdebrid.go +++ b/pkg/debrid/realdebrid/realdebrid.go @@ -1,6 +1,7 @@ package realdebrid import ( + "bytes" "errors" "fmt" "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) { + 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) payload := gourl.Values{ "magnet": {t.Magnet.Link}, diff --git a/pkg/qbit/import.go b/pkg/qbit/import.go index 4b51aa3..3fa6b61 100644 --- a/pkg/qbit/import.go +++ b/pkg/qbit/import.go @@ -12,15 +12,15 @@ import ( ) type ImportRequest struct { - ID string `json:"id"` - Path string `json:"path"` - URI string `json:"uri"` - Arr *arr.Arr `json:"arr"` - IsSymlink bool `json:"isSymlink"` - SeriesId int `json:"series"` - Seasons []int `json:"seasons"` - Episodes []string `json:"episodes"` - DownloadUncached bool `json:"downloadUncached"` + ID string `json:"id"` + Path string `json:"path"` + Magnet *utils.Magnet `json:"magnet"` + Arr *arr.Arr `json:"arr"` + IsSymlink bool `json:"isSymlink"` + SeriesId int `json:"series"` + Seasons []int `json:"seasons"` + Episodes []string `json:"episodes"` + DownloadUncached bool `json:"downloadUncached"` Failed bool `json:"failed"` FailedAt time.Time `json:"failedAt"` @@ -41,10 +41,10 @@ type ManualImportResponseSchema struct { 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{ ID: uuid.NewString(), - URI: uri, + Magnet: magnet, Arr: arr, Failed: false, Completed: false, @@ -69,12 +69,8 @@ func (i *ImportRequest) Process(q *QBit) (err error) { // Use this for now. // This sends the torrent to the arr svc := service.GetService() - magnet, err := utils.GetMagnetFromUrl(i.URI) - if err != nil { - 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) + torrent := createTorrentFromMagnet(i.Magnet, i.Arr.Name, "manual") + debridTorrent, err := debrid.ProcessTorrent(svc.Debrid, i.Magnet, i.Arr, i.IsSymlink, i.DownloadUncached) if err != nil || debridTorrent == nil { if debridTorrent != nil { dbClient := service.GetDebrid().GetByName(debridTorrent.Debrid) diff --git a/pkg/qbit/misc.go b/pkg/qbit/misc.go index 2057b05..20e6dff 100644 --- a/pkg/qbit/misc.go +++ b/pkg/qbit/misc.go @@ -6,7 +6,7 @@ import ( "strings" ) -func CreateTorrentFromMagnet(magnet *utils.Magnet, category, source string) *Torrent { +func createTorrentFromMagnet(magnet *utils.Magnet, category, source string) *Torrent { torrent := &Torrent{ ID: uuid.NewString(), Hash: strings.ToLower(magnet.InfoHash), diff --git a/pkg/qbit/torrent.go b/pkg/qbit/torrent.go index 11970f8..89525d1 100644 --- a/pkg/qbit/torrent.go +++ b/pkg/qbit/torrent.go @@ -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 { svc := service.GetService() - torrent := CreateTorrentFromMagnet(magnet, category, "auto") + torrent := createTorrentFromMagnet(magnet, category, "auto") a, ok := ctx.Value("arr").(*arr.Arr) if !ok { return fmt.Errorf("arr not found in context") diff --git a/pkg/web/server.go b/pkg/web/server.go index 1800a29..e2826ac 100644 --- a/pkg/web/server.go +++ b/pkg/web/server.go @@ -322,9 +322,13 @@ func (ui *Handler) handleAddContent(w http.ResponseWriter, r *http.Request) { } for _, url := range urlList { - importReq := qbit.NewImportRequest(url, _arr, !notSymlink, downloadUncached) - err := importReq.Process(ui.qbit) + magnet, err := utils.GetMagnetFromUrl(url) 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)) continue } @@ -347,7 +351,7 @@ func (ui *Handler) handleAddContent(w http.ResponseWriter, r *http.Request) { continue } - importReq := qbit.NewImportRequest(magnet.Link, _arr, !notSymlink, downloadUncached) + importReq := qbit.NewImportRequest(magnet, _arr, !notSymlink, downloadUncached) err = importReq.Process(ui.qbit) if err != nil { errs = append(errs, fmt.Sprintf("File %s: %v", fileHeader.Filename, err))