all repos — gopipe @ 83cd0bd9237351f9da3ef236617c2f915f2277c4

Embed YouTube videos on Telegram, Discord and more!

src/app/handlers.go (view raw)

  1package app
  2
  3import (
  4	"fmt"
  5	"log"
  6	"net/http"
  7	"regexp"
  8	"text/template"
  9
 10	g "github.com/birabittoh/gopipe/src/globals"
 11	"golang.org/x/time/rate"
 12)
 13
 14const (
 15	fmtYouTubeURL = "https://www.youtube.com/watch?v=%s"
 16	err404        = "Not Found"
 17	err500        = "Internal Server Error"
 18)
 19
 20var (
 21	templates      = template.Must(template.ParseGlob("templates/*.html"))
 22	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`)
 23	videoRegex     = regexp.MustCompile(`(?i)^[a-z0-9_-]{11}$`)
 24)
 25
 26func limit(limiter *rate.Limiter, next http.Handler) http.Handler {
 27	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 28		if !limiter.Allow() {
 29			status := http.StatusTooManyRequests
 30			http.Error(w, http.StatusText(status), status)
 31			return
 32		}
 33		next.ServeHTTP(w, r)
 34	})
 35}
 36
 37func indexHandler(w http.ResponseWriter, r *http.Request) {
 38	err := templates.ExecuteTemplate(w, "index.html", nil)
 39	if err != nil {
 40		log.Println("indexHandler ERROR: ", err)
 41		http.Error(w, err500, http.StatusInternalServerError)
 42		return
 43	}
 44}
 45
 46func videoHandler(w http.ResponseWriter, r *http.Request) {
 47	videoID := r.URL.Query().Get("v")
 48	if videoID == "" {
 49		videoID = r.PathValue("videoID")
 50		if videoID == "" {
 51			http.Error(w, "Missing video ID", http.StatusBadRequest)
 52			return
 53		}
 54	}
 55
 56	if !userAgentRegex.MatchString(r.UserAgent()) {
 57		log.Println("Regex did not match. UA: ", r.UserAgent())
 58		if !g.Debug {
 59			log.Println("Redirecting.")
 60			http.Redirect(w, r, getURL(videoID), http.StatusFound)
 61			return
 62		}
 63	}
 64
 65	if !videoRegex.MatchString(videoID) {
 66		log.Println("Invalid video ID: ", videoID)
 67		http.Error(w, "Invalid video ID.", http.StatusBadRequest)
 68		return
 69	}
 70
 71	formatID := getFormatID(r.PathValue("formatID"))
 72
 73	video, format, err := getVideo(videoID, formatID)
 74	if err != nil {
 75		http.Error(w, err500, http.StatusInternalServerError)
 76		return
 77	}
 78
 79	if video == nil || format == nil {
 80		http.Error(w, err500, http.StatusInternalServerError)
 81		return
 82	}
 83
 84	var thumbnail string
 85	if len(video.Thumbnails) > 0 {
 86		thumbnail = video.Thumbnails[len(video.Thumbnails)-1].URL
 87	}
 88
 89	videoURL := format.URL
 90	if g.Proxy {
 91		videoURL = fmt.Sprintf("/proxy/%s/%d", videoID, formatID)
 92	}
 93
 94	data := map[string]interface{}{
 95		"VideoID":     videoID,
 96		"VideoURL":    videoURL,
 97		"Uploader":    video.Author,
 98		"Title":       video.Title,
 99		"Description": video.Description,
100		"Thumbnail":   thumbnail,
101		"Duration":    video.Duration,
102		"Debug":       g.Debug,
103	}
104
105	err = templates.ExecuteTemplate(w, "video.html", data)
106	if err != nil {
107		log.Println("indexHandler ERROR: ", err)
108		http.Error(w, err500, http.StatusInternalServerError)
109		return
110	}
111}