1
1
package main
2
2
3
3
import (
4
+ "crypto/rand"
5
+ "encoding/base64"
4
6
"fmt"
7
+ "io"
8
+ "mime"
5
9
"net/http"
10
+ "os"
11
+ "path/filepath"
6
12
7
13
"github.com/bootdotdev/learn-file-storage-s3-golang-starter/internal/auth"
8
14
"github.com/google/uuid"
@@ -28,10 +34,67 @@ func (cfg *apiConfig) handlerUploadThumbnail(w http.ResponseWriter, r *http.Requ
28
34
return
29
35
}
30
36
31
-
32
37
fmt .Println ("uploading thumbnail for video" , videoID , "by user" , userID )
33
38
34
- // TODO: implement the upload here
39
+ const maxMemory = 10 << 20
40
+ r .ParseMultipartForm (maxMemory )
41
+
42
+ file , header , err := r .FormFile ("thumbnail" )
43
+ if err != nil {
44
+ respondWithError (w , http .StatusBadRequest , "Unable to parse form file" , err )
45
+ return
46
+ }
47
+ defer file .Close ()
48
+
49
+ mimeType := header .Header .Get ("Content-Type" )
50
+ mediaType , _ , err := mime .ParseMediaType (mimeType )
51
+ if mediaType != "image/jpeg" && mediaType != "image/png" {
52
+ respondWithError (w , http .StatusBadRequest , "Upload a valid jpeg/png" , err )
53
+ return
54
+ }
55
+
56
+ extensions , err := mime .ExtensionsByType (mimeType )
57
+ if err != nil || len (extensions ) == 0 {
58
+ respondWithError (w , http .StatusBadRequest , "Invalid file format" , err )
59
+ return
60
+ }
61
+
62
+ video , err := cfg .db .GetVideo (videoID )
63
+ if err != nil || video .UserID != userID {
64
+ respondWithError (w , http .StatusUnauthorized , "Unauthorized" , err )
65
+ return
66
+ }
67
+
68
+ b := make ([]byte , 32 )
69
+ _ , err = rand .Read (b )
70
+ if err != nil {
71
+ respondWithError (w , http .StatusInternalServerError , "Internal Server Error" , err )
72
+ return
73
+ }
74
+
75
+ filenameNoExt := base64 .RawURLEncoding .EncodeToString (b )
76
+
77
+ filename := filepath .Join (cfg .assetsRoot , filenameNoExt + extensions [0 ])
78
+ newfile , err := os .Create (filename )
79
+ if err != nil {
80
+ respondWithError (w , http .StatusInternalServerError , "Internal Server Error" , err )
81
+ return
82
+ }
83
+
84
+ _ , err = io .Copy (newfile , file )
85
+ if err != nil {
86
+ respondWithError (w , http .StatusInternalServerError , "Internal Server Error" , err )
87
+ return
88
+ }
89
+
90
+ thumbnailURL := fmt .Sprintf ("http://localhost:%s/assets/%s" , cfg .port , filenameNoExt + extensions [0 ])
91
+ video .ThumbnailURL = & thumbnailURL
92
+
93
+ err = cfg .db .UpdateVideo (video )
94
+ if err != nil {
95
+ respondWithError (w , http .StatusInternalServerError , "Error uploading video thumbnail" , err )
96
+ return
97
+ }
35
98
36
- respondWithJSON (w , http .StatusOK , struct {}{} )
99
+ respondWithJSON (w , http .StatusOK , video )
37
100
}
0 commit comments