2024-10-11 13:05:46 +02:00
|
|
|
package music
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"hugo-medialog/utils"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
spotifyAPIBaseURL = "https://api.spotify.com/v1/search"
|
|
|
|
spotifyTokenURL = "https://accounts.spotify.com/api/token"
|
|
|
|
)
|
|
|
|
|
|
|
|
func getSpotifyToken() (string, error) {
|
|
|
|
apiKey := os.Getenv("SPOTIFY_API_KEY")
|
|
|
|
apiSecret := os.Getenv("SPOTIFY_SECRET_ID")
|
|
|
|
|
|
|
|
// Prepare the request body
|
|
|
|
data := url.Values{}
|
|
|
|
data.Set("grant_type", "client_credentials")
|
|
|
|
|
|
|
|
// Prepare the request
|
|
|
|
req, err := http.NewRequest("POST", spotifyTokenURL, strings.NewReader(data.Encode()))
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the headers
|
|
|
|
req.SetBasicAuth(apiKey, apiSecret)
|
|
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
|
|
|
|
// Send the request
|
|
|
|
client := &http.Client{}
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
// Read the response
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the response
|
|
|
|
var result map[string]interface{}
|
|
|
|
if err := json.Unmarshal(body, &result); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extract the access token
|
|
|
|
accessToken, ok := result["access_token"].(string)
|
|
|
|
if !ok {
|
|
|
|
return "", fmt.Errorf("could not retrieve access token")
|
|
|
|
}
|
|
|
|
|
|
|
|
return accessToken, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func SearchAlbumByTitle(title string, album *Album) error {
|
|
|
|
// Obtain the access token
|
|
|
|
accessToken, err := getSpotifyToken()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Search URL
|
|
|
|
titleEsc := url.QueryEscape(fmt.Sprintf("%s", title))
|
|
|
|
url := fmt.Sprintf("%s?q=%s&type=track&limit=1", spotifyAPIBaseURL, titleEsc)
|
|
|
|
|
|
|
|
// Prepare the request and add the auth header
|
|
|
|
req, _ := http.NewRequest("GET", url, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
req.Header.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
// Send the request
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Decode the response
|
|
|
|
var result map[string]interface{}
|
|
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
tracks := result["tracks"].(map[string]interface{})["items"].([]interface{})
|
|
|
|
track := tracks[0].(map[string]interface{})
|
|
|
|
albumData := track["album"].(map[string]interface{})
|
|
|
|
|
|
|
|
album.Artist = track["artists"].([]interface{})[0].(map[string]interface{})["name"].(string)
|
|
|
|
album.ID = albumData["id"].(string)
|
|
|
|
album.Album = albumData["name"].(string)
|
|
|
|
album.Date = albumData["release_date"].(string)
|
|
|
|
album.Year, _ = strconv.Atoi(strings.Split(album.Date, "-")[0])
|
|
|
|
album.Subtitle = strconv.Itoa(album.Year)
|
|
|
|
album.Tracks = int(albumData["total_tracks"].(float64)) // Spotify envía números como float64
|
|
|
|
album.Link = albumData["href"].(string)
|
|
|
|
images := albumData["images"].([]interface{})
|
|
|
|
if len(images) > 0 {
|
|
|
|
firstImage := images[0].(map[string]interface{})
|
|
|
|
album.Image = firstImage["url"].(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func DownloadImage(url, slug string) error {
|
|
|
|
imageDir := filepath.Join(os.Getenv("MARKDOWN_OUTPUT_MUSIC_DIR"), os.Getenv("IMAGES_OUTPUT_DIR"))
|
|
|
|
if err := utils.CreateDirIfNotExists(imageDir); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
filename := fmt.Sprintf("%s.jpg", slug)
|
|
|
|
filePath := filepath.Join(imageDir, filename)
|
|
|
|
|
|
|
|
resp, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error downloading image: %w", err)
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
return fmt.Errorf("non-200 response while downloading image: %d", resp.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
file, err := os.Create(filePath)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error creating image file: %w", err)
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error reading image data: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = file.Write(body)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error writing image data: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf(" - Image saved successfully at: %s\n", filePath)
|
2024-10-28 12:57:45 +01:00
|
|
|
|
|
|
|
// Generate thumbnails for the specified resolutions
|
|
|
|
resolutions := []uint{1024, 640, 320} // Define resolutions array for thumbnails
|
|
|
|
if err := utils.GenerateThumbnails(filePath, slug, imageDir, resolutions); err != nil {
|
|
|
|
return fmt.Errorf("error generating thumbnails: %w", err)
|
|
|
|
}
|
|
|
|
|
2024-10-11 13:05:46 +02:00
|
|
|
return nil
|
|
|
|
}
|