package main import ( "fmt" "log" "net/http" "path/filepath" "strconv" "git.andreafazzi.eu/andrea/youtube-dl-service/task" "git.andreafazzi.eu/andrea/youtube-dl-service/youtube" youtube_dl "git.andreafazzi.eu/andrea/youtube-dl-service/youtube/youtube-dl" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" ) var tasks task.Tasks func init() { log.SetPrefix("[youtube-dl-service] ") tasks = make(task.Tasks, 0) } func download(c *gin.Context, downloader youtube.Downloader) error { video, err := downloader.GetVideo() if err != nil { return err } c.JSON(http.StatusOK, video) go downloader.StartDownload(video, tasks) return nil } func createTask(c *gin.Context) { err := c.Request.ParseForm() if err != nil { panic(err) } if err := download(c, youtube_dl.NewYoutubeDlDownloader(c.PostForm("url"), "yt-dlp")); err != nil { panic(err) } } func getTask(c *gin.Context, id string) error { task, ok := tasks[id] if ok { c.JSON(http.StatusOK, task) } return nil } func data(c *gin.Context, id string) error { c.Writer.Header().Set("Content-Disposition", "attachment; filename="+strconv.Quote(tasks[id].Filename)) c.Writer.Header().Set("Content-Type", "application/octet-stream") http.ServeFile(c.Writer, c.Request, filepath.Join("data", id+filepath.Ext(tasks[id].Filename))) return nil } // API outline // // POST /task content: url=https://foo.org start a new download task // GET /task/:id get the status for the task // GET /task/:id/download download the file resulted from the task execution // func main() { r := gin.Default() r.Use(cors.New(cors.Config{ AllowOrigins: []string{ "http://localhost:8080", "http://localhost:5000", "https://yt-dls.andreafazzi.eu", }, AllowCredentials: true, AllowHeaders: []string{"*"}, })) r.Use(gin.CustomRecovery(func(c *gin.Context, recovered interface{}) { if err, ok := recovered.(string); ok { c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) } c.AbortWithStatus(http.StatusInternalServerError) })) r.GET("/data/:id", func(c *gin.Context) { if err := data(c, c.Param("id")); err != nil { panic(err) } }) r.POST("/task", createTask) r.GET("/task/:id", func(c *gin.Context) { if err := getTask(c, c.Param("id")); err != nil { panic(err) } }) r.Run() }