This commit is contained in:
afkarxyz
2025-11-22 17:59:48 +07:00
parent 8a2dbe4e32
commit d90221b835
11 changed files with 211 additions and 15 deletions
+6 -1
View File
@@ -124,11 +124,16 @@ func (d *DeezerDownloader) DownloadFile(url, filepath string) error {
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
fmt.Println("Downloading...")
// Use progress writer to track download
pw := NewProgressWriter(out)
_, err = io.Copy(pw, resp.Body)
if err != nil {
return fmt.Errorf("failed to write file: %w", err)
}
// Print final size
fmt.Printf("\rDownloaded: %.2f MB (Complete)\n", float64(pw.GetTotal())/(1024*1024))
return nil
}
+93
View File
@@ -0,0 +1,93 @@
package backend
import (
"fmt"
"io"
"sync"
)
// Global progress tracker
var (
currentProgress float64
currentProgressLock sync.RWMutex
isDownloading bool
downloadingLock sync.RWMutex
)
// ProgressInfo represents download progress information
type ProgressInfo struct {
IsDownloading bool `json:"is_downloading"`
MBDownloaded float64 `json:"mb_downloaded"`
}
// GetDownloadProgress returns current download progress
func GetDownloadProgress() ProgressInfo {
downloadingLock.RLock()
downloading := isDownloading
downloadingLock.RUnlock()
currentProgressLock.RLock()
progress := currentProgress
currentProgressLock.RUnlock()
return ProgressInfo{
IsDownloading: downloading,
MBDownloaded: progress,
}
}
// SetDownloadProgress updates the current download progress
func SetDownloadProgress(mbDownloaded float64) {
currentProgressLock.Lock()
currentProgress = mbDownloaded
currentProgressLock.Unlock()
}
// SetDownloading sets the downloading state
func SetDownloading(downloading bool) {
downloadingLock.Lock()
isDownloading = downloading
downloadingLock.Unlock()
if !downloading {
// Reset progress when download completes
SetDownloadProgress(0)
}
}
// ProgressWriter wraps an io.Writer and reports download progress
type ProgressWriter struct {
writer io.Writer
total int64
lastPrinted int64
}
func NewProgressWriter(writer io.Writer) *ProgressWriter {
return &ProgressWriter{
writer: writer,
total: 0,
lastPrinted: 0,
}
}
func (pw *ProgressWriter) Write(p []byte) (int, error) {
n, err := pw.writer.Write(p)
pw.total += int64(n)
// Report progress every 256KB for smoother updates
if pw.total-pw.lastPrinted >= 256*1024 {
mbDownloaded := float64(pw.total) / (1024 * 1024)
fmt.Printf("\rDownloaded: %.2f MB", mbDownloaded)
// Update global progress
SetDownloadProgress(mbDownloaded)
pw.lastPrinted = pw.total
}
return n, err
}
func (pw *ProgressWriter) GetTotal() int64 {
return pw.total
}
+6 -3
View File
@@ -184,13 +184,16 @@ func (q *QobuzDownloader) DownloadFile(url, filepath string) error {
}
defer out.Close()
fmt.Println("Writing file content...")
written, err := io.Copy(out, resp.Body)
fmt.Println("Downloading...")
// Use progress writer to track download
pw := NewProgressWriter(out)
_, err = io.Copy(pw, resp.Body)
if err != nil {
return fmt.Errorf("failed to write file: %w", err)
}
fmt.Printf("✓ Downloaded %d bytes\n", written)
// Print final size
fmt.Printf("\rDownloaded: %.2f MB (Complete)\n", float64(pw.GetTotal())/(1024*1024))
return nil
}
+22 -2
View File
@@ -83,7 +83,22 @@ func NewTidalDownloader(apiURL string) *TidalDownloader {
func (t *TidalDownloader) GetAvailableAPIs() ([]string, error) {
// Decode base64 API URL
apiURL, _ := base64.StdEncoding.DecodeString("aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2Fma2FyeHl6L1Nwb3RpRkxBQy9yZWZzL2hlYWRzL21haW4vdGlkYWwuanNvbg==")
resp, err := http.Get(string(apiURL))
// Add cache-busting parameter with current timestamp
urlWithCacheBust := fmt.Sprintf("%s?t=%d", string(apiURL), time.Now().Unix())
// Create request with cache bypass headers
req, err := http.NewRequest("GET", urlWithCacheBust, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
// Add headers to bypass cache
req.Header.Set("Cache-Control", "no-cache, no-store, must-revalidate")
req.Header.Set("Pragma", "no-cache")
req.Header.Set("Expires", "0")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to fetch API list: %w", err)
}
@@ -304,11 +319,16 @@ func (t *TidalDownloader) DownloadFile(url, filepath string) error {
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
// Use progress writer to track download
pw := NewProgressWriter(out)
_, err = io.Copy(pw, resp.Body)
if err != nil {
return fmt.Errorf("failed to write file: %w", err)
}
// Print final size
fmt.Printf("\rDownloaded: %.2f MB (Complete)\n", float64(pw.GetTotal())/(1024*1024))
fmt.Println("Download complete")
return nil
}