youtuber/testdata/main.go

102 lines
2.3 KiB
Go
Executable File

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]
}