- Make Blackhole and Proxy optional - Query all Hashes at once, speeeding up the process - refractor the code a little bit
165 lines
4.3 KiB
Go
165 lines
4.3 KiB
Go
package debrid
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"goBlack/common"
|
|
"goBlack/debrid/structs"
|
|
"log"
|
|
"net/http"
|
|
gourl "net/url"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type RealDebrid struct {
|
|
Host string `json:"host"`
|
|
APIKey string
|
|
DownloadUncached bool
|
|
client *common.RLHTTPClient
|
|
}
|
|
|
|
func (r *RealDebrid) Process(arr *Arr, magnet string) (*Torrent, error) {
|
|
torrent, err := GetTorrentInfo(magnet)
|
|
torrent.Arr = arr
|
|
if err != nil {
|
|
return torrent, err
|
|
}
|
|
log.Printf("Torrent Name: %s", torrent.Name)
|
|
if !r.DownloadUncached {
|
|
if !r.IsAvailable([]string{torrent.InfoHash})[torrent.InfoHash] {
|
|
return torrent, fmt.Errorf("torrent is not cached")
|
|
}
|
|
log.Printf("Torrent: %s is cached", torrent.Name)
|
|
}
|
|
|
|
torrent, err = r.SubmitMagnet(torrent)
|
|
if err != nil || torrent.Id == "" {
|
|
return nil, err
|
|
}
|
|
return r.CheckStatus(torrent)
|
|
}
|
|
|
|
func (r *RealDebrid) IsAvailable(infohashes []string) map[string]bool {
|
|
hashes := strings.Join(infohashes, "/")
|
|
result := make(map[string]bool)
|
|
url := fmt.Sprintf("%s/torrents/instantAvailability/%s", r.Host, hashes)
|
|
resp, err := r.client.MakeRequest(http.MethodGet, url, nil)
|
|
if err != nil {
|
|
log.Println(url)
|
|
log.Println("Error checking availability:", err)
|
|
return result
|
|
}
|
|
var data structs.RealDebridAvailabilityResponse
|
|
err = json.Unmarshal(resp, &data)
|
|
if err != nil {
|
|
log.Println("Error marshalling availability:", err)
|
|
return result
|
|
}
|
|
for _, h := range infohashes {
|
|
hosters, exists := data[strings.ToLower(h)]
|
|
if !exists || len(hosters.Rd) < 1 {
|
|
result[h] = false
|
|
} else {
|
|
result[h] = true
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (r *RealDebrid) SubmitMagnet(torrent *Torrent) (*Torrent, error) {
|
|
url := fmt.Sprintf("%s/torrents/addMagnet", r.Host)
|
|
payload := gourl.Values{
|
|
"magnet": {torrent.Magnet.Link},
|
|
}
|
|
var data structs.RealDebridAddMagnetSchema
|
|
resp, err := r.client.MakeRequest(http.MethodPost, url, strings.NewReader(payload.Encode()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = json.Unmarshal(resp, &data)
|
|
log.Printf("Torrent: %s added with id: %s\n", torrent.Name, data.Id)
|
|
torrent.Id = data.Id
|
|
|
|
return torrent, nil
|
|
}
|
|
|
|
func (r *RealDebrid) CheckStatus(torrent *Torrent) (*Torrent, error) {
|
|
url := fmt.Sprintf("%s/torrents/info/%s", r.Host, torrent.Id)
|
|
for {
|
|
resp, err := r.client.MakeRequest(http.MethodGet, url, nil)
|
|
if err != nil {
|
|
return torrent, err
|
|
}
|
|
var data structs.RealDebridTorrentInfo
|
|
err = json.Unmarshal(resp, &data)
|
|
status := data.Status
|
|
torrent.Folder = common.RemoveExtension(data.OriginalFilename)
|
|
if status == "error" || status == "dead" || status == "magnet_error" {
|
|
return torrent, fmt.Errorf("torrent: %s has error", torrent.Name)
|
|
} else if status == "waiting_files_selection" {
|
|
files := make([]TorrentFile, 0)
|
|
for _, f := range data.Files {
|
|
name := f.Path
|
|
if !common.RegexMatch(common.VIDEOMATCH, name) && !common.RegexMatch(common.SUBMATCH, name) {
|
|
continue
|
|
}
|
|
fileId := f.ID
|
|
file := &TorrentFile{
|
|
Name: name,
|
|
Path: filepath.Join(torrent.Folder, name),
|
|
Size: int64(f.Bytes),
|
|
Id: strconv.Itoa(fileId),
|
|
}
|
|
files = append(files, *file)
|
|
}
|
|
torrent.Files = files
|
|
if len(files) == 0 {
|
|
return torrent, fmt.Errorf("no video files found")
|
|
}
|
|
filesId := make([]string, 0)
|
|
for _, f := range files {
|
|
filesId = append(filesId, f.Id)
|
|
}
|
|
p := gourl.Values{
|
|
"files": {strings.Join(filesId, ",")},
|
|
}
|
|
payload := strings.NewReader(p.Encode())
|
|
_, err = r.client.MakeRequest(http.MethodPost, fmt.Sprintf("%s/torrents/selectFiles/%s", r.Host, torrent.Id), payload)
|
|
if err != nil {
|
|
return torrent, err
|
|
}
|
|
} else if status == "downloaded" {
|
|
log.Printf("Torrent: %s downloaded\n", torrent.Name)
|
|
err = r.DownloadLink(torrent)
|
|
if err != nil {
|
|
return torrent, err
|
|
}
|
|
break
|
|
} else if status == "downloading" {
|
|
return torrent, fmt.Errorf("torrent is uncached")
|
|
}
|
|
|
|
}
|
|
return torrent, nil
|
|
}
|
|
|
|
func (r *RealDebrid) DownloadLink(torrent *Torrent) error {
|
|
return nil
|
|
}
|
|
|
|
func NewRealDebrid(dc common.DebridConfig) *RealDebrid {
|
|
rl := common.ParseRateLimit(dc.RateLimit)
|
|
headers := map[string]string{
|
|
"Authorization": fmt.Sprintf("Bearer %s", dc.APIKey),
|
|
}
|
|
client := common.NewRLHTTPClient(rl, headers)
|
|
return &RealDebrid{
|
|
Host: dc.Host,
|
|
APIKey: dc.APIKey,
|
|
DownloadUncached: dc.DownloadUncached,
|
|
client: client,
|
|
}
|
|
}
|