diff --git a/.gitignore b/.gitignore index a0979b2..86efe73 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ podcasts.toml +db/* diff --git a/podcatch/podcatch.go b/podcatch/podcatch.go index c9dee07..daec87e 100644 --- a/podcatch/podcatch.go +++ b/podcatch/podcatch.go @@ -7,20 +7,35 @@ import ( "io/ioutil" "net/http" "regexp" + "os" "log" + "strings" ) var Version string = "0.1" +var Settings Settings var Podcasts map[string]Podcast = make(map[string]Podcast) +var donefile string func Start(){ fmt.Printf("Starting PodCatch Version : %s...\r\n", Version ) + getSettings() getPodcasts() } +func getSettings(){ + content, err := ioutil.ReadFile("settings.toml") + if err != nil { + log.Fatal(err) + } + e := toml.Unmarshal(content,&Settings) + if e != nil { + log.Fatal(err) + } +} func getPodcasts(){ if len(Podcasts) == 0 { getPodcastFiles() } for shortname,podcast := range Podcasts { - fmt.Println(shortname) + podcast.Directory = shortname fmt.Printf("Checking RSS for %s...\r\n", podcast.Name) podcast.RSS = getRSS(podcast) downloadCasts(podcast) @@ -58,12 +73,101 @@ func parseRSS(podcast Podcast, rssxml []byte) Rss { return rss } func downloadCasts(podcast Podcast) { - fmt.Println(podcast.RSS.Version) + count := 0 for _,item := range podcast.RSS.Channel.Items { - fmt.Printf("Downloading '%s' from : %s.\r\n", item.Title, item.Media.URL) - re := regexp.MustCompile(`[^0-9a-zA-Z-_]+`) - filename := re.ReplaceAllString(item.Title,"_") + ".mp3" - fmt.Println(filename) - // fmt.Printf("%s - %s - %s\r\n", item.Title, item.Media.URL, item.Media.Type) + if count >= Settings.Limit { + break + } + if !podcastDownloaded(item){ + fmt.Printf("Downloading '%s %s' from : %s.\r\n", item.Episode, item.Title, item.Media.URL) + re := regexp.MustCompile(`[^0-9a-zA-Z-_]+`) + filename := item.Episode + re.ReplaceAllString(item.Title,"_") + ".mp3" + dir := Settings.Directory + podcast.Directory + err := os.Mkdir(dir, 0777) + if err != nil && err.Error() != fmt.Sprintf("mkdir %s: file exists",dir){ + log.Fatal(err) + } + ok := downloadMp3(item.Media.URL, dir + "/" + filename) + if ok { + // createNFO(item, strings.Replace(dir + "/" + filename,".mp3",".nfo",1)) + markAsReceived(item) + } else { + markAsErrored(item) + } + } else { + fmt.Printf("Skipping '%s' - already downloaded\r\n", item.Title) + } + count = count + 1 + } +} +func podcastDownloaded(item Item) bool { + if len(donefile) < 1 { + content, err := ioutil.ReadFile("db/complete") + if err != nil { + log.Fatal(err) + } + donefile = string(content) + } + if strings.Contains(donefile,item.Title){ + return true + } + if strings.Contains(donefile,item.Media.URL){ + return true + } + return false +} +func downloadMp3(url string, file string) bool { + ok := false + resp, err := http.Get(url) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(file, data, 0775) + if err != nil { + log.Fatal(err) + } + ok = true + return ok +} +func createNFO(item Item, file string) { + fmt.Printf("Saving NFO file %s",file) + var nfo NFO + nfo.Title = item.Title + nfo.Outline = item.Description + nfo.Aired = item.PubDate + data, err := xml.Marshal(nfo) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(file, data, 0775) + if err != nil { + log.Fatal(err) + } +} +func markAsReceived(item Item) { + file, err := os.OpenFile("db/complete", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0755) + if err != nil { + log.Println(err) + } + defer file.Close() + content := fmt.Sprintf("%s - %s\r\n",item.Title, item.Media.URL) + if _, err := file.WriteString(content); err != nil { + log.Fatal(err) + } +} +func markAsErrored(item Item) { + file, err := os.OpenFile("db/error", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0755) + if err != nil { + log.Println(err) + } + defer file.Close() + content := fmt.Sprintf("%s\r\n%s",item.Title, item.Media.URL) + if _, err := file.WriteString(content); err != nil { + log.Fatal(err) } } diff --git a/settings.toml b/settings.toml new file mode 100644 index 0000000..b3ee729 --- /dev/null +++ b/settings.toml @@ -0,0 +1,2 @@ +Directory = "/home/psw/podcasts/" +Limit = 50 diff --git a/structs/structs.go b/structs/structs.go index 47da4a3..3172147 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -2,12 +2,22 @@ package structs import ( "encoding/xml" ) +type Settings struct { + Directory string + Limit int +} type Podcast struct { URL string Name string Directory string RSS Rss } +type NFO struct { + XMLName xml.Name `xml:"podcast"` + Title string `xml:"title"` + Outline string `xml:"outline"` + Aired string `xml:"aired"` +} type Rss struct { XMLName xml.Name `xml:"rss"` Version string `xml:"version,attr"` @@ -26,6 +36,7 @@ type Channel struct { type Item struct { XMLName xml.Name `xml:"item"` Title string `xml:"title"` + Episode string `xml:"episode"` Link string `xml:"link"` Description string `xml:"description"` PubDate string `xml:"pubdate"`