forked from knadh/listmonk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
media.go
128 lines (112 loc) · 3.37 KB
/
media.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"fmt"
"net/http"
"strconv"
"github.com/knadh/listmonk/media"
"github.com/labstack/echo"
uuid "github.com/satori/go.uuid"
)
var imageMimes = []string{"image/jpg", "image/jpeg", "image/png", "image/svg", "image/gif"}
const (
thumbPrefix = "thumb_"
thumbnailSize = 90
)
// handleUploadMedia handles media file uploads.
func handleUploadMedia(c echo.Context) error {
var (
app = c.Get("app").(*App)
cleanUp = false
)
file, err := c.FormFile("file")
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Invalid file uploaded: %v", err))
}
// Validate MIME type with the list of allowed types.
var typ = file.Header.Get("Content-type")
ok := validateMIME(typ, imageMimes)
if !ok {
return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Unsupported file type (%s) uploaded.", typ))
}
// Generate filename
fName := generateFileName(file.Filename)
// Read file contents in memory
src, err := file.Open()
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error reading file: %s", err))
}
defer src.Close()
// Upload the file.
fName, err = app.Media.Put(fName, typ, src)
if err != nil {
cleanUp = true
return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error uploading file: %s", err))
}
defer func() {
// If any of the subroutines in this function fail,
// the uploaded image should be removed.
if cleanUp {
app.Media.Delete(fName)
app.Media.Delete(thumbPrefix + fName)
}
}()
// Create thumbnail from file.
thumbFile, err := createThumbnail(file)
if err != nil {
cleanUp = true
return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error opening image for resizing: %s", err))
}
// Upload thumbnail.
thumbfName, err := app.Media.Put(thumbPrefix+fName, typ, thumbFile)
if err != nil {
cleanUp = true
return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error saving thumbnail: %s", err))
}
// Write to the DB.
if _, err := app.Queries.InsertMedia.Exec(uuid.NewV4(), fName, thumbfName, 0, 0); err != nil {
cleanUp = true
return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error saving uploaded file to db: %s", pqErrMsg(err)))
}
return c.JSON(http.StatusOK, okResp{true})
}
// handleGetMedia handles retrieval of uploaded media.
func handleGetMedia(c echo.Context) error {
var (
app = c.Get("app").(*App)
out []media.Media
)
if err := app.Queries.GetMedia.Select(&out); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching media list: %s", pqErrMsg(err)))
}
for i := 0; i < len(out); i++ {
out[i].URI = app.Media.Get(out[i].Filename)
out[i].ThumbURI = app.Media.Get(thumbPrefix + out[i].Filename)
}
return c.JSON(http.StatusOK, okResp{out})
}
// deleteMedia handles deletion of uploaded media.
func handleDeleteMedia(c echo.Context) error {
var (
app = c.Get("app").(*App)
id, _ = strconv.Atoi(c.Param("id"))
)
if id < 1 {
return echo.NewHTTPError(http.StatusBadRequest, "Invalid ID.")
}
var m media.Media
if err := app.Queries.DeleteMedia.Get(&m, id); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error deleting media: %s", pqErrMsg(err)))
}
app.Media.Delete(m.Filename)
app.Media.Delete(thumbPrefix + m.Filename)
return c.JSON(http.StatusOK, okResp{true})
}