mirror of
https://github.com/knadh/listmonk.git
synced 2025-10-06 05:16:48 +08:00
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"
|
"strconv"
|
||||||
|
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
|
"github.com/knadh/listmonk/models"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ func handleUploadMedia(c echo.Context) error {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Create thumbnail from file.
|
// Create thumbnail from file.
|
||||||
thumbFile, err := createThumbnail(file)
|
thumbFile, width, height, err := processImage(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cleanUp = true
|
cleanUp = true
|
||||||
app.log.Printf("error resizing image: %v", err)
|
app.log.Printf("error resizing image: %v", err)
|
||||||
|
@ -96,7 +97,11 @@ func handleUploadMedia(c echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to the DB.
|
// 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 {
|
if err != nil {
|
||||||
cleanUp = true
|
cleanUp = true
|
||||||
return err
|
return err
|
||||||
|
@ -150,17 +155,18 @@ func handleDeleteMedia(c echo.Context) error {
|
||||||
return c.JSON(http.StatusOK, okResp{true})
|
return c.JSON(http.StatusOK, okResp{true})
|
||||||
}
|
}
|
||||||
|
|
||||||
// createThumbnail reads the file object and returns a smaller image
|
// processImage reads the image file and returns thumbnail bytes and
|
||||||
func createThumbnail(file *multipart.FileHeader) (*bytes.Reader, error) {
|
// the original image's width, and height.
|
||||||
|
func processImage(file *multipart.FileHeader) (*bytes.Reader, int, int, error) {
|
||||||
src, err := file.Open()
|
src, err := file.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
defer src.Close()
|
defer src.Close()
|
||||||
|
|
||||||
img, err := imaging.Decode(src)
|
img, err := imaging.Decode(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode the image into a byte slice as PNG.
|
// Encode the image into a byte slice as PNG.
|
||||||
|
@ -169,7 +175,9 @@ func createThumbnail(file *multipart.FileHeader) (*bytes.Reader, error) {
|
||||||
out bytes.Buffer
|
out bytes.Buffer
|
||||||
)
|
)
|
||||||
if err := imaging.Encode(&out, thumb, imaging.PNG); err != nil {
|
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.0.0", migrations.V2_0_0},
|
||||||
{"v2.1.0", migrations.V2_1_0},
|
{"v2.1.0", migrations.V2_1_0},
|
||||||
{"v2.2.0", migrations.V2_2_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
|
// upgrade upgrades the database to the current version by running SQL migration files
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
"github.com/knadh/listmonk/internal/media"
|
"github.com/knadh/listmonk/internal/media"
|
||||||
|
"github.com/knadh/listmonk/models"
|
||||||
"github.com/labstack/echo/v4"
|
"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.
|
// 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()
|
uu, err := uuid.NewV4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.log.Printf("error generating UUID: %v", err)
|
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.
|
// Write to the DB.
|
||||||
var newID int
|
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)
|
c.log.Printf("error inserting uploaded file to db: %v", err)
|
||||||
return media.Media{}, echo.NewHTTPError(http.StatusInternalServerError,
|
return media.Media{}, echo.NewHTTPError(http.StatusInternalServerError,
|
||||||
c.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.media}", "error", pqErrMsg(err)))
|
c.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.media}", "error", pqErrMsg(err)))
|
||||||
|
|
|
@ -3,6 +3,7 @@ package media
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/knadh/listmonk/models"
|
||||||
"gopkg.in/volatiletech/null.v6"
|
"gopkg.in/volatiletech/null.v6"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ type Media struct {
|
||||||
CreatedAt null.Time `db:"created_at" json:"created_at"`
|
CreatedAt null.Time `db:"created_at" json:"created_at"`
|
||||||
ThumbURL string `json:"thumb_url"`
|
ThumbURL string `json:"thumb_url"`
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
|
Meta models.JSON `db:"meta" json:"meta"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
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
|
-- media
|
||||||
-- name: insert-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
|
-- name: get-all-media
|
||||||
SELECT * FROM media WHERE provider=$1 ORDER BY created_at DESC;
|
SELECT * FROM media WHERE provider=$1 ORDER BY created_at DESC;
|
||||||
|
|
|
@ -139,6 +139,7 @@ CREATE TABLE media (
|
||||||
provider TEXT NOT NULL DEFAULT '',
|
provider TEXT NOT NULL DEFAULT '',
|
||||||
filename TEXT NOT NULL,
|
filename TEXT NOT NULL,
|
||||||
thumb TEXT NOT NULL,
|
thumb TEXT NOT NULL,
|
||||||
|
meta JSONB NOT NULL DEFAULT '{}',
|
||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue