all repos

rss-tools @ d3bc404

get rss feed from sources that(i need and) dont provide one

rss-tools/sources/moviefeed/moviefeed.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
add moviefeed source, 1 month ago
1
package moviefeed
2
3
import (
4
	"fmt"
5
	"net/http"
6
	"strings"
7
	"time"
8
9
	"olexsmir.xyz/rss-tools/app"
10
)
11
12
type moviefeed struct {
13
	api    *TMDBAPI
14
	shows  []string
15
	client *http.Client
16
}
17
18
func Register(a *app.App) error {
19
	if a.Config.MoviefeedAPIKey == "" {
20
		return nil
21
	}
22
23
	mf := &moviefeed{
24
		api:    NewTMDBAPI(a.Config.MoviefeedAPIKey, a.Client),
25
		shows:  a.Config.MoviefeedShows,
26
		client: a.Client,
27
	}
28
29
	a.Route("GET /movies/{rest...}", mf.handleMovies)
30
31
	a.Logger.Info("moviefeed source registered")
32
	return nil
33
}
34
35
func (mf *moviefeed) handleMovies(w http.ResponseWriter, r *http.Request) {
36
	rest := r.PathValue("rest")
37
38
	if rest == "" {
39
		mf.handler(w, r, mf.shows)
40
		return
41
	}
42
43
	ids := strings.Split(rest, "/")
44
	var requestedIDs []string
45
	for _, id := range ids {
46
		if id != "" {
47
			requestedIDs = append(requestedIDs, id)
48
		}
49
	}
50
51
	if len(requestedIDs) == 0 {
52
		mf.handler(w, r, mf.shows)
53
		return
54
	}
55
56
	mf.handler(w, r, requestedIDs)
57
}
58
59
func (mf *moviefeed) handler(w http.ResponseWriter, r *http.Request, requestedIDs []string) {
60
	if len(requestedIDs) == 0 {
61
		http.Error(w, "no movie IDs provided", http.StatusBadRequest)
62
		return
63
	}
64
65
	var allEpisodes []TMDBEpisode
66
	for _, showID := range requestedIDs {
67
		episodes, err := mf.api.FetchEpisodesForShow(showID)
68
		if err != nil {
69
			continue
70
		}
71
		allEpisodes = append(allEpisodes, episodes...)
72
	}
73
74
	sortEpisodes(allEpisodes)
75
76
	feedID := fmt.Sprintf("moviefeed-%s", strings.Join(requestedIDs, "-"))
77
	feedTitle := fmt.Sprintf("Episodes from %s", strings.Join(requestedIDs, ", "))
78
	feed := app.NewFeed(feedTitle, feedID)
79
80
	for _, ep := range allEpisodes {
81
		entryID := fmt.Sprintf("tmdb-%s-s%de%d", ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber)
82
		airDate := parseAirDate(ep.AirDate)
83
84
		feed.Add(app.FeedEntry{
85
			Title: fmt.Sprintf("%s S%dE%d: %s",
86
				ep.ShowName,
87
				ep.SeasonNumber,
88
				ep.EpisodeNumber,
89
				ep.Name),
90
			ID:      entryID,
91
			Content: ep.Overview,
92
			Updated: airDate,
93
			Links: []app.FeedLink{
94
				{
95
					Rel:  "alternate",
96
					Href: fmt.Sprintf("https://www.themoviedb.org/tv/episode/%d", ep.ID),
97
				},
98
			},
99
		})
100
101
		if ep.StillPath != "" {
102
			feed.Add(app.FeedEntry{
103
				Title:   fmt.Sprintf("%s (image)", ep.Name),
104
				ID:      entryID + "-img",
105
				Content: fmt.Sprintf("![%s](%s%s)", ep.Name, tmdbImageBaseURL, ep.StillPath),
106
				Updated: airDate,
107
				Links: []app.FeedLink{
108
					{
109
						Rel:  "alternate",
110
						Href: fmt.Sprintf("https://www.themoviedb.org/tv/episode/%d", ep.ID),
111
					},
112
				},
113
			})
114
		}
115
	}
116
117
	if err := feed.Render(w); err != nil {
118
		http.Error(w, "failed to render feed", http.StatusInternalServerError)
119
		return
120
	}
121
}
122
123
func parseAirDate(dateStr string) time.Time {
124
	if dateStr == "" {
125
		return time.Now()
126
	}
127
	t, err := time.Parse(dateFormat, dateStr)
128
	if err != nil {
129
		return time.Now()
130
	}
131
	return t
132
}
133
134
func sortEpisodes(episodes []TMDBEpisode) {
135
	for i := range episodes {
136
		for j := i + 1; j < len(episodes); j++ {
137
			if episodes[j].AirDate > episodes[i].AirDate || (episodes[j].AirDate == episodes[i].AirDate && episodes[j].EpisodeNumber > episodes[i].EpisodeNumber) {
138
				episodes[i], episodes[j] = episodes[j], episodes[i]
139
			}
140
		}
141
	}
142
}