aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/controllers/demoController.go91
-rw-r--r--backend/controllers/recordController.go126
-rw-r--r--backend/database/init.sql11
-rw-r--r--backend/models/models.go17
-rw-r--r--backend/routes/routes.go2
5 files changed, 146 insertions, 101 deletions
diff --git a/backend/controllers/demoController.go b/backend/controllers/demoController.go
deleted file mode 100644
index 85f6ede..0000000
--- a/backend/controllers/demoController.go
+++ /dev/null
@@ -1,91 +0,0 @@
1package controllers
2
3import (
4 "context"
5 b64 "encoding/base64"
6 "fmt"
7 "io"
8 "log"
9 "net/http"
10 "os"
11
12 "github.com/gin-gonic/gin"
13 "golang.org/x/oauth2/google"
14 "golang.org/x/oauth2/jwt"
15 "google.golang.org/api/drive/v3"
16)
17
18func UploadDemo(c *gin.Context) {
19 // Check if user exists
20 /*user, exists := c.Get("user")
21 if !exists {
22 c.JSON(http.StatusUnauthorized, gin.H{
23 "code": http.StatusUnauthorized,
24 "output": gin.H{
25 "error": "User not logged in. Could be invalid token.",
26 },
27 })
28 return
29 } else {
30 user := user.(models.User)
31 c.JSON(http.StatusOK, gin.H{
32 "code": http.StatusOK,
33 "output": gin.H{
34 "avatar": user.AvatarLink,
35 "country": user.CountryCode,
36 "types": user.TypeToString(),
37 "username": user.Username,
38 },
39 "profile": true,
40 })
41 return
42 }*/
43 f, err := os.Open("pgun_2280.dem")
44 if err != nil {
45 panic(fmt.Sprintf("cannot open file: %v", err))
46 }
47 defer f.Close()
48 client := serviceAccount()
49 srv, err := drive.New(client)
50 if err != nil {
51 log.Fatalf("Unable to retrieve drive Client %v", err)
52 }
53 file, err := createFile(srv, f.Name(), "application/octet-stream", f, os.Getenv("GOOGLE_FOLDER_ID"))
54 if err != nil {
55 panic(fmt.Sprintf("Could not create file: %v\n", err))
56 }
57
58 fmt.Printf("File '%s' successfully uploaded", file.Name)
59 fmt.Printf("\nFile Id: '%s' ", file.Id)
60}
61
62// Use Service account
63func serviceAccount() *http.Client {
64 privateKey, _ := b64.StdEncoding.DecodeString(os.Getenv("GOOGLE_PRIVATE_KEY_BASE64"))
65 config := &jwt.Config{
66 Email: os.Getenv("GOOGLE_CLIENT_EMAIL"),
67 PrivateKey: []byte(privateKey),
68 Scopes: []string{
69 drive.DriveScope,
70 },
71 TokenURL: google.JWTTokenURL,
72 }
73 client := config.Client(context.Background())
74 return client
75}
76
77func createFile(service *drive.Service, name string, mimeType string, content io.Reader, parentId string) (*drive.File, error) {
78 f := &drive.File{
79 MimeType: mimeType,
80 Name: name,
81 Parents: []string{parentId},
82 }
83 file, err := service.Files.Create(f).Media(content).Do()
84
85 if err != nil {
86 log.Println("Could not create file: " + err.Error())
87 return nil, err
88 }
89
90 return file, nil
91}
diff --git a/backend/controllers/recordController.go b/backend/controllers/recordController.go
new file mode 100644
index 0000000..a44d6f6
--- /dev/null
+++ b/backend/controllers/recordController.go
@@ -0,0 +1,126 @@
1package controllers
2
3import (
4 "context"
5 b64 "encoding/base64"
6 "fmt"
7 "io"
8 "log"
9 "net/http"
10 "os"
11 "time"
12
13 "github.com/gin-gonic/gin"
14 "github.com/pektezol/leastportals/backend/database"
15 "github.com/pektezol/leastportals/backend/models"
16 "golang.org/x/oauth2/google"
17 "golang.org/x/oauth2/jwt"
18 "google.golang.org/api/drive/v3"
19)
20
21func CreateRecordWithDemo(c *gin.Context) {
22 mapId := c.Param("id")
23 // Check if user exists
24 user, exists := c.Get("user")
25 if !exists {
26 c.JSON(http.StatusUnauthorized, gin.H{
27 "code": http.StatusUnauthorized,
28 "output": gin.H{
29 "error": "User not logged in. Could be invalid token.",
30 },
31 })
32 return
33 }
34 var record models.Record
35 err := c.Bind(&record)
36 if err != nil {
37 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
38 return
39 }
40 var recordCount int
41 err = database.DB.QueryRow(`SELECT COUNT(id) FROM records;`).Scan(&recordCount)
42 if err != nil {
43 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
44 return
45 }
46 // var mapName string
47 // err = database.DB.QueryRow(`SELECT map_name FROM maps WHERE id = $1;`, mapId).Scan(&mapName)
48 // if err != nil {
49 // c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
50 // return
51 // }
52 outputDemoName := fmt.Sprintf("%s_%s_%d", time.Now().UTC().Format("2006-01-02"), user.(models.User).SteamID, recordCount)
53 header, err := c.FormFile("file")
54 if err != nil {
55 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
56 return
57 }
58 err = c.SaveUploadedFile(header, "docs/"+header.Filename)
59 if err != nil {
60 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
61 return
62 }
63 f, err := os.Open("docs/" + header.Filename)
64 if err != nil {
65 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
66 return
67 }
68 defer f.Close()
69 client := serviceAccount()
70 srv, err := drive.New(client)
71 if err != nil {
72 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
73 return
74 }
75 file, err := createFile(srv, outputDemoName, "application/octet-stream", f, os.Getenv("GOOGLE_FOLDER_ID"))
76 if err != nil {
77 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
78 return
79 }
80 os.Remove("docs/" + header.Filename)
81 // Demo upload success
82 // Insert record into database
83 sql := `INSERT INTO records(map_id,host_id,score_count,score_time,is_coop,partner_id,demo_id)
84 VALUES ($1, $2, $3, $4, $5, $6, $7);`
85 _, err = database.DB.Exec(sql, mapId, user.(models.User).SteamID, record.ScoreCount, record.ScoreTime, record.IsCoop, record.PartnerID, file.Id)
86 if err != nil {
87 c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error()))
88 return
89 }
90 c.JSON(http.StatusOK, models.Response{
91 Success: true,
92 Message: "Successfully created record.",
93 })
94 return
95}
96
97// Use Service account
98func serviceAccount() *http.Client {
99 privateKey, _ := b64.StdEncoding.DecodeString(os.Getenv("GOOGLE_PRIVATE_KEY_BASE64"))
100 config := &jwt.Config{
101 Email: os.Getenv("GOOGLE_CLIENT_EMAIL"),
102 PrivateKey: []byte(privateKey),
103 Scopes: []string{
104 drive.DriveScope,
105 },
106 TokenURL: google.JWTTokenURL,
107 }
108 client := config.Client(context.Background())
109 return client
110}
111
112func createFile(service *drive.Service, name string, mimeType string, content io.Reader, parentId string) (*drive.File, error) {
113 f := &drive.File{
114 MimeType: mimeType,
115 Name: name,
116 Parents: []string{parentId},
117 }
118 file, err := service.Files.Create(f).Media(content).Do()
119
120 if err != nil {
121 log.Println("Could not create file: " + err.Error())
122 return nil, err
123 }
124
125 return file, nil
126}
diff --git a/backend/database/init.sql b/backend/database/init.sql
index 4f68e0d..f69bf10 100644
--- a/backend/database/init.sql
+++ b/backend/database/init.sql
@@ -25,12 +25,14 @@ CREATE TABLE maps (
25 25
26CREATE TABLE records ( 26CREATE TABLE records (
27 id SERIAL, 27 id SERIAL,
28 map_id SMALLINT, 28 map_id SMALLINT NOT NULL,
29 host_id TEXT NOT NULL, 29 host_id TEXT NOT NULL,
30 score_count SMALLINT NOT NULL, 30 score_count SMALLINT NOT NULL,
31 score_time INTEGER NOT NULL, 31 score_time INTEGER NOT NULL,
32 is_coop BOOLEAN NOT NULL DEFAULT false, 32 is_coop BOOLEAN NOT NULL DEFAULT false,
33 partner_id TEXT NOT NULL DEFAULT '', 33 partner_id TEXT NOT NULL DEFAULT '',
34 demo_id TEXT NOT NULL,
35 record_date TIMESTAMP NOT NULL DEFAULT now(),
34 PRIMARY KEY (id), 36 PRIMARY KEY (id),
35 FOREIGN KEY (map_id) REFERENCES maps(id), 37 FOREIGN KEY (map_id) REFERENCES maps(id),
36 FOREIGN KEY (host_id) REFERENCES users(steam_id), 38 FOREIGN KEY (host_id) REFERENCES users(steam_id),
@@ -42,11 +44,4 @@ CREATE TABLE titles (
42 title_name TEXT NOT NULL, 44 title_name TEXT NOT NULL,
43 PRIMARY KEY (user_id), 45 PRIMARY KEY (user_id),
44 FOREIGN KEY (user_id) REFERENCES users(steam_id) 46 FOREIGN KEY (user_id) REFERENCES users(steam_id)
45);
46
47CREATE TABLE showcases (
48 record_id INT,
49 video_id TEXT NOT NULL,
50 PRIMARY KEY (record_id),
51 FOREIGN KEY (record_id) REFERENCES records(id)
52); \ No newline at end of file 47); \ No newline at end of file
diff --git a/backend/models/models.go b/backend/models/models.go
index c49eaeb..994a1e7 100644
--- a/backend/models/models.go
+++ b/backend/models/models.go
@@ -1,6 +1,9 @@
1package models 1package models
2 2
3import "time" 3import (
4 "mime/multipart"
5 "time"
6)
4 7
5type User struct { 8type User struct {
6 SteamID string `json:"steam_id"` 9 SteamID string `json:"steam_id"`
@@ -10,3 +13,15 @@ type User struct {
10 CreatedAt time.Time `json:"created_at"` 13 CreatedAt time.Time `json:"created_at"`
11 UpdatedAt time.Time `json:"updated_at"` 14 UpdatedAt time.Time `json:"updated_at"`
12} 15}
16
17type Record struct {
18 MapID int `json:"map_id" binding:"required"`
19 ScoreCount int `json:"score_count" binding:"required"`
20 ScoreTime int `json:"score_time" binding:"required"`
21 IsCoop bool `json:"is_coop" binding:"required"`
22 PartnerID string `json:"partner_id"`
23}
24
25type ds struct {
26 File *multipart.FileHeader `form:"file" binding:"required"`
27}
diff --git a/backend/routes/routes.go b/backend/routes/routes.go
index 6ca1d46..f9256ca 100644
--- a/backend/routes/routes.go
+++ b/backend/routes/routes.go
@@ -17,6 +17,6 @@ func InitRoutes(router *gin.Engine) {
17 v1.GET("/login", controllers.Login) 17 v1.GET("/login", controllers.Login)
18 v1.GET("/profile", middleware.CheckAuth, controllers.Profile) 18 v1.GET("/profile", middleware.CheckAuth, controllers.Profile)
19 v1.GET("/user/:id", middleware.CheckAuth, controllers.FetchUser) 19 v1.GET("/user/:id", middleware.CheckAuth, controllers.FetchUser)
20 v1.POST("/demo/", middleware.CheckAuth, controllers.UploadDemo) 20 v1.POST("/record/:id", middleware.CheckAuth, controllers.CreateRecordWithDemo)
21 } 21 }
22} 22}