init: streaming backend upload video
This commit is contained in:
commit
0615ff0b06
|
|
@ -0,0 +1,16 @@
|
|||
# binary
|
||||
*.exe
|
||||
*.out
|
||||
|
||||
# env
|
||||
.env
|
||||
|
||||
# upload video (JANGAN di push)
|
||||
storage/videos/*
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# go
|
||||
/vendor/
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var DB *gorm.DB
|
||||
|
||||
func InitDB() {
|
||||
dsn := "host=38.47.185.79 user=streamin_user password=StreaminDB@2026 dbname=streamin_db port=5432 sslmode=disable"
|
||||
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Fatal("DB Error:", err)
|
||||
}
|
||||
|
||||
DB = db
|
||||
fmt.Println("✅ DB Connected")
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package video
|
||||
|
||||
type Video struct {
|
||||
ID int `json:"id" gorm:"primaryKey"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
FileURL string `json:"file_url"`
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package video
|
||||
|
||||
type Video struct {
|
||||
ID int `json:"id" gorm:"primaryKey"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
FileURL string `json:"file_url"`
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package video
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func UploadVideoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err := r.ParseMultipartForm(100 << 20)
|
||||
if err != nil {
|
||||
http.Error(w, "File too large", 400)
|
||||
return
|
||||
}
|
||||
|
||||
file, handler, err := r.FormFile("video")
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid file", 400)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
title := r.FormValue("title")
|
||||
description := r.FormValue("description")
|
||||
|
||||
video, err := SaveVideo(file, handler, title, description)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(video)
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package video
|
||||
|
||||
import "streamin-be/app/database"
|
||||
|
||||
func InsertVideo(v *Video) error {
|
||||
return database.DB.Create(v).Error
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package video
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
func SaveVideo(file multipart.File, handler *multipart.FileHeader, title, description string) (*Video, error) {
|
||||
|
||||
os.MkdirAll("storage/videos", os.ModePerm)
|
||||
|
||||
filename := fmt.Sprintf("%d_%s", time.Now().Unix(), handler.Filename)
|
||||
filePath := filepath.Join("storage/videos", filename)
|
||||
|
||||
dst, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
_, err = io.Copy(dst, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
video := Video{
|
||||
Title: title,
|
||||
Description: description,
|
||||
FileURL: filePath,
|
||||
}
|
||||
|
||||
err = InsertVideo(&video)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &video, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"streamin-be/app/module/video"
|
||||
)
|
||||
|
||||
func InitRouter() {
|
||||
http.HandleFunc("/api/upload", video.UploadVideoHandler)
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
module streamin-be
|
||||
|
||||
go 1.25.3
|
||||
|
||||
require (
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.6.0 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
gorm.io/driver/postgres v1.6.0 // indirect
|
||||
gorm.io/gorm v1.31.1 // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=
|
||||
github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
|
||||
gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
|
||||
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||
Loading…
Reference in New Issue