package handlers import ( "fmt" "os" "os/exec" "path/filepath" "strings" "beat-harvester/src/models" "beat-harvester/src/utils" "beat-harvester/src/broadcast" ) // DownloadPaths holds the directory paths for a download operation type DownloadPaths struct { AlbumDir string TempDir string } // getAlbumName extracts or returns the album name for the download func (h *Handler) getAlbumName(req models.DownloadRequest) (string, error) { if req.AlbumName != "" { broadcast.Log(fmt.Sprintf("📝 Using provided album name: %s", req.AlbumName)) return req.AlbumName, nil } broadcast.Log("📝 Extracting video title...") title, err := h.extractVideoInfo(req.YtLink) if err != nil { broadcast.Log(fmt.Sprintf("❌ Failed to extract title: %v", err)) return "", err } broadcast.Log(fmt.Sprintf("📝 Extracted title: %s", title)) return title, nil } // setupDownloadPaths creates and returns the necessary directory paths func (h *Handler) setupDownloadPaths(albumName, outputPath string) DownloadPaths { sanitizedAlbumName := utils.SanitizeFilename(albumName) baseOutputPath := outputPath if baseOutputPath == "" { baseOutputPath = h.config.DefaultOutputPath } albumDir := filepath.Join(baseOutputPath, sanitizedAlbumName) tempDir := filepath.Join(albumDir, h.config.TempDir) broadcast.Log(fmt.Sprintf("📁 Album directory: %s", albumDir)) broadcast.Log(fmt.Sprintf("📁 Temp directory: %s", tempDir)) // Create directories if err := os.MkdirAll(tempDir, 0755); err != nil { broadcast.Log(fmt.Sprintf("❌ Failed to create directories: %v", err)) } else { broadcast.Log("✅ Directories created successfully") } return DownloadPaths{ AlbumDir: albumDir, TempDir: tempDir, } } // extractVideoInfo gets video title using yt-dlp func (h *Handler) extractVideoInfo(url string) (string, error) { broadcast.Log("🔍 Extracting video information...") cmd := exec.Command("yt-dlp", "--get-title", "--no-warnings", url) // Capture both stdout and stderr for better debugging output, err := cmd.CombinedOutput() if err != nil { broadcast.Log(fmt.Sprintf("❌ Failed to get video title: %v", err)) if len(output) > 0 { broadcast.Log(fmt.Sprintf("❌ yt-dlp output: %s", string(output))) } return "", err } title := strings.TrimSpace(string(output)) if title == "" { broadcast.Log("⚠️ Empty title received, using fallback") return "Unknown", nil } broadcast.Log(fmt.Sprintf("✅ Video title extracted: %s", title)) return title, nil }