|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/xml"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/akhilrex/podgrab/db"
|
|
|
|
"github.com/microcosm-cc/bluemonday"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
)
|
|
|
|
|
|
|
|
//Fetch is
|
|
|
|
func FetchURL(url string) (PodcastData, error) {
|
|
|
|
body, err := makeQuery(url)
|
|
|
|
if err != nil {
|
|
|
|
return PodcastData{}, err
|
|
|
|
}
|
|
|
|
var response PodcastData
|
|
|
|
err = xml.Unmarshal(body, &response)
|
|
|
|
return response, err
|
|
|
|
}
|
|
|
|
func GetAllPodcasts() *[]db.Podcast {
|
|
|
|
var podcasts []db.Podcast
|
|
|
|
db.GetAllPodcasts(&podcasts)
|
|
|
|
return &podcasts
|
|
|
|
}
|
|
|
|
func AddPodcast(url string) (db.Podcast, error) {
|
|
|
|
|
|
|
|
data, err := FetchURL(url)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error")
|
|
|
|
//log.Fatal(err)
|
|
|
|
return db.Podcast{}, err
|
|
|
|
}
|
|
|
|
var podcast db.Podcast
|
|
|
|
err = db.GetPodcastByTitleAndAuthor(data.Channel.Title, data.Channel.Author, &podcast)
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
p := bluemonday.StripTagsPolicy()
|
|
|
|
|
|
|
|
podcast := db.Podcast{
|
|
|
|
Title: data.Channel.Title,
|
|
|
|
Summary: p.Sanitize(data.Channel.Summary),
|
|
|
|
Author: data.Channel.Author,
|
|
|
|
Image: data.Channel.Image.URL,
|
|
|
|
URL: url,
|
|
|
|
}
|
|
|
|
err = db.CreatePodcast(&podcast)
|
|
|
|
return podcast, err
|
|
|
|
}
|
|
|
|
return podcast, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func AddPodcastItems(podcast *db.Podcast) error {
|
|
|
|
fmt.Println("Creating: " + podcast.ID)
|
|
|
|
data, err := FetchURL(podcast.URL)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
p := bluemonday.StripTagsPolicy()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
obj := data.Channel.Item[i]
|
|
|
|
var podcastItem db.PodcastItem
|
|
|
|
err := db.GetPodcastItemByPodcastIdAndGUID(podcast.ID, obj.Guid.Text, &podcastItem)
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
duration, _ := strconv.Atoi(obj.Duration)
|
|
|
|
pubDate, _ := time.Parse(time.RFC1123Z, obj.PubDate)
|
|
|
|
podcastItem = db.PodcastItem{
|
|
|
|
PodcastID: podcast.ID,
|
|
|
|
Title: obj.Title,
|
|
|
|
Summary: p.Sanitize(obj.Summary),
|
|
|
|
EpisodeType: obj.EpisodeType,
|
|
|
|
Duration: duration,
|
|
|
|
PubDate: pubDate,
|
|
|
|
FileURL: obj.Enclosure.URL,
|
|
|
|
GUID: obj.Guid.Text,
|
|
|
|
}
|
|
|
|
db.CreatePodcastItem(&podcastItem)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetPodcastItemAsDownloaded(id string, location string) {
|
|
|
|
var podcastItem db.PodcastItem
|
|
|
|
db.GetPodcastItemById(id, &podcastItem)
|
|
|
|
|
|
|
|
podcastItem.DownloadDate = time.Now()
|
|
|
|
podcastItem.DownloadPath = location
|
|
|
|
|
|
|
|
db.UpdatePodcastItem(&podcastItem)
|
|
|
|
}
|
|
|
|
|
|
|
|
func DownloadMissingEpisodes() error {
|
|
|
|
data, err := db.GetAllPodcastItemsToBeDownloaded()
|
|
|
|
|
|
|
|
fmt.Println("Processing episodes: ", strconv.Itoa(len(*data)))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, item := range *data {
|
|
|
|
|
|
|
|
url, _ := Download(item.FileURL, item.Title, item.Podcast.Title)
|
|
|
|
SetPodcastItemAsDownloaded(item.ID, url)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func RefreshEpisodes() error {
|
|
|
|
var data []db.Podcast
|
|
|
|
err := db.GetAllPodcasts(&data)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, item := range data {
|
|
|
|
AddPodcastItems(&item)
|
|
|
|
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeQuery(url string) ([]byte, error) {
|
|
|
|
//link := "https://www.goodreads.com/search/index.xml?q=Good%27s+Omens&key=" + "jCmNlIXjz29GoB8wYsrd0w"
|
|
|
|
//link := "https://www.goodreads.com/search/index.xml?key=jCmNlIXjz29GoB8wYsrd0w&q=Ender%27s+Game"
|
|
|
|
//fmt.Println(url)
|
|
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
fmt.Println("Response status:", resp.Status)
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
|
|
|
|
return body, nil
|
|
|
|
|
|
|
|
}
|