Read podcast list from saved file and merge new entries. Add daysAgo() selector.

Remember length of podcast episodes so we know if we need to download it again.
This commit is contained in:
Greg 2019-03-14 10:28:54 -04:00
parent 08ef8abf35
commit 95e73fd219
2 changed files with 103 additions and 30 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
rssd.conf rssd.conf
output.conf output.conf
*.mp3

124
main.go
View File

@ -3,6 +3,7 @@ package main
import ( import (
"log" "log"
"os" "os"
"strconv"
"time" "time"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
@ -15,10 +16,11 @@ type Config struct {
type Item struct { type Item struct {
Title, Description, Url, Filename string Title, Description, Url, Filename string
Length int
} }
type Podcast struct { type Podcast struct {
Title, Description string Title, Description, Url string
Items []Item Items []Item
} }
@ -26,32 +28,79 @@ type pcList struct {
Podcasts []Podcast Podcasts []Podcast
} }
func newpcList(confs ...string) (ret *pcList) {
ret = &pcList{}
ret.Podcasts = make([]Podcast,0)
if len(confs) > 0 {
if _, err := toml.DecodeFile("output.conf", &ret); err != nil {
log.Print("Error reading podcast list:",err)
}
}
return
}
func (p *pcList) Find(x *Podcast) (int, bool) {
for i,y := range p.Podcasts {
if y.Title == x.Title {
return i, true
}
}
return 0, false
}
func (p *pcList) Add(x *Podcast) { func (p *pcList) Add(x *Podcast) {
(*p).Podcasts = append((*p).Podcasts,*x) if x == nil {
return
}
if i,ok := p.Find(x); ok == true {
log.Print(" Existing podcast")
p.Podcasts[i].Merge(x)
} else {
log.Print(" New podcast")
p.Podcasts = append((*p).Podcasts,*x)
}
} }
type Db struct { func (p *Podcast) Merge(x *Podcast) {
Podcasts []Podcast for _,item := range x.Items {
if !p.Has(item) {
log.Print(" Appending '",item.Title,"'")
p.Items = append(p.Items,item)
}
}
} }
type Selector func(*gofeed.Item) bool func (p *Podcast) Has(i Item) bool {
for _,x := range p.Items {
func Any(ss []Selector, i *gofeed.Item) bool { if x.Title == i.Title {
for _, s := range ss {
if s(i) {
return true return true
} }
} }
return false return false
} }
func All(ss []Selector, i *gofeed.Item) bool { type Selector func(*gofeed.Item) bool
func AllSelectors(ss ...Selector) Selector {
return func(i *gofeed.Item) bool {
for _, s := range ss { for _, s := range ss {
if !s(i) { if !s(i) {
return false return false
} }
} }
return true return true
}
}
func AnySelector(ss ...Selector) Selector {
return func(i *gofeed.Item) bool {
for _, s := range ss {
if s(i) {
return true
}
}
return false
}
} }
func newerThan(t time.Time) Selector { func newerThan(t time.Time) Selector {
@ -63,20 +112,46 @@ func newerThan(t time.Time) Selector {
} }
} }
func readFeed(url string,ss ...Selector) *Podcast { func daysAgo(x int) Selector {
d := time.Now()
return newerThan(time.Date(d.Year(),d.Month(),d.Day()-x,0,0,0,0,time.Local))
}
func toPodcast(sel Selector, url string, feed *gofeed.Feed) (ret *Podcast) {
ret = &Podcast{
Title: feed.Title,
Description: feed.Description,
Url: url,
Items: []Item{},
}
for _, i := range feed.Items {
if sel(i) {
it := Item{
Title: i.Title,
Description: i.Description,
}
for _, n := range i.Enclosures {
if n.Type == "audio/mpeg" {
it.Url = n.URL
if l, err := strconv.Atoi(n.Length); err == nil {
it.Length = l
}
}
}
ret.Items = append(ret.Items,it)
}
}
return
}
func readFeed(url string,sel Selector) *Podcast {
fp := gofeed.NewParser() fp := gofeed.NewParser()
feed, err := fp.ParseURL(url) feed, err := fp.ParseURL(url)
if err != nil { if err != nil {
log.Fatal(err) log.Print(err)
return nil
} }
pc := Podcast{ feed.Title, feed.Description, []Item{} } return toPodcast(sel,url,feed)
for _, i := range feed.Items {
if All(ss,i) {
it := Item{ Title: i.Title, Description: i.Description }
pc.Items = append(pc.Items,it)
}
}
return &pc
} }
func main() { func main() {
@ -86,15 +161,12 @@ func main() {
if _, err := toml.DecodeFile("rssd.conf", &conf); err != nil { if _, err := toml.DecodeFile("rssd.conf", &conf); err != nil {
log.Fatal("Error reading config file:",err) log.Fatal("Error reading config file:",err)
} }
pl := &pcList{} pl := newpcList("output.conf")
pl.Podcasts = make([]Podcast,0)
d := time.Now()
lastMonth := newerThan(time.Date(d.Year(),d.Month()-1,d.Day(),0,0,0,0,time.Local))
sel := daysAgo(60)
for _,url := range conf.Urls { for _,url := range conf.Urls {
log.Print(" -> ",url) log.Print(" -> ",url)
pl.Add(readFeed(url,lastMonth)) pl.Add(readFeed(url,sel))
} }
of,err := os.Create("output.conf") of,err := os.Create("output.conf")
if err != nil { if err != nil {