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}