first working prototype

This commit is contained in:
Paul Wilde 2021-05-24 22:05:12 +01:00
parent 2ca59a846b
commit 7d855c7d4d
4 changed files with 125 additions and 7 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
podcasts.toml
db/*

View file

@ -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)
}
}

2
settings.toml Normal file
View file

@ -0,0 +1,2 @@
Directory = "/home/psw/podcasts/"
Limit = 50

View file

@ -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"`