first working prototype
This commit is contained in:
parent
2ca59a846b
commit
7d855c7d4d
4 changed files with 125 additions and 7 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
podcasts.toml
|
podcasts.toml
|
||||||
|
db/*
|
||||||
|
|
|
@ -7,20 +7,35 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"os"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
var Version string = "0.1"
|
var Version string = "0.1"
|
||||||
|
var Settings Settings
|
||||||
var Podcasts map[string]Podcast = make(map[string]Podcast)
|
var Podcasts map[string]Podcast = make(map[string]Podcast)
|
||||||
|
var donefile string
|
||||||
func Start(){
|
func Start(){
|
||||||
fmt.Printf("Starting PodCatch Version : %s...\r\n", Version )
|
fmt.Printf("Starting PodCatch Version : %s...\r\n", Version )
|
||||||
|
getSettings()
|
||||||
getPodcasts()
|
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(){
|
func getPodcasts(){
|
||||||
if len(Podcasts) == 0 {
|
if len(Podcasts) == 0 {
|
||||||
getPodcastFiles()
|
getPodcastFiles()
|
||||||
}
|
}
|
||||||
for shortname,podcast := range Podcasts {
|
for shortname,podcast := range Podcasts {
|
||||||
fmt.Println(shortname)
|
podcast.Directory = shortname
|
||||||
fmt.Printf("Checking RSS for %s...\r\n", podcast.Name)
|
fmt.Printf("Checking RSS for %s...\r\n", podcast.Name)
|
||||||
podcast.RSS = getRSS(podcast)
|
podcast.RSS = getRSS(podcast)
|
||||||
downloadCasts(podcast)
|
downloadCasts(podcast)
|
||||||
|
@ -58,12 +73,101 @@ func parseRSS(podcast Podcast, rssxml []byte) Rss {
|
||||||
return rss
|
return rss
|
||||||
}
|
}
|
||||||
func downloadCasts(podcast Podcast) {
|
func downloadCasts(podcast Podcast) {
|
||||||
fmt.Println(podcast.RSS.Version)
|
count := 0
|
||||||
for _,item := range podcast.RSS.Channel.Items {
|
for _,item := range podcast.RSS.Channel.Items {
|
||||||
fmt.Printf("Downloading '%s' from : %s.\r\n", item.Title, item.Media.URL)
|
if count >= Settings.Limit {
|
||||||
re := regexp.MustCompile(`[^0-9a-zA-Z-_]+`)
|
break
|
||||||
filename := re.ReplaceAllString(item.Title,"_") + ".mp3"
|
}
|
||||||
fmt.Println(filename)
|
if !podcastDownloaded(item){
|
||||||
// fmt.Printf("%s - %s - %s\r\n", item.Title, item.Media.URL, item.Media.Type)
|
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
2
settings.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Directory = "/home/psw/podcasts/"
|
||||||
|
Limit = 50
|
|
@ -2,12 +2,22 @@ package structs
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
)
|
)
|
||||||
|
type Settings struct {
|
||||||
|
Directory string
|
||||||
|
Limit int
|
||||||
|
}
|
||||||
type Podcast struct {
|
type Podcast struct {
|
||||||
URL string
|
URL string
|
||||||
Name string
|
Name string
|
||||||
Directory string
|
Directory string
|
||||||
RSS Rss
|
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 {
|
type Rss struct {
|
||||||
XMLName xml.Name `xml:"rss"`
|
XMLName xml.Name `xml:"rss"`
|
||||||
Version string `xml:"version,attr"`
|
Version string `xml:"version,attr"`
|
||||||
|
@ -26,6 +36,7 @@ type Channel struct {
|
||||||
type Item struct {
|
type Item struct {
|
||||||
XMLName xml.Name `xml:"item"`
|
XMLName xml.Name `xml:"item"`
|
||||||
Title string `xml:"title"`
|
Title string `xml:"title"`
|
||||||
|
Episode string `xml:"episode"`
|
||||||
Link string `xml:"link"`
|
Link string `xml:"link"`
|
||||||
Description string `xml:"description"`
|
Description string `xml:"description"`
|
||||||
PubDate string `xml:"pubdate"`
|
PubDate string `xml:"pubdate"`
|
||||||
|
|
Loading…
Reference in a new issue