mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-05-21 07:26:51 +02:00
Fix .tmp permission issue on Android Music folder
This commit is contained in:
@@ -20,10 +20,8 @@
|
||||
- Progress now updates smoothly every 64KB of data received
|
||||
- First progress update happens immediately when download starts
|
||||
- **Incomplete Downloads**: Fixed bug where interrupted downloads could result in corrupted/incomplete files
|
||||
- Downloads now use temporary files (`.tmp`) during transfer
|
||||
- File size is validated against server's Content-Length header
|
||||
- Incomplete files are automatically deleted and error is reported
|
||||
- Final file is only created after successful download completion
|
||||
- Applies to all services: Tidal, Qobuz, and Amazon
|
||||
|
||||
### Technical
|
||||
|
||||
+5
-13
@@ -300,9 +300,7 @@ func (a *AmazonDownloader) DownloadFile(downloadURL, outputPath, itemID string)
|
||||
SetItemBytesTotal(itemID, expectedSize)
|
||||
}
|
||||
|
||||
// Use temp file to avoid incomplete downloads
|
||||
tempPath := outputPath + ".tmp"
|
||||
out, err := os.Create(tempPath)
|
||||
out, err := os.Create(outputPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -326,30 +324,24 @@ func (a *AmazonDownloader) DownloadFile(downloadURL, outputPath, itemID string)
|
||||
|
||||
// Check for any errors
|
||||
if err != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("download interrupted: %w", err)
|
||||
}
|
||||
if flushErr != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("failed to flush buffer: %w", flushErr)
|
||||
}
|
||||
if closeErr != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("failed to close file: %w", closeErr)
|
||||
}
|
||||
|
||||
// Verify file size if Content-Length was provided
|
||||
if expectedSize > 0 && written != expectedSize {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("incomplete download: expected %d bytes, got %d bytes", expectedSize, written)
|
||||
}
|
||||
|
||||
// Rename temp file to final path
|
||||
if err := os.Rename(tempPath, outputPath); err != nil {
|
||||
os.Remove(tempPath)
|
||||
return fmt.Errorf("failed to rename temp file: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("\r[Amazon] Downloaded: %.2f MB (Complete)\n", float64(written)/(1024*1024))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -282,6 +282,8 @@ func DownloadWithFallback(requestJSON string) (string, error) {
|
||||
preferredService = "tidal"
|
||||
}
|
||||
|
||||
fmt.Printf("[DownloadWithFallback] Preferred service from request: '%s'\n", req.Service)
|
||||
|
||||
// Create ordered list: preferred first, then others
|
||||
services := []string{preferredService}
|
||||
for _, s := range allServices {
|
||||
@@ -290,9 +292,12 @@ func DownloadWithFallback(requestJSON string) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("[DownloadWithFallback] Service order: %v\n", services)
|
||||
|
||||
var lastErr error
|
||||
|
||||
for _, service := range services {
|
||||
fmt.Printf("[DownloadWithFallback] Trying service: %s\n", service)
|
||||
req.Service = service
|
||||
|
||||
var result DownloadResult
|
||||
|
||||
+5
-13
@@ -479,9 +479,7 @@ func (q *QobuzDownloader) DownloadFile(downloadURL, outputPath, itemID string) e
|
||||
SetItemBytesTotal(itemID, expectedSize)
|
||||
}
|
||||
|
||||
// Use temp file to avoid incomplete downloads
|
||||
tempPath := outputPath + ".tmp"
|
||||
out, err := os.Create(tempPath)
|
||||
out, err := os.Create(outputPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -505,30 +503,24 @@ func (q *QobuzDownloader) DownloadFile(downloadURL, outputPath, itemID string) e
|
||||
|
||||
// Check for any errors
|
||||
if err != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("download interrupted: %w", err)
|
||||
}
|
||||
if flushErr != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("failed to flush buffer: %w", flushErr)
|
||||
}
|
||||
if closeErr != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("failed to close file: %w", closeErr)
|
||||
}
|
||||
|
||||
// Verify file size if Content-Length was provided
|
||||
if expectedSize > 0 && written != expectedSize {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("incomplete download: expected %d bytes, got %d bytes", expectedSize, written)
|
||||
}
|
||||
|
||||
// Rename temp file to final path
|
||||
if err := os.Rename(tempPath, outputPath); err != nil {
|
||||
os.Remove(tempPath)
|
||||
return fmt.Errorf("failed to rename temp file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+9
-25
@@ -752,9 +752,7 @@ func (t *TidalDownloader) DownloadFile(downloadURL, outputPath, itemID string) e
|
||||
SetItemBytesTotal(itemID, expectedSize)
|
||||
}
|
||||
|
||||
// Use temp file to avoid incomplete downloads
|
||||
tempPath := outputPath + ".tmp"
|
||||
out, err := os.Create(tempPath)
|
||||
out, err := os.Create(outputPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -778,30 +776,24 @@ func (t *TidalDownloader) DownloadFile(downloadURL, outputPath, itemID string) e
|
||||
|
||||
// Check for any errors
|
||||
if err != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("download interrupted: %w", err)
|
||||
}
|
||||
if flushErr != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("failed to flush buffer: %w", flushErr)
|
||||
}
|
||||
if closeErr != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("failed to close file: %w", closeErr)
|
||||
}
|
||||
|
||||
// Verify file size if Content-Length was provided
|
||||
if expectedSize > 0 && written != expectedSize {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("incomplete download: expected %d bytes, got %d bytes", expectedSize, written)
|
||||
}
|
||||
|
||||
// Rename temp file to final path
|
||||
if err := os.Rename(tempPath, outputPath); err != nil {
|
||||
os.Remove(tempPath)
|
||||
return fmt.Errorf("failed to rename temp file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -844,9 +836,7 @@ func (t *TidalDownloader) downloadFromManifest(manifestB64, outputPath, itemID s
|
||||
SetItemBytesTotal(itemID, expectedSize)
|
||||
}
|
||||
|
||||
// Use temp file to avoid incomplete downloads
|
||||
tempPath := outputPath + ".tmp"
|
||||
out, err := os.Create(tempPath)
|
||||
out, err := os.Create(outputPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file: %w", err)
|
||||
}
|
||||
@@ -863,26 +853,20 @@ func (t *TidalDownloader) downloadFromManifest(manifestB64, outputPath, itemID s
|
||||
closeErr := out.Close()
|
||||
|
||||
if err != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("download interrupted: %w", err)
|
||||
}
|
||||
if closeErr != nil {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("failed to close file: %w", closeErr)
|
||||
}
|
||||
|
||||
// Verify file size if Content-Length was provided
|
||||
if expectedSize > 0 && written != expectedSize {
|
||||
os.Remove(tempPath)
|
||||
os.Remove(outputPath)
|
||||
return fmt.Errorf("incomplete download: expected %d bytes, got %d bytes", expectedSize, written)
|
||||
}
|
||||
|
||||
// Rename temp file to final path
|
||||
if err := os.Rename(tempPath, outputPath); err != nil {
|
||||
os.Remove(tempPath)
|
||||
return fmt.Errorf("failed to rename temp file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user