Random Fixes:
- Fix uncached error - Fix naming and race conditions
This commit is contained in:
@@ -15,25 +15,29 @@ type DebridConfig struct {
|
|||||||
RateLimit string `json:"rate_limit"` // 200/minute or 10/second
|
RateLimit string `json:"rate_limit"` // 200/minute or 10/second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProxyConfig struct {
|
||||||
|
Port string `json:"port"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
Debug bool `json:"debug"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
CachedOnly *bool `json:"cached_only"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QBitTorrentConfig struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Port string `json:"port"`
|
||||||
|
Debug bool `json:"debug"`
|
||||||
|
DownloadFolder string `json:"download_folder"`
|
||||||
|
Categories []string `json:"categories"`
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Debrid DebridConfig `json:"debrid"`
|
Debrid DebridConfig `json:"debrid"`
|
||||||
Proxy struct {
|
Proxy ProxyConfig `json:"proxy"`
|
||||||
Port string `json:"port"`
|
MaxCacheSize int `json:"max_cache_size"`
|
||||||
Enabled bool `json:"enabled"`
|
QBitTorrent QBitTorrentConfig `json:"qbittorrent"`
|
||||||
Debug bool `json:"debug"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
CachedOnly *bool `json:"cached_only"`
|
|
||||||
}
|
|
||||||
MaxCacheSize int `json:"max_cache_size"`
|
|
||||||
QBitTorrent struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Port string `json:"port"`
|
|
||||||
Debug bool `json:"debug"`
|
|
||||||
DownloadFolder string `json:"download_folder"`
|
|
||||||
Categories []string `json:"categories"`
|
|
||||||
} `json:"qbittorrent"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig(path string) (*Config, error) {
|
func LoadConfig(path string) (*Config, error) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
VIDEOMATCH = "(?i)(\\.)(YUV|WMV|WEBM|VOB|VIV|SVI|ROQ|RMVB|RM|OGV|OGG|NSV|MXF|MTS|M2TS|TS|MPG|MPEG|M2V|MP2|MPE|MPV|MP4|M4P|M4V|MOV|QT|MNG|MKV|FLV|DRC|AVI|ASF|AMV|MKA|F4V|3GP|3G2|DIVX|X264|X265)$"
|
VIDEOMATCH = "(?i)(\\.)(YUV|WMV|WEBM|VOB|VIV|SVI|ROQ|RMVB|RM|OGV|OGG|NSV|MXF|MPG|MPEG|M2V|MP2|MPE|MPV|MP4|M4P|M4V|MOV|QT|MNG|MKV|FLV|DRC|AVI|ASF|AMV|MKA|F4V|3GP|3G2|DIVX|X264|X265)$"
|
||||||
SUBMATCH = "(?i)(\\.)(SRT|SUB|SBV|ASS|VTT|TTML|DFXP|STL|SCC|CAP|SMI|TTXT|TDS|USF|JSS|SSA|PSB|RT|LRC|SSB)$"
|
SUBMATCH = "(?i)(\\.)(SRT|SUB|SBV|ASS|VTT|TTML|DFXP|STL|SCC|CAP|SMI|TTXT|TDS|USF|JSS|SSA|PSB|RT|LRC|SSB)$"
|
||||||
SAMPLEMATCH = `(?i)(^|[\\/]|[._-])(sample|trailer|thumb)s?([._-]|$)`
|
SAMPLEMATCH = `(?i)(^|[\\/]|[._-])(sample|trailer|thumb)s?([._-]|$)`
|
||||||
)
|
)
|
||||||
@@ -16,8 +16,7 @@ func RegexMatch(regex string, value string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RemoveExtension(value string) string {
|
func RemoveExtension(value string) string {
|
||||||
pattern := "(?i)(\\.)(YUV|WMV|WEBM|VOB|VIV|SVI|ROQ|RMVB|RM|OGV|OGG|NSV|MXF|MTS|M2TS|TS|MPG|MPEG|M2V|MP2|MPE|MPV|MP4|M4P|M4V|MOV|QT|MNG|MKV|FLV|DRC|AVI|ASF|AMV|MKA|F4V|3GP|3G2|DIVX|X264|X265)$"
|
re := regexp.MustCompile(VIDEOMATCH)
|
||||||
re := regexp.MustCompile(pattern)
|
|
||||||
|
|
||||||
// Find the last index of the matched extension
|
// Find the last index of the matched extension
|
||||||
loc := re.FindStringIndex(value)
|
loc := re.FindStringIndex(value)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Magnet struct {
|
type Magnet struct {
|
||||||
@@ -211,3 +213,44 @@ func NewLogger(prefix string, output *os.File) *log.Logger {
|
|||||||
f := fmt.Sprintf("[%s] ", prefix)
|
f := fmt.Sprintf("[%s] ", prefix)
|
||||||
return log.New(output, f, log.LstdFlags)
|
return log.New(output, f, log.LstdFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetInfohashFromURL(url string) (string, error) {
|
||||||
|
// Download the torrent file
|
||||||
|
var magnetLink string
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||||
|
if len(via) >= 3 {
|
||||||
|
return fmt.Errorf("stopped after 3 redirects")
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(req.URL.String(), "magnet:") {
|
||||||
|
// Stop the redirect chain
|
||||||
|
magnetLink = req.URL.String()
|
||||||
|
return http.ErrUseLastResponse
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if magnetLink != "" {
|
||||||
|
return ExtractInfoHash(magnetLink), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := metainfo.Load(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
hash := mi.HashInfoBytes()
|
||||||
|
infoHash := hash.HexString()
|
||||||
|
return infoHash, nil
|
||||||
|
}
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -6,8 +6,8 @@ require (
|
|||||||
github.com/anacrolix/torrent v1.55.0
|
github.com/anacrolix/torrent v1.55.0
|
||||||
github.com/elazarl/goproxy v0.0.0-20240726154733-8b0c20506380
|
github.com/elazarl/goproxy v0.0.0-20240726154733-8b0c20506380
|
||||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2
|
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2
|
||||||
github.com/fsnotify/fsnotify v1.7.0
|
|
||||||
github.com/go-chi/chi/v5 v5.1.0
|
github.com/go-chi/chi/v5 v5.1.0
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
github.com/valyala/fastjson v1.6.4
|
github.com/valyala/fastjson v1.6.4
|
||||||
golang.org/x/time v0.6.0
|
golang.org/x/time v0.6.0
|
||||||
)
|
)
|
||||||
@@ -17,9 +17,7 @@ require (
|
|||||||
github.com/anacrolix/missinggo/v2 v2.7.3 // indirect
|
github.com/anacrolix/missinggo/v2 v2.7.3 // indirect
|
||||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
|
||||||
github.com/huandu/xstrings v1.3.2 // indirect
|
github.com/huandu/xstrings v1.3.2 // indirect
|
||||||
golang.org/x/net v0.27.0 // indirect
|
golang.org/x/net v0.27.0 // indirect
|
||||||
golang.org/x/sys v0.22.0 // indirect
|
|
||||||
golang.org/x/text v0.16.0 // indirect
|
golang.org/x/text v0.16.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -62,8 +62,6 @@ github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8
|
|||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||||
@@ -233,8 +231,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ type Service interface {
|
|||||||
SubmitMagnet(torrent *Torrent) (*Torrent, error)
|
SubmitMagnet(torrent *Torrent) (*Torrent, error)
|
||||||
CheckStatus(torrent *Torrent) (*Torrent, error)
|
CheckStatus(torrent *Torrent) (*Torrent, error)
|
||||||
DownloadLink(torrent *Torrent) error
|
DownloadLink(torrent *Torrent) error
|
||||||
Process(arr *Arr, magnet string) (*Torrent, error)
|
|
||||||
IsAvailable(infohashes []string) map[string]bool
|
IsAvailable(infohashes []string) map[string]bool
|
||||||
GetMountPath() string
|
GetMountPath() string
|
||||||
GetDownloadUncached() bool
|
GetDownloadUncached() bool
|
||||||
@@ -132,17 +131,19 @@ func ProcessQBitTorrent(d Service, magnet *common.Magnet, category string) (*Tor
|
|||||||
Size: magnet.Size,
|
Size: magnet.Size,
|
||||||
}
|
}
|
||||||
logger := d.GetLogger()
|
logger := d.GetLogger()
|
||||||
logger.Printf("Torrent Name: %s", debridTorrent.Name)
|
logger.Printf("Torrent Hash: %s", debridTorrent.InfoHash)
|
||||||
if !d.GetDownloadUncached() {
|
if !d.GetDownloadUncached() {
|
||||||
hash, exists := d.IsAvailable([]string{debridTorrent.InfoHash})[debridTorrent.InfoHash]
|
hash, exists := d.IsAvailable([]string{debridTorrent.InfoHash})[debridTorrent.InfoHash]
|
||||||
if !exists || !hash {
|
if !exists || !hash {
|
||||||
return debridTorrent, fmt.Errorf("torrent is not cached")
|
return debridTorrent, fmt.Errorf("torrent: %s is not cached", debridTorrent.Name)
|
||||||
|
} else {
|
||||||
|
logger.Printf("Torrent: %s is cached", debridTorrent.Name)
|
||||||
}
|
}
|
||||||
logger.Printf("Torrent: %s is cached", debridTorrent.Name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debridTorrent, err := d.SubmitMagnet(debridTorrent)
|
debridTorrent, err := d.SubmitMagnet(debridTorrent)
|
||||||
if err != nil || debridTorrent.Id == "" {
|
if err != nil || debridTorrent.Id == "" {
|
||||||
|
logger.Printf("Error submitting magnet: %s", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return d.CheckStatus(debridTorrent)
|
return d.CheckStatus(debridTorrent)
|
||||||
|
|||||||
@@ -55,28 +55,6 @@ func GetTorrentFiles(data structs.RealDebridTorrentInfo) []TorrentFile {
|
|||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|
||||||
hash, exists := r.IsAvailable([]string{torrent.InfoHash})[torrent.InfoHash]
|
|
||||||
if !exists || !hash {
|
|
||||||
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 {
|
func (r *RealDebrid) IsAvailable(infohashes []string) map[string]bool {
|
||||||
// Check if the infohashes are available in the local cache
|
// Check if the infohashes are available in the local cache
|
||||||
hashes, result := GetLocalCache(infohashes, r.cache)
|
hashes, result := GetLocalCache(infohashes, r.cache)
|
||||||
@@ -183,7 +161,9 @@ func (r *RealDebrid) CheckStatus(torrent *Torrent) (*Torrent, error) {
|
|||||||
var data structs.RealDebridTorrentInfo
|
var data structs.RealDebridTorrentInfo
|
||||||
err = json.Unmarshal(resp, &data)
|
err = json.Unmarshal(resp, &data)
|
||||||
status := data.Status
|
status := data.Status
|
||||||
torrent.Folder = common.RemoveExtension(data.OriginalFilename)
|
name := common.RemoveExtension(data.OriginalFilename)
|
||||||
|
torrent.Name = name // Important because some magnet changes the name
|
||||||
|
torrent.Folder = name
|
||||||
torrent.Bytes = data.Bytes
|
torrent.Bytes = data.Bytes
|
||||||
torrent.Progress = data.Progress
|
torrent.Progress = data.Progress
|
||||||
torrent.Speed = data.Speed
|
torrent.Speed = data.Speed
|
||||||
|
|||||||
@@ -217,6 +217,13 @@ func (item Item) getHash() string {
|
|||||||
//if err == nil && magnet != nil && magnet.InfoHash != "" {
|
//if err == nil && magnet != nil && magnet.InfoHash != "" {
|
||||||
// log.Printf("Magnet: %s", magnet.InfoHash)
|
// log.Printf("Magnet: %s", magnet.InfoHash)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
if strings.Contains(magnetLink, "http") {
|
||||||
|
h, _ := common.GetInfohashFromURL(magnetLink)
|
||||||
|
if h != "" {
|
||||||
|
infohash = h
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return infohash
|
return infohash
|
||||||
|
|
||||||
@@ -249,7 +256,6 @@ func (p *Proxy) ProcessXMLResponse(resp *http.Response) *http.Response {
|
|||||||
if len(rss.Channel.Items) > 0 {
|
if len(rss.Channel.Items) > 0 {
|
||||||
indexer = rss.Channel.Items[0].ProwlarrIndexer.Text
|
indexer = rss.Channel.Items[0].ProwlarrIndexer.Text
|
||||||
} else {
|
} else {
|
||||||
p.logger.Println("No items found in RSS feed")
|
|
||||||
resp.Body = io.NopCloser(bytes.NewReader(body))
|
resp.Body = io.NopCloser(bytes.NewReader(body))
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
@@ -283,6 +289,8 @@ func (p *Proxy) ProcessXMLResponse(resp *http.Response) *http.Response {
|
|||||||
p.logger.Printf("[%s Report]: %d/%d items are cached || Found %d infohash", indexer, len(newItems), len(rss.Channel.Items), len(hashes))
|
p.logger.Printf("[%s Report]: %d/%d items are cached || Found %d infohash", indexer, len(newItems), len(rss.Channel.Items), len(hashes))
|
||||||
} else {
|
} else {
|
||||||
// This will prevent the indexer from being disabled by the arr
|
// This will prevent the indexer from being disabled by the arr
|
||||||
|
//filename := common.RandomString(10) + ".xml"
|
||||||
|
//_ = os.WriteFile(filename, body, 0644)
|
||||||
p.logger.Printf("[%s Report]: No Items are cached; Return only first item with [UnCached]", indexer)
|
p.logger.Printf("[%s Report]: No Items are cached; Return only first item with [UnCached]", indexer)
|
||||||
item := rss.Channel.Items[0]
|
item := rss.Channel.Items[0]
|
||||||
item.Title = fmt.Sprintf("%s [UnCached]", item.Title)
|
item.Title = fmt.Sprintf("%s [UnCached]", item.Title)
|
||||||
|
|||||||
@@ -37,15 +37,9 @@ func (q *QBit) handleTorrentsAdd(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
files := r.MultipartForm.File["torrents"]
|
|
||||||
urls := r.FormValue("urls")
|
urls := r.FormValue("urls")
|
||||||
category := r.FormValue("category")
|
category := r.FormValue("category")
|
||||||
|
|
||||||
if len(files) == 0 && urls == "" {
|
|
||||||
http.Error(w, "No torrent provided", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var urlList []string
|
var urlList []string
|
||||||
if urls != "" {
|
if urls != "" {
|
||||||
urlList = strings.Split(urls, "\n")
|
urlList = strings.Split(urls, "\n")
|
||||||
@@ -62,18 +56,22 @@ func (q *QBit) handleTorrentsAdd(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fileHeader := range files {
|
if contentType == "multipart/form-data" {
|
||||||
file, _ := fileHeader.Open()
|
files := r.MultipartForm.File["torrents"]
|
||||||
defer file.Close()
|
for _, fileHeader := range files {
|
||||||
var reader io.Reader = file
|
file, _ := fileHeader.Open()
|
||||||
magnet, err := common.GetMagnetFromFile(reader, fileHeader.Filename)
|
defer file.Close()
|
||||||
if err != nil {
|
var reader io.Reader = file
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
magnet, err := common.GetMagnetFromFile(reader, fileHeader.Filename)
|
||||||
q.logger.Printf("Error reading file: %s", fileHeader.Filename)
|
if err != nil {
|
||||||
return
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
q.logger.Printf("Error reading file: %s", fileHeader.Filename)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go q.Process(magnet, category)
|
||||||
}
|
}
|
||||||
go q.Process(magnet, category)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,14 @@ func (q *QBit) Process(magnet *common.Magnet, category string) (*Torrent, error)
|
|||||||
debridTorrent, err := debrid.ProcessQBitTorrent(q.debrid, magnet, category)
|
debridTorrent, err := debrid.ProcessQBitTorrent(q.debrid, magnet, category)
|
||||||
if err != nil || debridTorrent == nil {
|
if err != nil || debridTorrent == nil {
|
||||||
// Mark as failed
|
// Mark as failed
|
||||||
|
q.logger.Printf("Failed to process torrent: %s: %v", magnet.Name, err)
|
||||||
q.MarkAsFailed(torrent)
|
q.MarkAsFailed(torrent)
|
||||||
return torrent, err
|
return torrent, err
|
||||||
}
|
}
|
||||||
torrent.ID = debridTorrent.Id
|
torrent.ID = debridTorrent.Id
|
||||||
q.processFiles(torrent, debridTorrent)
|
torrent.Name = debridTorrent.Name // Update the name before adding it to *arrs storage
|
||||||
|
torrent.DebridTorrent = debridTorrent
|
||||||
|
go q.processFiles(torrent, debridTorrent)
|
||||||
return torrent, nil
|
return torrent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package qbit
|
package qbit
|
||||||
|
|
||||||
|
import "goBlack/pkg/debrid"
|
||||||
|
|
||||||
type BuildInfo struct {
|
type BuildInfo struct {
|
||||||
Libtorrent string `json:"libtorrent"`
|
Libtorrent string `json:"libtorrent"`
|
||||||
Bitness int `json:"bitness"`
|
Bitness int `json:"bitness"`
|
||||||
@@ -167,7 +169,8 @@ type TorrentCategory struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Torrent struct {
|
type Torrent struct {
|
||||||
ID string `json:"-"`
|
ID string `json:"-"`
|
||||||
|
DebridTorrent *debrid.Torrent `json:"-"`
|
||||||
|
|
||||||
AddedOn int64 `json:"added_on,omitempty"`
|
AddedOn int64 `json:"added_on,omitempty"`
|
||||||
AmountLeft int64 `json:"amount_left,omitempty"`
|
AmountLeft int64 `json:"amount_left,omitempty"`
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (q *QBit) UpdateTorrent(t *Torrent, debridTorrent *debrid.Torrent) *Torrent
|
|||||||
t.Uploaded = sizeCompleted
|
t.Uploaded = sizeCompleted
|
||||||
t.UploadedSession = sizeCompleted
|
t.UploadedSession = sizeCompleted
|
||||||
t.AmountLeft = totalSize - sizeCompleted
|
t.AmountLeft = totalSize - sizeCompleted
|
||||||
t.Progress = 100
|
t.Progress = float32(progress)
|
||||||
t.SavePath = savePath
|
t.SavePath = savePath
|
||||||
t.ContentPath = torrentPath
|
t.ContentPath = torrentPath
|
||||||
t.Eta = eta
|
t.Eta = eta
|
||||||
|
|||||||
Reference in New Issue
Block a user