Add arbitrary meta
field to media. Closes #938.
- Add new `meta` JSONB field to `media` table. - Start storing image width and height as meta with media uploads.
This commit is contained in:
parent
c3d04a5490
commit
c38100427d
7 changed files with 48 additions and 19 deletions
24
cmd/media.go
24
cmd/media.go
|
@ -8,6 +8,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/knadh/listmonk/models"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
|
@ -78,7 +79,7 @@ func handleUploadMedia(c echo.Context) error {
|
|||
}()
|
||||
|
||||
// Create thumbnail from file.
|
||||
thumbFile, err := createThumbnail(file)
|
||||
thumbFile, width, height, err := processImage(file)
|
||||
if err != nil {
|
||||
cleanUp = true
|
||||
app.log.Printf("error resizing image: %v", err)
|
||||
|
@ -96,7 +97,11 @@ func handleUploadMedia(c echo.Context) error {
|
|||
}
|
||||
|
||||
// Write to the DB.
|
||||
m, err := app.core.InsertMedia(fName, thumbfName, app.constants.MediaProvider, app.media)
|
||||
meta := models.JSON{
|
||||
"width": width,
|
||||
"height": height,
|
||||
}
|
||||
m, err := app.core.InsertMedia(fName, thumbfName, meta, app.constants.MediaProvider, app.media)
|
||||
if err != nil {
|
||||
cleanUp = true
|
||||
return err
|
||||
|
@ -150,17 +155,18 @@ func handleDeleteMedia(c echo.Context) error {
|
|||
return c.JSON(http.StatusOK, okResp{true})
|
||||
}
|
||||
|
||||
// createThumbnail reads the file object and returns a smaller image
|
||||
func createThumbnail(file *multipart.FileHeader) (*bytes.Reader, error) {
|
||||
// processImage reads the image file and returns thumbnail bytes and
|
||||
// the original image's width, and height.
|
||||
func processImage(file *multipart.FileHeader) (*bytes.Reader, int, int, error) {
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
img, err := imaging.Decode(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
// Encode the image into a byte slice as PNG.
|
||||
|
@ -169,7 +175,9 @@ func createThumbnail(file *multipart.FileHeader) (*bytes.Reader, error) {
|
|||
out bytes.Buffer
|
||||
)
|
||||
if err := imaging.Encode(&out, thumb, imaging.PNG); err != nil {
|
||||
return nil, err
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
return bytes.NewReader(out.Bytes()), nil
|
||||
|
||||
b := img.Bounds().Max
|
||||
return bytes.NewReader(out.Bytes()), b.X, b.Y, nil
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ var migList = []migFunc{
|
|||
{"v2.0.0", migrations.V2_0_0},
|
||||
{"v2.1.0", migrations.V2_1_0},
|
||||
{"v2.2.0", migrations.V2_2_0},
|
||||
{"v2.3.0", migrations.V2_3_0},
|
||||
}
|
||||
|
||||
// upgrade upgrades the database to the current version by running SQL migration files
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/knadh/listmonk/internal/media"
|
||||
"github.com/knadh/listmonk/models"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
|
@ -45,7 +46,7 @@ func (c *Core) GetMedia(id int, uuid string, s media.Store) (media.Media, error)
|
|||
}
|
||||
|
||||
// InsertMedia inserts a new media file into the DB.
|
||||
func (c *Core) InsertMedia(fileName, thumbName string, provider string, s media.Store) (media.Media, error) {
|
||||
func (c *Core) InsertMedia(fileName, thumbName string, meta models.JSON, provider string, s media.Store) (media.Media, error) {
|
||||
uu, err := uuid.NewV4()
|
||||
if err != nil {
|
||||
c.log.Printf("error generating UUID: %v", err)
|
||||
|
@ -55,7 +56,7 @@ func (c *Core) InsertMedia(fileName, thumbName string, provider string, s media.
|
|||
|
||||
// Write to the DB.
|
||||
var newID int
|
||||
if err := c.q.InsertMedia.Get(&newID, uu, fileName, thumbName, provider); err != nil {
|
||||
if err := c.q.InsertMedia.Get(&newID, uu, fileName, thumbName, provider, meta); err != nil {
|
||||
c.log.Printf("error inserting uploaded file to db: %v", err)
|
||||
return media.Media{}, echo.NewHTTPError(http.StatusInternalServerError,
|
||||
c.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.media}", "error", pqErrMsg(err)))
|
||||
|
|
|
@ -3,19 +3,21 @@ package media
|
|||
import (
|
||||
"io"
|
||||
|
||||
"github.com/knadh/listmonk/models"
|
||||
"gopkg.in/volatiletech/null.v6"
|
||||
)
|
||||
|
||||
// Media represents an uploaded object.
|
||||
type Media struct {
|
||||
ID int `db:"id" json:"id"`
|
||||
UUID string `db:"uuid" json:"uuid"`
|
||||
Filename string `db:"filename" json:"filename"`
|
||||
Thumb string `db:"thumb" json:"thumb"`
|
||||
CreatedAt null.Time `db:"created_at" json:"created_at"`
|
||||
ThumbURL string `json:"thumb_url"`
|
||||
Provider string `json:"provider"`
|
||||
URL string `json:"url"`
|
||||
ID int `db:"id" json:"id"`
|
||||
UUID string `db:"uuid" json:"uuid"`
|
||||
Filename string `db:"filename" json:"filename"`
|
||||
Thumb string `db:"thumb" json:"thumb"`
|
||||
CreatedAt null.Time `db:"created_at" json:"created_at"`
|
||||
ThumbURL string `json:"thumb_url"`
|
||||
Provider string `json:"provider"`
|
||||
Meta models.JSON `db:"meta" json:"meta"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// Store represents functions to store and retrieve media (files).
|
||||
|
|
16
internal/migrations/v2.3.0.go
Normal file
16
internal/migrations/v2.3.0.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/knadh/koanf"
|
||||
"github.com/knadh/stuffbin"
|
||||
)
|
||||
|
||||
// V2_2_0 performs the DB migrations for v.2.2.0.
|
||||
func V2_3_0(db *sqlx.DB, fs stuffbin.FileSystem, ko *koanf.Koanf) error {
|
||||
if _, err := db.Exec(`ALTER TABLE media ADD COLUMN IF NOT EXISTS "meta" JSONB NOT NULL DEFAULT '{}'`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -811,7 +811,7 @@ SELECT id FROM tpl;
|
|||
|
||||
-- media
|
||||
-- name: insert-media
|
||||
INSERT INTO media (uuid, filename, thumb, provider, created_at) VALUES($1, $2, $3, $4, NOW()) RETURNING id;
|
||||
INSERT INTO media (uuid, filename, thumb, provider, meta, created_at) VALUES($1, $2, $3, $4, $5, NOW()) RETURNING id;
|
||||
|
||||
-- name: get-all-media
|
||||
SELECT * FROM media WHERE provider=$1 ORDER BY created_at DESC;
|
||||
|
|
|
@ -139,6 +139,7 @@ CREATE TABLE media (
|
|||
provider TEXT NOT NULL DEFAULT '',
|
||||
filename TEXT NOT NULL,
|
||||
thumb TEXT NOT NULL,
|
||||
meta JSONB NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue