all repos — gopipe @ 28aff114e23cb584fea3a9c94c0836f4cb521eca

Embed YouTube videos on Telegram, Discord and more!

src/app/handlers.go (view raw)

 1package app
 2
 3import (
 4	"log"
 5	"net/http"
 6	"regexp"
 7	"text/template"
 8	"time"
 9
10	g "github.com/birabittoh/gopipe/src/globals"
11)
12
13const err500 = "Internal Server Error"
14const urlDuration = 6 * time.Hour
15
16var (
17	templates      = template.Must(template.ParseGlob("templates/*.html"))
18	userAgentRegex = regexp.MustCompile(`(?i)bot|facebook|embed|got|firefox\/92|firefox\/38|curl|wget|go-http|yahoo|generator|whatsapp|preview|link|proxy|vkshare|images|analyzer|index|crawl|spider|python|cfnetwork|node`)
19	videoRegex     = regexp.MustCompile(`(?i)^[a-z0-9_-]{11}$`)
20)
21
22func indexHandler(w http.ResponseWriter, r *http.Request) {
23	err := templates.ExecuteTemplate(w, "index.html", nil)
24	if err != nil {
25		log.Println("indexHandler ERROR: ", err)
26		http.Error(w, err500, http.StatusInternalServerError)
27		return
28	}
29}
30
31func videoHandler(w http.ResponseWriter, r *http.Request) {
32	videoID := r.URL.Query().Get("v")
33	if videoID == "" {
34		videoID = r.PathValue("videoID")
35		if videoID == "" {
36			http.Error(w, "Missing video ID", http.StatusBadRequest)
37			return
38		}
39	}
40
41	url := "https://www.youtube.com/watch?v=" + videoID
42
43	if !userAgentRegex.MatchString(r.UserAgent()) {
44		log.Println("Regex did not match.")
45		if !g.Debug {
46			log.Println("Redirecting. UA:", r.UserAgent())
47			http.Redirect(w, r, url, http.StatusFound)
48			return
49		}
50	}
51
52	if !videoRegex.MatchString(videoID) {
53		log.Println("Invalid video ID: ", videoID)
54		http.Error(w, "Invalid video ID.", http.StatusBadRequest)
55		return
56	}
57
58	video, err := g.YT.GetVideo(url)
59	if err != nil {
60		log.Println("videoHandler ERROR: ", err)
61		http.Error(w, err500, http.StatusInternalServerError)
62		return
63	}
64
65	formats := video.Formats.WithAudioChannels()
66	if len(formats) == 0 {
67		log.Println("videoHandler ERROR: ", err)
68		http.Error(w, err500, http.StatusInternalServerError)
69		return
70	}
71
72	// TODO: check formats[i].ContentLength
73	// g.KS.Set(videoID, formats[0].URL, urlDuration)
74
75	data := map[string]interface{}{
76		"VideoID":     videoID,
77		"VideoURL":    formats[0].URL,
78		"Uploader":    video.Author,
79		"Title":       video.Title,
80		"Description": video.Description,
81		"Duration":    video.Duration,
82		"Debug":       g.Debug,
83	}
84
85	err = templates.ExecuteTemplate(w, "video.html", data)
86	if err != nil {
87		log.Println("indexHandler ERROR: ", err)
88		http.Error(w, err500, http.StatusInternalServerError)
89		return
90	}
91}