package main import ( "errors" "fmt" "io/ioutil" "local/jbtserve/jbt" "local/system/sysconf" "log" "net" "net/http" "os" "os/signal" "path" "regexp" "strings" "syscall" "github.com/otium/ytdl" ) var validURL = regexp.MustCompile("(?is)https?://([a-z1-9]+.)+[a-z]+/.*") func main() { if os.Getenv("MNT") == "" { os.Setenv("MNT", "./") } if !strings.HasSuffix(os.Getenv("MNT"), "/") { os.Setenv("MNT", os.Getenv("MNT")+"/") } config := sysconf.Get("ytubespdrun") exit := make(chan bool) go jbt.RegisterDeregister(config.Name, config.Port, exit) log.Print("Listen on", net.JoinHostPort(config.IP, config.Port)) go func() { log.Print(http.ListenAndServe(net.JoinHostPort(config.IP, config.Port), http.HandlerFunc(accept))) }() sigc := make(chan os.Signal) signal.Notify(sigc, syscall.SIGINT, ) <-sigc <-exit <-exit } func accept(w http.ResponseWriter, r *http.Request) { config := sysconf.Get("ytubespdrun") if r.Method != "POST" { w.WriteHeader(http.StatusMethodNotAllowed) return } body, err := ioutil.ReadAll(r.Body) if err != nil { panic(err) } token := string(body) token = strings.Split(token, "&")[0] log.Print("Received request", token) if !validURL.MatchString(token) { w.WriteHeader(http.StatusBadRequest) return } if err := download(token, config.Log); err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Cannot download %s, encountered error %v", token, err) log.Print("Failed request", token) return } w.WriteHeader(http.StatusOK) log.Print("Completed request", token) } func download(url, log string) error { vid, err := ytdl.GetVideoInfo(url) if err != nil { return err } format := vid.Formats.Best(ytdl.FormatExtensionKey) if len(format) < 1 { return errors.New("no formats available") } log.Print("Downloading format", format[0].Resolution, format[0].Extension, format[0].Itag, "for video", vid.Title) file, err := os.Create(os.Getenv("MNT") + strings.Replace(fmt.Sprintf("%s.%s", vid.Title, format[0].Extension), " ", "_", -1)) if err != nil { return err } defer file.Close() return vid.Download(format[0], file) } func pathAdvance(r *http.Request) string { p := path.Clean("/" + r.URL.Path) i := strings.Index(p[1:], "/") + 1 if i <= 0 { r.URL.Path = "/" return p[1:] } r.URL.Path = p[i:] return p[1:i] }