fixyoutube.go (view raw)
1package main
2
3import (
4 "net/http"
5 "os"
6 "strconv"
7 "time"
8
9 "github.com/BiRabittoh/fixyoutube-go/invidious"
10 "github.com/joho/godotenv"
11 "github.com/sirupsen/logrus"
12 "golang.org/x/time/rate"
13)
14
15var (
16 apiKey string
17 debugSwitch = false
18 logger = logrus.New()
19)
20
21func limit(limiter *rate.Limiter, next http.Handler) http.Handler {
22 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
23 if !limiter.Allow() {
24 status := http.StatusTooManyRequests
25 http.Error(w, http.StatusText(status), status)
26 return
27 }
28 next.ServeHTTP(w, r)
29 })
30}
31
32func getenvDefault(key string, def string) string {
33 res := os.Getenv(key)
34 if res == "" {
35 return def
36 }
37 return res
38}
39
40func getenvDefaultParse(key string, def string) float64 {
41 value := getenvDefault(key, def)
42 res, err := strconv.ParseFloat(value, 64)
43 if err != nil {
44 logger.Fatal(err)
45 }
46 return res
47}
48
49func main() {
50 err := godotenv.Load()
51 if err != nil {
52 logger.Info("No .env file provided.")
53 }
54
55 if os.Getenv("DEBUG") != "" {
56 logger.SetLevel(logrus.DebugLevel)
57 logger.Debug("Debug mode enabled (rate limiting is disabled)")
58 debugSwitch = true
59 }
60
61 apiKey = getenvDefault("API_KEY", "itsme")
62 port := getenvDefault("PORT", "3000")
63 burstTokens := getenvDefaultParse("BURST_TOKENS", "3")
64 rateLimit := getenvDefaultParse("RATE_LIMIT", "1")
65 cacheDuration := getenvDefaultParse("CACHE_DURATION_MINUTES", "5")
66 timeoutDuration := getenvDefaultParse("TIMEOUT_DURATION_MINUTES", "10")
67 cleanupInterval := getenvDefaultParse("CLEANUP_INTERVAL_SECONDS", "30")
68 maxSizeMB := getenvDefaultParse("MAX_SIZE_MB", "20")
69
70 myClient := &http.Client{Timeout: 10 * time.Second}
71 options := invidious.ClientOptions{
72 CacheDuration: time.Duration(cacheDuration) * time.Minute,
73 TimeoutDuration: time.Duration(timeoutDuration) * time.Minute,
74 CleanupInterval: time.Duration(cleanupInterval) * time.Second,
75 MaxSizeBytes: int64(maxSizeMB * 1000000),
76 }
77 videoapi := invidious.NewClient(myClient, options)
78
79 r := http.NewServeMux()
80 r.HandleFunc("/", indexHandler)
81 r.HandleFunc("/clear", clearHandler)
82 r.HandleFunc("/watch", watchHandler(videoapi))
83 r.HandleFunc("/proxy/{videoId}", proxyHandler(videoapi))
84 r.HandleFunc("/{videoId}", shortHandler(videoapi))
85
86 var serveMux http.Handler
87 if debugSwitch {
88 serveMux = r
89 } else {
90 limiter := rate.NewLimiter(rate.Limit(rateLimit), int(burstTokens))
91 serveMux = limit(limiter, r)
92 }
93 logger.Info("Serving on port ", port)
94 http.ListenAndServe(":"+port, serveMux)
95}