all repos

moviefeed @ main

rss feed server for tracking new tv show episodes

moviefeed/main.go(view raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main

import (
	"flag"
	"fmt"
	"log/slog"
	"net/http"
	"os"
	"time"

	"github.com/gorilla/feeds"
)

const dateFormat = "2006-01-02"

func main() {
	configFile := flag.String("config", "config.yaml", "Path to config file")
	flag.Parse()

	config, err := loadConfig(*configFile)
	if err != nil {
		slog.Error("failed to load config", "err", err)
		os.Exit(1)
	}

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		slog.Info("incoming request", "method", r.Method, "url", r.URL.String())

		if r.URL.Query().Get("access_key") != config.AccessKey {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}

		episodes, err := fetchNewEpisodes(config)
		if err != nil {
			slog.Error("failed to fetch episodes", "err", err)
			http.Error(w, "Internal server error", http.StatusInternalServerError)
			return
		}

		rssFeed := generateRSS(episodes)
		w.Header().Set("Content-Type", "application/rss+xml")
		_, _ = w.Write([]byte(rssFeed))
	})

	addr := ":" + config.Port
	slog.Info("server starting", "port", config.Port)
	if err := http.ListenAndServe(addr, nil); err != nil {
		slog.Error("server failed", "err", err)
		os.Exit(1)
	}
}

func generateRSS(episodes []TMDBEpisode) string {
	feed := &feeds.Feed{
		Title:       "moviefeed",
		Link:        &feeds.Link{},
		Description: "Latest episodes from followed shows",
		Created:     time.Now(),
	}

	for i := len(episodes) - 1; i >= 0; i-- {
		ep := episodes[i]
		airDate, _ := time.Parse("2006-01-02", ep.AirDate)
		item := &feeds.Item{
			Id: fmt.Sprintf("%s-%d-%d", ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber),
			Title: fmt.Sprintf(
				"%s S%dE%d: %s",
				ep.ShowName,
				ep.SeasonNumber,
				ep.EpisodeNumber,
				ep.Name,
			),
			Link: &feeds.Link{
				Href: fmt.Sprintf("https://www.themoviedb.org/tv/episode/%d", ep.ID),
			},
			Description: ep.Overview,
			Created:     airDate,
		}
		if ep.StillPath != "" {
			item.Enclosure = &feeds.Enclosure{
				Url:    "https://image.tmdb.org/t/p/w500" + ep.StillPath,
				Length: "0",
				Type:   "image/jpeg",
			}
		}
		feed.Items = append(feed.Items, item)
	}

	rss, err := feed.ToRss()
	if err != nil {
		slog.Error("error generating RSS", "err", err)
		return ""
	}

	return rss
}