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) return nil }