99 lines
1.6 KiB
Go
99 lines
1.6 KiB
Go
package deezer
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/mathismqn/godeez/internal/crypto"
|
|
)
|
|
|
|
type Media struct {
|
|
Errors []MediaError `json:"errors"`
|
|
Data []struct {
|
|
Media []struct {
|
|
Type string `json:"media_type"`
|
|
Cipher Cipher `json:"cipher"`
|
|
Format string `json:"format"`
|
|
Sources []Source `json:"sources"`
|
|
}
|
|
Errors []MediaError `json:"errors"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type MediaError struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
type Cipher struct {
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
type Source struct {
|
|
URL string `json:"url"`
|
|
Provider string `json:"provider"`
|
|
}
|
|
|
|
const ChunkSize = 2048
|
|
|
|
func (m *Media) Download(url, path, songID string) error {
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
}
|
|
|
|
file, err := os.Create(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
key := crypto.GetBlowfishKey(songID)
|
|
buffer := make([]byte, ChunkSize)
|
|
|
|
for chunk := 0; ; chunk++ {
|
|
totalRead := 0
|
|
for totalRead < ChunkSize {
|
|
n, err := resp.Body.Read(buffer[totalRead:])
|
|
if err != nil {
|
|
if err.Error() == "EOF" {
|
|
break
|
|
}
|
|
return err
|
|
}
|
|
|
|
if n > 0 {
|
|
totalRead += n
|
|
}
|
|
}
|
|
|
|
if totalRead == 0 {
|
|
break
|
|
}
|
|
|
|
if chunk%3 == 0 && totalRead == ChunkSize {
|
|
buffer, err = crypto.DecryptBlowfish(buffer, key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
_, err = file.Write(buffer[:totalRead])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if totalRead < ChunkSize {
|
|
break
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|