Compare commits
No commits in common. "7c782522f516d1b6b81137aa547a0fa52cae3cdb" and "cb437f3bb6c5de53fdd568373e49dae919baf32f" have entirely different histories.
7c782522f5
...
cb437f3bb6
286
main.go
286
main.go
@ -14,218 +14,196 @@ import (
|
|||||||
"github.com/jaswdr/faker"
|
"github.com/jaswdr/faker"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dbpool *pgxpool.Pool
|
// This is taken from our DB model
|
||||||
|
type video struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Filepath string `json:"filepath"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// videos slice to seed record video data.
|
||||||
|
var videos []video
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
dbpool, err := pgxpool.New(context.Background(), "postgresql://postgres:postgres@172.19.0.2:5432/postgres")
|
||||||
dbpool, err = pgxpool.New(context.Background(), "postgresql://postgres:postgres@172.19.0.2:5432/postgres")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer dbpool.Close()
|
defer dbpool.Close()
|
||||||
|
|
||||||
sqlStmt := `
|
sqlStmt := `
|
||||||
DROP TABLE IF EXISTS videos;
|
DROP TABLE IF EXISTS public.videos;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS videos
|
CREATE TABLE IF NOT EXISTS public.videos
|
||||||
(
|
(
|
||||||
id serial NOT NULL,
|
id integer NOT NULL,
|
||||||
filepath text,
|
filepath text,
|
||||||
CONSTRAINT videos_pkey PRIMARY KEY (id)
|
CONSTRAINT videos_pkey PRIMARY KEY (id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TABLESPACE pg_default;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.videos
|
||||||
|
OWNER to postgres;
|
||||||
`
|
`
|
||||||
_, err = dbpool.Exec(context.Background(), sqlStmt)
|
_, err = dbpool.Exec(context.Background(), sqlStmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("main: create table: %v\n", err)
|
log.Fatalf("Unable to connection to database: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
faker := faker.New()
|
faker := faker.New()
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
_, err = dbpool.Exec(context.Background(), "insert into videos(filepath) values($1)", faker.File().AbsoluteFilePathForUnix(2))
|
sqlStmt = fmt.Sprintf("insert into public.videos(id, filepath) values(%d, '%s')", i, faker.File().AbsoluteFilePathForUnix(2))
|
||||||
|
_, err = dbpool.Exec(context.Background(), sqlStmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("main: fill with fake data: %v\n", err)
|
log.Fatalf("Unable to add videos: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rows, _ := dbpool.Query(context.Background(), "select * from videos")
|
||||||
|
for rows.Next() {
|
||||||
|
var id int
|
||||||
|
var name string
|
||||||
|
err = rows.Scan(&id, &name)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to list videos: %v\n", err)
|
||||||
|
}
|
||||||
|
fmt.Println(id, name)
|
||||||
|
}
|
||||||
|
err = rows.Err()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to list videos: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
videos = append(videos, video{ID: i, Filepath: faker.File().AbsoluteFilePathForUnix(5)})
|
||||||
|
}
|
||||||
|
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
router.SetTrustedProxies(nil)
|
router.SetTrustedProxies(nil)
|
||||||
|
|
||||||
router.POST("/video/init", initUpload)
|
router.POST("/upload", ReceiveFile)
|
||||||
router.POST("/video/chunk", ReceiveChunk)
|
router.GET("/videos", getvideos)
|
||||||
router.POST("/video/completed", finishUpload)
|
router.GET("/videos/:id", getvideoByID)
|
||||||
router.GET("/videos", listVideos)
|
router.POST("/videos", postvideos)
|
||||||
router.GET("/videos/:id", getVideo)
|
router.DELETE("/videos", delvideos)
|
||||||
router.DELETE("/videos/:id", deleteVideo)
|
router.DELETE("/videos/:id", delvideoByID)
|
||||||
|
router.PATCH("/videos/:id", updatevideo)
|
||||||
|
|
||||||
router.Run("localhost:8080")
|
router.Run("localhost:8080")
|
||||||
}
|
}
|
||||||
|
|
||||||
func initUpload(c *gin.Context) {
|
func remove(slice []video, s int) []video {
|
||||||
var err error
|
return append(slice[:s], slice[s+1:]...)
|
||||||
|
}
|
||||||
|
|
||||||
fileName, err := io.ReadAll(c.Request.Body)
|
func ReceiveFile(c *gin.Context) {
|
||||||
|
// maybe even re-verify mime-type (before or after upload)
|
||||||
|
|
||||||
|
fileName := c.GetHeader("file-name")
|
||||||
|
/*
|
||||||
|
get data from request
|
||||||
|
write append data to file
|
||||||
|
*/
|
||||||
|
data, err := io.ReadAll(c.Request.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, "Couldn't read html request body")
|
c.IndentedJSON(http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
currentDir, err := os.Getwd()
|
f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("initUpload: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, _ := dbpool.Query(context.Background(), "select filepath from videos")
|
|
||||||
for rows.Next() {
|
|
||||||
var filepath string
|
|
||||||
err = rows.Scan(&filepath)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("initUpload: %v\n", err)
|
|
||||||
}
|
|
||||||
fmt.Println(filepath)
|
|
||||||
if filepath == fmt.Sprintf("%s/%s", currentDir, fileName) {
|
|
||||||
c.JSON(http.StatusForbidden, "File already exists")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = rows.Err()
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("initUpload: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, "Upload can proceed")
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReceiveChunk(c *gin.Context) {
|
|
||||||
chunk, err := io.ReadAll(c.Request.Body)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusBadRequest, "Couldn't read html request body")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.OpenFile(c.GetHeader("file-name"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if _, err := f.Write(chunk); err != nil {
|
if _, err := f.Write(data); err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, "Received chunk")
|
c.IndentedJSON(http.StatusOK, "Received chunk")
|
||||||
}
|
}
|
||||||
|
|
||||||
func finishUpload(c *gin.Context) {
|
// getvideos responds with the list of all videos as JSON.
|
||||||
currentDir, err := os.Getwd()
|
func getvideos(c *gin.Context) {
|
||||||
if err != nil {
|
c.IndentedJSON(http.StatusOK, videos)
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("finishUpload: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName, err := io.ReadAll(c.Request.Body)
|
// postvideos adds an video from JSON received in the request body.
|
||||||
if err != nil {
|
func postvideos(c *gin.Context) {
|
||||||
c.JSON(http.StatusBadRequest, "Couldn't read html request body")
|
var newvideo video
|
||||||
|
|
||||||
|
// Call BindJSON to bind the received JSON to
|
||||||
|
// newvideo.
|
||||||
|
if err := c.BindJSON(&newvideo); err != nil {
|
||||||
|
c.Status(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dbpool.Exec(context.Background(), "insert into videos(filepath) values($1)", fmt.Sprintf("%s/%s", currentDir, fileName))
|
for _, a := range videos {
|
||||||
if err != nil {
|
if a == newvideo {
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
c.Status(http.StatusBadRequest)
|
||||||
log.Fatalf("finishUpload: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{}) // return list of videos
|
|
||||||
}
|
|
||||||
|
|
||||||
func listVideos(c *gin.Context) {
|
|
||||||
var err error
|
|
||||||
rows, _ := dbpool.Query(context.Background(), "select * from videos")
|
|
||||||
for rows.Next() {
|
|
||||||
var id int
|
|
||||||
var filepath string
|
|
||||||
err = rows.Scan(&id, &filepath)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("listVideos: %v\n", err)
|
|
||||||
}
|
|
||||||
fmt.Println(id, filepath)
|
|
||||||
}
|
|
||||||
err = rows.Err()
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("listVideos: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func getVideo(c *gin.Context) {
|
|
||||||
var err error
|
|
||||||
inputId, err := strconv.Atoi(c.Param("id"))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, _ := dbpool.Query(context.Background(), "select * from videos where id = $1", inputId)
|
|
||||||
rows.Next()
|
|
||||||
var id int
|
|
||||||
var filepath string
|
|
||||||
err = rows.Scan(&id, &filepath)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("getVideo: %v\n", err)
|
|
||||||
}
|
|
||||||
fmt.Println(id, filepath)
|
|
||||||
err = rows.Err()
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("getVideo: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteVideo(c *gin.Context) {
|
|
||||||
inputId, err := strconv.Atoi(c.Param("id"))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, _ := dbpool.Query(context.Background(), "select filepath from videos where id = $1", inputId)
|
|
||||||
rows.Next()
|
|
||||||
var filepath string
|
|
||||||
err = rows.Scan(&filepath)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("deleteVideo: %v\n", err)
|
|
||||||
c.JSON(http.StatusBadRequest, "Video does not exist")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println(filepath)
|
}
|
||||||
err = rows.Err()
|
|
||||||
if err != nil {
|
// Add the new video to the slice.
|
||||||
log.Printf("deleteVideo: %v\n", err)
|
videos = append(videos, newvideo)
|
||||||
c.JSON(http.StatusInternalServerError, "Scanning the row didn't work")
|
c.IndentedJSON(http.StatusCreated, newvideo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getvideoByID locates the video whose ID value matches the id
|
||||||
|
// parameter sent by the client, then returns that video as a response.
|
||||||
|
func getvideoByID(c *gin.Context) {
|
||||||
|
inputId := c.Param("id")
|
||||||
|
|
||||||
|
// Loop through the list of videos, looking for
|
||||||
|
// an video whose ID value matches the parameter.
|
||||||
|
for _, a := range videos {
|
||||||
|
if strconv.Itoa(a.ID) == inputId {
|
||||||
|
c.IndentedJSON(http.StatusOK, a)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "video not found"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func delvideos(c *gin.Context) {
|
||||||
|
videos = []video{}
|
||||||
|
c.IndentedJSON(http.StatusOK, videos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func delvideoByID(c *gin.Context) {
|
||||||
|
inputId := c.Param("id")
|
||||||
|
|
||||||
|
for s, a := range videos {
|
||||||
|
if strconv.Itoa(a.ID) == inputId {
|
||||||
|
videos = remove(videos, s)
|
||||||
|
c.IndentedJSON(http.StatusCreated, videos)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "video not found"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatevideo(c *gin.Context) {
|
||||||
|
inputId := c.Param("id")
|
||||||
|
|
||||||
|
var newvideo video
|
||||||
|
|
||||||
|
if err := c.BindJSON(&newvideo); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dbpool.Exec(context.Background(), "delete from videos where id = $1", inputId)
|
for s, a := range videos {
|
||||||
if err != nil {
|
if strconv.Itoa(a.ID) == inputId {
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
videos = remove(videos, s)
|
||||||
log.Fatalf("deleteVideo: %v\n", err)
|
videos = append(videos, newvideo)
|
||||||
|
c.IndentedJSON(http.StatusCreated, newvideo)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = os.Remove(filepath); err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, "")
|
|
||||||
log.Fatalf("deleteVideo: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "video not found"})
|
||||||
c.JSON(http.StatusOK, gin.H{}) // return list of videos
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user