podcast-go

TUI podcast downloader for Apple Podcasts
Log | Files | Refs | README | LICENSE

commit 56afb3fd19985927b299e08866fbe7d843fcc370
parent 9808cdfb990bfa46357dbf0695190d2d00173904
Author: Erik Loualiche <eloualic@umn.edu>
Date:   Sun, 11 Jan 2026 10:36:56 -0600

added demo and options to download directory

Diffstat:
M.gitignore | 3+++
MREADME.md | 9++++++++-
Mmain.go | 48++++++++++++++++++++++++++++++------------------
Amedia/demo-podcastdownload.gif | 0
Mpodcastdownload | 0
5 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,5 @@ podcastdownload # Claude Code local settings .claude/ +.DS_Store +*.tape+ \ No newline at end of file diff --git a/README.md b/README.md @@ -1,6 +1,13 @@ +<div align="center"> + # Podcast Downloader +### Vibe coded Go TUI for downloading your favorites + +<img src="./media/demo-podcastdownload.gif" width="800" alt="Demo of the TUI"> + +</div> -A TUI (Terminal User Interface) application for downloading podcast episodes from Apple Podcasts. Built with Go and the Charm libraries for a beautiful terminal experience. +--- ## Features diff --git a/main.go b/main.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "flag" "fmt" "io" "net/http" @@ -131,6 +132,7 @@ type model struct { downloadIndex int downloadTotal int outputDir string + baseDir string downloaded []string percent float64 } @@ -171,14 +173,13 @@ func isNumeric(s string) bool { return len(s) > 0 } -func initialModel(input string) model { +func initialModel(input string, baseDir string) model { s := spinner.New() s.Spinner = spinner.Dot s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205")) p := progress.New(progress.WithDefaultGradient()) - // Determine if input is a podcast ID or search query isID := isNumeric(input) m := model{ @@ -186,6 +187,7 @@ func initialModel(input string) model { spinner: s, progress: p, windowHeight: 24, + baseDir: baseDir, } if isID { @@ -396,7 +398,8 @@ func (m model) handleSelectionKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) { m.state = stateDownloading m.downloadTotal = len(selected) m.downloadIndex = 0 - m.outputDir = sanitizeFilename(m.podcastInfo.Name) + podcastFolder := sanitizeFilename(m.podcastInfo.Name) + m.outputDir = filepath.Join(m.baseDir, podcastFolder) os.MkdirAll(m.outputDir, 0755) return m, func() tea.Msg { return startDownloadMsg{} } } @@ -881,26 +884,34 @@ func searchPodcasts(query string) tea.Cmd { } func main() { - if len(os.Args) < 2 { - fmt.Println("Podcast Downloader") - fmt.Println() - fmt.Println("Usage: podcastdownload <podcast_id_or_search_query>") - fmt.Println() - fmt.Println("Examples:") - fmt.Println(" podcastdownload 1200361736 # Download by Apple Podcast ID") - fmt.Println(" podcastdownload \"the daily\" # Search for podcasts by name") - fmt.Println() - fmt.Println("Find the ID in the Apple Podcasts URL:") - fmt.Println(" https://podcasts.apple.com/us/podcast/the-daily/id1200361736") - fmt.Println(" ^^^^^^^^^^") + // Define the -o flag. Defaults to "." (current directory) + baseDir := flag.String("o", ".", "Base directory where the podcast folder will be created") + + // Custom usage message + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: %s [flags] <podcast_id_or_search_query>\n\n", os.Args[0]) + fmt.Println("Flags:") + flag.PrintDefaults() + fmt.Println("\nExamples:") + fmt.Println(" podcastdownload -o ~/Music \"the daily\"") + fmt.Println(" podcastdownload 1200361736") + } + + flag.Parse() + + // Check if we have arguments left after parsing flags (the search query) + if flag.NArg() < 1 { + flag.Usage() os.Exit(1) } - input := strings.Join(os.Args[1:], " ") + // Join remaining arguments to form the search query + input := strings.Join(flag.Args(), " ") - program = tea.NewProgram(initialModel(input), tea.WithAltScreen()) + // Pass the baseDir to initialModel + program = tea.NewProgram(initialModel(input, *baseDir), tea.WithAltScreen()) if _, err := program.Run(); err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } -} +}+ \ No newline at end of file diff --git a/media/demo-podcastdownload.gif b/media/demo-podcastdownload.gif Binary files differ. diff --git a/podcastdownload b/podcastdownload Binary files differ.