Wrap up file downloading feature

This commit is contained in:
Mukhtar Akere
2024-09-22 16:28:31 +01:00
parent ba147ac56c
commit ff74e279d9
12 changed files with 94 additions and 133 deletions

View File

@@ -40,7 +40,9 @@ func (q *QBit) RefreshArr(arr *debrid.Arr) {
if reqErr == nil {
statusOk := strconv.Itoa(resp.StatusCode)[0] == '2'
if statusOk {
q.logger.Printf("Refreshed monitored downloads for %s", cmp.Or(arr.Name, arr.Host))
if q.debug {
q.logger.Printf("Refreshed monitored downloads for %s", cmp.Or(arr.Name, arr.Host))
}
}
}
if reqErr != nil {

View File

@@ -1,7 +1,6 @@
package qbit
import (
"github.com/cavaliergopher/grab/v3"
"goBlack/common"
"goBlack/pkg/debrid"
"goBlack/pkg/qbit/downloaders"
@@ -13,62 +12,35 @@ import (
func (q *QBit) processManualFiles(torrent *Torrent, debridTorrent *debrid.Torrent, arr *debrid.Arr) {
q.logger.Printf("Downloading %d files...", len(debridTorrent.DownloadLinks))
parent := common.RemoveInvalidChars(filepath.Join(q.DownloadFolder, debridTorrent.Arr.Name, torrent.Name))
torrentPath := common.RemoveExtension(debridTorrent.OriginalFilename)
parent := common.RemoveInvalidChars(filepath.Join(q.DownloadFolder, debridTorrent.Arr.Name, torrentPath))
err := os.MkdirAll(parent, os.ModePerm)
if err != nil {
q.logger.Printf("Failed to create directory: %s\n", parent)
q.MarkAsFailed(torrent)
return
}
torrent.TorrentPath = torrentPath
q.downloadFiles(debridTorrent, parent)
q.UpdateTorrent(torrent, debridTorrent)
q.RefreshArr(arr)
}
func (q *QBit) downloadFile(client *grab.Client, link debrid.TorrentDownloadLinks, parent string, wg *sync.WaitGroup, semaphore chan struct{}) {
url := link.DownloadLink
defer wg.Done()
defer func() { <-semaphore }()
req, _ := grab.NewRequest(parent, url)
resp := client.Do(req)
//t := time.NewTicker(5 * time.Second)
//defer t.Stop()
//Loop:
// for {
// select {
// case <-t.C:
// fmt.Printf(" %s: transferred %d / %d bytes (%.2f%%)\n",
// resp.Filename,
// resp.BytesComplete(),
// resp.Size,
// 100*resp.Progress())
//
// case <-resp.Done:
// // download is complete
// break Loop
// }
// }
// Check for errors
if err := resp.Err(); err != nil {
q.logger.Printf("Error downloading %v: %v\n", url, err)
return
}
q.logger.Printf("Downloaded %s successfully\n", link.DownloadLink)
}
func (q *QBit) downloadFiles(debridTorrent *debrid.Torrent, parent string) {
var wg sync.WaitGroup
client := downloaders.GetFastHTTPClient()
semaphore := make(chan struct{}, 5)
client := downloaders.GetHTTPClient()
for _, link := range debridTorrent.DownloadLinks {
if link.DownloadLink == "" {
q.logger.Printf("No download link found for %s\n", link.Filename)
continue
}
wg.Add(1)
semaphore <- struct{}{}
go func(link debrid.TorrentDownloadLinks) {
defer wg.Done()
err := downloaders.NormalFastHTTP(client, link.DownloadLink, filepath.Join(parent, link.Filename))
defer func() { <-semaphore }()
err := downloaders.NormalHTTP(client, link.DownloadLink, filepath.Join(parent, link.Filename))
if err != nil {
q.logger.Printf("Error downloading %s: %v\n", link.DownloadLink, err)
} else {

View File

@@ -10,7 +10,8 @@ import (
func GetFastHTTPClient() *fasthttp.Client {
return &fasthttp.Client{
TLSConfig: &tls.Config{InsecureSkipVerify: true},
TLSConfig: &tls.Config{InsecureSkipVerify: true},
StreamResponseBody: true,
}
}
@@ -35,19 +36,24 @@ func NormalFastHTTP(client *fasthttp.Client, url, filename string) error {
if err != nil {
return err
}
defer file.Close()
defer func(file *os.File) {
err := file.Close()
if err != nil {
fmt.Println("Error closing file:", err)
return
}
}(file)
bodyStream := resp.BodyStream()
if bodyStream == nil {
return fmt.Errorf("bodyStream is nil")
}
defer func() {
if rc, ok := bodyStream.(io.Closer); ok {
rc.Close()
// Write to memory and then to file
_, err := file.Write(resp.Body())
if err != nil {
return err
}
} else {
if _, err := io.Copy(file, bodyStream); err != nil {
return err
}
}()
if _, err := io.Copy(file, bodyStream); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,55 @@
package downloaders
import (
"crypto/tls"
"fmt"
"github.com/cavaliergopher/grab/v3"
"net/http"
"time"
)
func GetGrabClient() *grab.Client {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyFromEnvironment,
}
return &grab.Client{
UserAgent: "qBitTorrent",
HTTPClient: &http.Client{
Transport: tr,
},
}
}
func NormalGrab(client *grab.Client, url, filename string) error {
req, err := grab.NewRequest(filename, url)
if err != nil {
return err
}
resp := client.Do(req)
if err := resp.Err(); err != nil {
return err
}
t := time.NewTicker(2 * time.Second)
defer t.Stop()
Loop:
for {
select {
case <-t.C:
fmt.Printf(" %s: transferred %d / %d bytes (%.2f%%)\n",
resp.Filename,
resp.BytesComplete(),
resp.Size,
100*resp.Progress())
case <-resp.Done:
// download is complete
break Loop
}
}
if err := resp.Err(); err != nil {
return err
}
return nil
}

View File

@@ -7,12 +7,10 @@ import (
func (q *QBit) handleVersion(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("v4.3.2"))
w.WriteHeader(http.StatusOK)
}
func (q *QBit) handleWebAPIVersion(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("2.7"))
w.WriteHeader(http.StatusOK)
}
func (q *QBit) handlePreferences(w http.ResponseWriter, r *http.Request) {

View File

@@ -63,7 +63,9 @@ func NewQBit(config *common.Config, deb debrid.Service, cache *common.Cache) *QB
func (q *QBit) Start() {
r := chi.NewRouter()
r.Use(middleware.Logger)
if q.debug {
r.Use(middleware.Logger)
}
r.Use(middleware.Recoverer)
q.AddRoutes(r)

View File

@@ -77,7 +77,7 @@ func (ts *TorrentStorage) Get(hash string) *Torrent {
func (ts *TorrentStorage) GetAll(category string, filter string, hashes []string) []*Torrent {
ts.mu.RLock()
defer ts.mu.RUnlock()
torrents := make([]*Torrent, 0, len(ts.torrents))
torrents := make([]*Torrent, 0)
for _, id := range ts.order {
torrent := ts.torrents[id]
if category != "" && torrent.Category != category {

View File

@@ -20,17 +20,15 @@ func (q *QBit) StartRefreshWorker(ctx context.Context) {
q.logger.Println("Qbit Refresh Worker stopped")
return
case <-refreshTicker.C:
q.RefreshArrs()
torrents := q.storage.GetAll("", "", nil)
if len(torrents) > 0 {
q.RefreshArrs()
}
}
}
}
func (q *QBit) RefreshArrs() {
torrents := q.storage.GetAll("", "", nil)
if len(torrents) == 0 {
return
}
q.arrs.Range(func(key, value interface{}) bool {
host, ok := key.(string)
token, ok2 := value.(string)