package service import ( "encoding/xml" "errors" "fmt" "io/ioutil" "net/http" "strconv" "time" "github.com/akhilrex/podgrab/db" "github.com/akhilrex/podgrab/model" strip "github.com/grokify/html-strip-tags-go" "gorm.io/gorm" ) //FetchURL is func FetchURL(url string) (model.PodcastData, error) { body, err := makeQuery(url) if err != nil { return model.PodcastData{}, err } var response model.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) { var podcast db.Podcast err := db.GetPodcastByURL(url, &podcast) if errors.Is(err, gorm.ErrRecordNotFound) { data, err := FetchURL(url) if err != nil { fmt.Println("Error") //log.Fatal(err) return db.Podcast{}, err } podcast := db.Podcast{ Title: data.Channel.Title, Summary: strip.StripTags(data.Channel.Summary), Author: data.Channel.Author, Image: data.Channel.Image.URL, URL: url, } err = db.CreatePodcast(&podcast) return podcast, err } return podcast, &model.PodcastAlreadyExistsError{Url: url} } 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.StrictPolicy() limit := 5 if len(data.Channel.Item) < limit { limit = len(data.Channel.Item) } for i := 0; i < limit; 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: strip.StripTags(obj.Summary), EpisodeType: obj.EpisodeType, Duration: duration, PubDate: pubDate, FileURL: obj.Enclosure.URL, GUID: obj.Guid.Text, Image: obj.Image.Href, } 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 } func RefreshEpisodes() error { var data []db.Podcast err := db.GetAllPodcasts(&data) if err != nil { return err } for _, item := range data { AddPodcastItems(&item) } go DownloadMissingEpisodes() return nil } func DeletePodcast(id string) error { var podcast db.Podcast err := db.GetPodcastById(id, &podcast) if err != nil { return err } var podcastItems []db.PodcastItem err = db.GetAllPodcastItemsByPodcastId(id, &podcastItems) if err != nil { return err } for _, item := range podcastItems { DeleteFile(item.DownloadPath) db.DeletePodcastItemById(item.ID) } err = db.DeletePodcastById(id) if err != nil { return err } 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 }