From 5ec2e0b89ede11fdf3bce166fedd79f96ef280ff Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 21:26:51 +0100 Subject: [PATCH 01/11] feat: add migration to create BlurHash strings for all list backgrounds --- go.mod | 1 + go.sum | 3 ++ pkg/initialize/init.go | 6 +-- pkg/migration/20211212210054.go | 94 +++++++++++++++++++++++++++++++++ pkg/models/list.go | 2 + 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 pkg/migration/20211212210054.go diff --git a/go.mod b/go.mod index 01adc7377..8e08ec26d 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/ThreeDotsLabs/watermill v1.1.1 github.com/adlio/trello v1.9.0 github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef + github.com/bbrks/go-blurhash v1.1.1 // indirect github.com/beevik/etree v1.1.0 // indirect github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2 github.com/coreos/go-oidc/v3 v3.1.0 diff --git a/go.sum b/go.sum index 0d53dc01a..46cd63303 100644 --- a/go.sum +++ b/go.sum @@ -99,6 +99,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/bbrks/go-blurhash v1.1.1 h1:uoXOxRPDca9zHYabUTwvS4KnY++KKUbwFo+Yxb8ME4M= +github.com/bbrks/go-blurhash v1.1.1/go.mod h1:lkAsdyXp+EhARcUo85yS2G1o+Sh43I2ebF5togC4bAY= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -531,6 +533,7 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= diff --git a/pkg/initialize/init.go b/pkg/initialize/init.go index b2b0d3b54..6af4068d3 100644 --- a/pkg/initialize/init.go +++ b/pkg/initialize/init.go @@ -78,15 +78,15 @@ func FullInit() { LightInit() + // Initialize the files handler + files.InitFileHandler() + // Run the migrations migration.Migrate(nil) // Set Engine InitEngines() - // Initialize the files handler - files.InitFileHandler() - // Start the mail daemon mail.StartMailDaemon() diff --git a/pkg/migration/20211212210054.go b/pkg/migration/20211212210054.go new file mode 100644 index 000000000..9ccab10bf --- /dev/null +++ b/pkg/migration/20211212210054.go @@ -0,0 +1,94 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-2021 Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public Licensee as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public Licensee for more details. +// +// You should have received a copy of the GNU Affero General Public Licensee +// along with this program. If not, see . + +package migration + +import ( + "code.vikunja.io/api/pkg/files" + "code.vikunja.io/api/pkg/log" + "github.com/bbrks/go-blurhash" + "golang.org/x/image/draw" + "image" + "src.techknowlogick.com/xormigrate" + "xorm.io/xorm" +) + +type lists20211212210054 struct { + ID int64 `xorm:"bigint autoincr not null unique pk" json:"id" param:"list"` + BackgroundFileID int64 `xorm:"null" json:"-"` + BackgroundBlurHash string `xorm:"varchar(50) null" json:"background_blur_hash"` +} + +func (lists20211212210054) TableName() string { + return "lists" +} + +func init() { + migrations = append(migrations, &xormigrate.Migration{ + ID: "20211212210054", + Description: "Add blurHash to list backgrounds.", + Migrate: func(tx *xorm.Engine) error { + err := tx.Sync2(lists20211212210054{}) + if err != nil { + return err + } + + lists := []*lists20211212210054{} + err = tx.Where("background_file_id is not null AND background_file_id != ?", 0).Find(&lists) + if err != nil { + return err + } + + log.Infof("Creating BlurHash for %d list backgrounds, this might take a while...", len(lists)) + + for _, l := range lists { + bgFile := &files.File{ + ID: l.BackgroundFileID, + } + if err := bgFile.LoadFileByID(); err != nil { + return err + } + + src, _, err := image.Decode(bgFile.File) + if err != nil { + return err + } + + dst := image.NewRGBA(image.Rect(0, 0, 32, 32)) + draw.NearestNeighbor.Scale(dst, dst.Rect, src, src.Bounds(), draw.Over, nil) + + hash, err := blurhash.Encode(4, 3, dst) + if err != nil { + return err + } + + l.BackgroundBlurHash = hash + _, err = tx.Where("id = ?", l.ID). + Cols("background_blur_hash"). + Update(l) + if err != nil { + return err + } + log.Debugf("Created BlurHash for list %d", l.ID) + } + + return nil + }, + Rollback: func(tx *xorm.Engine) error { + return nil + }, + }) +} diff --git a/pkg/models/list.go b/pkg/models/list.go index 513f388b2..493220df5 100644 --- a/pkg/models/list.go +++ b/pkg/models/list.go @@ -59,6 +59,8 @@ type List struct { BackgroundFileID int64 `xorm:"null" json:"-"` // Holds extra information about the background set since some background providers require attribution or similar. If not null, the background can be accessed at /lists/{listID}/background BackgroundInformation interface{} `xorm:"-" json:"background_information"` + // Contains a very small version of the list background to use as a blurry preview until the actual background is loaded. Check out https://blurha.sh/ to learn how it works. + BackgroundBlurHash string `xorm:"varchar(50) null" json:"background_blur_hash"` // True if a list is a favorite. Favorite lists show up in a separate namespace. This value depends on the user making the call to the api. IsFavorite bool `xorm:"-" json:"is_favorite"` -- 2.45.1 From 4b40e0e28311ef4895b073044fc3e8d644a5faf7 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 21:42:35 +0100 Subject: [PATCH 02/11] feat: generate a BlurHash when uploading a new image --- pkg/models/list.go | 11 +++--- pkg/models/list_duplicate.go | 2 +- pkg/modules/background/handler/background.go | 37 +++++++++++++++---- pkg/modules/background/upload/upload.go | 6 +-- .../migration/create_from_structure.go | 8 +++- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/pkg/models/list.go b/pkg/models/list.go index 493220df5..8857050fa 100644 --- a/pkg/models/list.go +++ b/pkg/models/list.go @@ -640,7 +640,7 @@ func UpdateList(s *xorm.Session, list *List, auth web.Auth, updateListBackground } if updateListBackground { - colsToUpdate = append(colsToUpdate, "background_file_id") + colsToUpdate = append(colsToUpdate, "background_file_id", "background_blur_hash") } wasFavorite, err := isFavorite(s, list.ID, auth, FavoriteKindList) @@ -801,14 +801,15 @@ func (l *List) Delete(s *xorm.Session, a web.Auth) (err error) { } // SetListBackground sets a background file as list background in the db -func SetListBackground(s *xorm.Session, listID int64, background *files.File) (err error) { +func SetListBackground(s *xorm.Session, listID int64, background *files.File, blurHash string) (err error) { l := &List{ - ID: listID, - BackgroundFileID: background.ID, + ID: listID, + BackgroundFileID: background.ID, + BackgroundBlurHash: blurHash, } _, err = s. Where("id = ?", l.ID). - Cols("background_file_id"). + Cols("background_file_id", "background_blur_hash"). Update(l) return } diff --git a/pkg/models/list_duplicate.go b/pkg/models/list_duplicate.go index 33cf7e2cf..5b1e51acb 100644 --- a/pkg/models/list_duplicate.go +++ b/pkg/models/list_duplicate.go @@ -144,7 +144,7 @@ func (ld *ListDuplicate) Create(s *xorm.Session, doer web.Auth) (err error) { } } - if err := SetListBackground(s, ld.List.ID, file); err != nil { + if err := SetListBackground(s, ld.List.ID, file, ld.List.BackgroundBlurHash); err != nil { return err } diff --git a/pkg/modules/background/handler/background.go b/pkg/modules/background/handler/background.go index 5ea40a808..13b15e5ab 100644 --- a/pkg/modules/background/handler/background.go +++ b/pkg/modules/background/handler/background.go @@ -17,6 +17,9 @@ package handler import ( + "github.com/bbrks/go-blurhash" + "golang.org/x/image/draw" + "image" "io" "net/http" "strconv" @@ -134,6 +137,18 @@ func (bp *BackgroundProvider) SetBackground(c echo.Context) error { return c.JSON(http.StatusOK, list) } +func CreateBlurHash(srcf io.Reader) (hash string, err error) { + src, _, err := image.Decode(srcf) + if err != nil { + return "", err + } + + dst := image.NewRGBA(image.Rect(0, 0, 32, 32)) + draw.NearestNeighbor.Scale(dst, dst.Rect, src, src.Bounds(), draw.Over, nil) + + return blurhash.Encode(4, 3, dst) +} + // UploadBackground uploads a background and passes the id of the uploaded file as an Image to the Set function of the BackgroundProvider. func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { s := db.NewSession() @@ -153,15 +168,15 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { _ = s.Rollback() return err } - src, err := file.Open() + srcf, err := file.Open() if err != nil { _ = s.Rollback() return err } - defer src.Close() + defer srcf.Close() // Validate we're dealing with an image - mime, err := mimetype.DetectReader(src) + mime, err := mimetype.DetectReader(srcf) if err != nil { _ = s.Rollback() return handler.HandleHTTPError(err, c) @@ -170,10 +185,10 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { _ = s.Rollback() return c.JSON(http.StatusBadRequest, models.Message{Message: "Uploaded file is no image."}) } - _, _ = src.Seek(0, io.SeekStart) + _, _ = srcf.Seek(0, io.SeekStart) // Save the file - f, err := files.CreateWithMime(src, file.Filename, uint64(file.Size), auth, mime.String()) + f, err := files.CreateWithMime(srcf, file.Filename, uint64(file.Size), auth, mime.String()) if err != nil { _ = s.Rollback() if files.IsErrFileIsTooLarge(err) { @@ -183,9 +198,16 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { return handler.HandleHTTPError(err, c) } - image := &background.Image{ID: strconv.FormatInt(f.ID, 10)} + // Generate a blurHash + _, _ = srcf.Seek(0, io.SeekStart) + list.BackgroundBlurHash, err = CreateBlurHash(srcf) + if err != nil { + return handler.HandleHTTPError(err, c) + } - err = p.Set(s, image, list, auth) + // Save it + img := &background.Image{ID: strconv.FormatInt(f.ID, 10)} + err = p.Set(s, img, list, auth) if err != nil { _ = s.Rollback() return handler.HandleHTTPError(err, c) @@ -300,6 +322,7 @@ func RemoveListBackground(c echo.Context) error { list.BackgroundFileID = 0 list.BackgroundInformation = nil + list.BackgroundBlurHash = "" err = models.UpdateList(s, list, auth, true) if err != nil { return err diff --git a/pkg/modules/background/upload/upload.go b/pkg/modules/background/upload/upload.go index 2597cb897..3bd3d5fea 100644 --- a/pkg/modules/background/upload/upload.go +++ b/pkg/modules/background/upload/upload.go @@ -52,7 +52,7 @@ func (p *Provider) Search(s *xorm.Session, search string, page int64) (result [] // @Failure 404 {object} models.Message "The list does not exist." // @Failure 500 {object} models.Message "Internal error" // @Router /lists/{id}/backgrounds/upload [put] -func (p *Provider) Set(s *xorm.Session, image *background.Image, list *models.List, auth web.Auth) (err error) { +func (p *Provider) Set(s *xorm.Session, img *background.Image, list *models.List, auth web.Auth) (err error) { // Remove the old background if one exists if list.BackgroundFileID != 0 { file := files.File{ID: list.BackgroundFileID} @@ -62,12 +62,12 @@ func (p *Provider) Set(s *xorm.Session, image *background.Image, list *models.Li } file := &files.File{} - file.ID, err = strconv.ParseInt(image.ID, 10, 64) + file.ID, err = strconv.ParseInt(img.ID, 10, 64) if err != nil { return } list.BackgroundInformation = &models.ListBackgroundType{Type: models.ListBackgroundUpload} - return models.SetListBackground(s, list.ID, file) + return models.SetListBackground(s, list.ID, file, list.BackgroundBlurHash) } diff --git a/pkg/modules/migration/create_from_structure.go b/pkg/modules/migration/create_from_structure.go index 7905e80fa..2aa9169ed 100644 --- a/pkg/modules/migration/create_from_structure.go +++ b/pkg/modules/migration/create_from_structure.go @@ -18,6 +18,7 @@ package migration import ( "bytes" + "code.vikunja.io/api/pkg/modules/background/handler" "io/ioutil" "xorm.io/xorm" @@ -115,7 +116,12 @@ func insertFromStructure(s *xorm.Session, str []*models.NamespaceWithListsAndTas return err } - err = models.SetListBackground(s, l.ID, file) + hash, err := handler.CreateBlurHash(backgroundFile) + if err != nil { + return err + } + + err = models.SetListBackground(s, l.ID, file, hash) if err != nil { return err } -- 2.45.1 From c07d3214627e28d931547bfa38403b50e23ebfd5 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 21:45:06 +0100 Subject: [PATCH 03/11] feat: save BlurHash from unsplash when selecting a photo from unsplash --- pkg/modules/background/unsplash/unsplash.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/modules/background/unsplash/unsplash.go b/pkg/modules/background/unsplash/unsplash.go index f097c6da0..60fd14ecf 100644 --- a/pkg/modules/background/unsplash/unsplash.go +++ b/pkg/modules/background/unsplash/unsplash.go @@ -61,6 +61,7 @@ type Photo struct { Height int `json:"height"` Color string `json:"color"` Description string `json:"description"` + BlurHash string `json:"blur_hash"` User struct { Username string `json:"username"` Name string `json:"name"` @@ -315,7 +316,7 @@ func (p *Provider) Set(s *xorm.Session, image *background.Image, list *models.Li list.BackgroundInformation = unsplashPhoto // Set it as the list background - return models.SetListBackground(s, list.ID, file) + return models.SetListBackground(s, list.ID, file, photo.BlurHash) } // Pingback pings the unsplash api if an unsplash photo has been accessed. -- 2.45.1 From 299e042497a3e3ba9f85c10acfeefc6389aa23e6 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 21:49:42 +0100 Subject: [PATCH 04/11] feat: return BlurHash for unsplash search results --- pkg/modules/background/background.go | 7 ++++--- pkg/modules/background/unsplash/unsplash.go | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/modules/background/background.go b/pkg/modules/background/background.go index 057a446c7..bd6cc2ab1 100644 --- a/pkg/modules/background/background.go +++ b/pkg/modules/background/background.go @@ -24,9 +24,10 @@ import ( // Image represents an image which can be used as a list background type Image struct { - ID string `json:"id"` - URL string `json:"url"` - Thumb string `json:"thumb,omitempty"` + ID string `json:"id"` + URL string `json:"url"` + Thumb string `json:"thumb,omitempty"` + BlurHash string `json:"blur_hash"` // This can be used to supply extra information from an image provider to clients Info interface{} `json:"info,omitempty"` } diff --git a/pkg/modules/background/unsplash/unsplash.go b/pkg/modules/background/unsplash/unsplash.go index 60fd14ecf..02d0e47bc 100644 --- a/pkg/modules/background/unsplash/unsplash.go +++ b/pkg/modules/background/unsplash/unsplash.go @@ -179,8 +179,9 @@ func (p *Provider) Search(s *xorm.Session, search string, page int64) (result [] result = []*background.Image{} for _, p := range collectionResult { result = append(result, &background.Image{ - ID: p.ID, - URL: getImageID(p.Urls.Raw), + ID: p.ID, + URL: getImageID(p.Urls.Raw), + BlurHash: p.BlurHash, Info: &models.UnsplashPhoto{ UnsplashID: p.ID, Author: p.User.Username, -- 2.45.1 From 3b9e2d0b8420edfedd33dae0fe06f21d7b92c5ed Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 21:50:13 +0100 Subject: [PATCH 05/11] fix: lint --- pkg/migration/20211212210054.go | 3 ++- pkg/modules/background/handler/background.go | 5 +++-- pkg/modules/migration/create_from_structure.go | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/migration/20211212210054.go b/pkg/migration/20211212210054.go index 9ccab10bf..a85503162 100644 --- a/pkg/migration/20211212210054.go +++ b/pkg/migration/20211212210054.go @@ -17,11 +17,12 @@ package migration import ( + "image" + "code.vikunja.io/api/pkg/files" "code.vikunja.io/api/pkg/log" "github.com/bbrks/go-blurhash" "golang.org/x/image/draw" - "image" "src.techknowlogick.com/xormigrate" "xorm.io/xorm" ) diff --git a/pkg/modules/background/handler/background.go b/pkg/modules/background/handler/background.go index 13b15e5ab..19eab2ddf 100644 --- a/pkg/modules/background/handler/background.go +++ b/pkg/modules/background/handler/background.go @@ -17,14 +17,15 @@ package handler import ( - "github.com/bbrks/go-blurhash" - "golang.org/x/image/draw" "image" "io" "net/http" "strconv" "strings" + "github.com/bbrks/go-blurhash" + "golang.org/x/image/draw" + "code.vikunja.io/api/pkg/db" "xorm.io/xorm" diff --git a/pkg/modules/migration/create_from_structure.go b/pkg/modules/migration/create_from_structure.go index 2aa9169ed..e523efe52 100644 --- a/pkg/modules/migration/create_from_structure.go +++ b/pkg/modules/migration/create_from_structure.go @@ -18,9 +18,10 @@ package migration import ( "bytes" - "code.vikunja.io/api/pkg/modules/background/handler" "io/ioutil" + "code.vikunja.io/api/pkg/modules/background/handler" + "xorm.io/xorm" "code.vikunja.io/api/pkg/db" -- 2.45.1 From c504f56c3f7924491da30d873829acc36cdb3fb2 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 21:52:07 +0100 Subject: [PATCH 06/11] chore: generate swagger docs --- pkg/swagger/docs.go | 7 +++++++ pkg/swagger/swagger.json | 7 +++++++ pkg/swagger/swagger.yaml | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index ab411d3ff..5b2b39e2e 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -7437,6 +7437,9 @@ var doc = `{ "background.Image": { "type": "object", "properties": { + "blur_hash": { + "type": "string" + }, "id": { "type": "string" }, @@ -7901,6 +7904,10 @@ var doc = `{ "models.List": { "type": "object", "properties": { + "background_blur_hash": { + "description": "Contains a very small version of the list background to use as a blurry preview until the actual background is loaded. Check out https://blurha.sh/ to learn how it works.", + "type": "string" + }, "background_information": { "description": "Holds extra information about the background set since some background providers require attribution or similar. If not null, the background can be accessed at /lists/{listID}/background" }, diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index 01a96a8a0..72a597300 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -7421,6 +7421,9 @@ "background.Image": { "type": "object", "properties": { + "blur_hash": { + "type": "string" + }, "id": { "type": "string" }, @@ -7885,6 +7888,10 @@ "models.List": { "type": "object", "properties": { + "background_blur_hash": { + "description": "Contains a very small version of the list background to use as a blurry preview until the actual background is loaded. Check out https://blurha.sh/ to learn how it works.", + "type": "string" + }, "background_information": { "description": "Holds extra information about the background set since some background providers require attribution or similar. If not null, the background can be accessed at /lists/{listID}/background" }, diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index b3e1849a5..adb7e0d50 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -7,6 +7,8 @@ definitions: type: object background.Image: properties: + blur_hash: + type: string id: type: string info: @@ -389,6 +391,11 @@ definitions: type: object models.List: properties: + background_blur_hash: + description: Contains a very small version of the list background to use as + a blurry preview until the actual background is loaded. Check out https://blurha.sh/ + to learn how it works. + type: string background_information: description: Holds extra information about the background set since some background providers require attribution or similar. If not null, the background can -- 2.45.1 From e83e248b6ddac92784bc4b1982990b1147d281a7 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 22:34:18 +0100 Subject: [PATCH 07/11] fix: return BlurHash in unsplash search results --- pkg/modules/background/unsplash/unsplash.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/modules/background/unsplash/unsplash.go b/pkg/modules/background/unsplash/unsplash.go index 02d0e47bc..1ee15ea5f 100644 --- a/pkg/modules/background/unsplash/unsplash.go +++ b/pkg/modules/background/unsplash/unsplash.go @@ -215,8 +215,9 @@ func (p *Provider) Search(s *xorm.Session, search string, page int64) (result [] result = []*background.Image{} for _, p := range searchResult.Results { result = append(result, &background.Image{ - ID: p.ID, - URL: getImageID(p.Urls.Raw), + ID: p.ID, + URL: getImageID(p.Urls.Raw), + BlurHash: p.BlurHash, Info: &models.UnsplashPhoto{ UnsplashID: p.ID, Author: p.User.Username, -- 2.45.1 From 8c9009ecd598100325fe5cb8c4d8ca1b2ca1c634 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Dec 2021 22:34:30 +0100 Subject: [PATCH 08/11] fix: go mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8e08ec26d..67ec2453d 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/ThreeDotsLabs/watermill v1.1.1 github.com/adlio/trello v1.9.0 github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef - github.com/bbrks/go-blurhash v1.1.1 // indirect + github.com/bbrks/go-blurhash v1.1.1 github.com/beevik/etree v1.1.0 // indirect github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2 github.com/coreos/go-oidc/v3 v3.1.0 -- 2.45.1 From 3c29f2e47e14223d3910a9e880db5a246d854b5f Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 20 Dec 2021 19:37:39 +0100 Subject: [PATCH 09/11] fix: decoding images for blurHash generation --- pkg/modules/background/handler/background.go | 55 ++++++++++--------- .../migration/create_from_structure.go | 20 ++----- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/pkg/modules/background/handler/background.go b/pkg/modules/background/handler/background.go index 19eab2ddf..6c8a8a2f1 100644 --- a/pkg/modules/background/handler/background.go +++ b/pkg/modules/background/handler/background.go @@ -18,27 +18,30 @@ package handler import ( "image" + _ "image/gif" + _ "image/jpeg" + _ "image/png" "io" "net/http" "strconv" "strings" - "github.com/bbrks/go-blurhash" - "golang.org/x/image/draw" - "code.vikunja.io/api/pkg/db" - "xorm.io/xorm" - "code.vikunja.io/api/pkg/files" "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" auth2 "code.vikunja.io/api/pkg/modules/auth" "code.vikunja.io/api/pkg/modules/background" "code.vikunja.io/api/pkg/modules/background/unsplash" + "code.vikunja.io/api/pkg/modules/background/upload" "code.vikunja.io/web" "code.vikunja.io/web/handler" + + "github.com/bbrks/go-blurhash" "github.com/gabriel-vasile/mimetype" "github.com/labstack/echo/v4" + "golang.org/x/image/draw" + "xorm.io/xorm" ) // BackgroundProvider represents a thing which holds a background provider @@ -161,8 +164,6 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { return handler.HandleHTTPError(err, c) } - p := bp.Provider() - // Get + upload the image file, err := c.FormFile("background") if err != nil { @@ -186,10 +187,8 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { _ = s.Rollback() return c.JSON(http.StatusBadRequest, models.Message{Message: "Uploaded file is no image."}) } - _, _ = srcf.Seek(0, io.SeekStart) - // Save the file - f, err := files.CreateWithMime(srcf, file.Filename, uint64(file.Size), auth, mime.String()) + err = SaveBackgroundFile(s, auth, list, srcf, file.Filename, uint64(file.Size)) if err != nil { _ = s.Rollback() if files.IsErrFileIsTooLarge(err) { @@ -199,21 +198,6 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { return handler.HandleHTTPError(err, c) } - // Generate a blurHash - _, _ = srcf.Seek(0, io.SeekStart) - list.BackgroundBlurHash, err = CreateBlurHash(srcf) - if err != nil { - return handler.HandleHTTPError(err, c) - } - - // Save it - img := &background.Image{ID: strconv.FormatInt(f.ID, 10)} - err = p.Set(s, img, list, auth) - if err != nil { - _ = s.Rollback() - return handler.HandleHTTPError(err, c) - } - if err := s.Commit(); err != nil { _ = s.Rollback() return handler.HandleHTTPError(err, c) @@ -222,6 +206,27 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error { return c.JSON(http.StatusOK, list) } +func SaveBackgroundFile(s *xorm.Session, auth web.Auth, list *models.List, srcf io.ReadSeeker, filename string, filesize uint64) (err error) { + _, _ = srcf.Seek(0, io.SeekStart) + f, err := files.Create(srcf, filename, filesize, auth) + if err != nil { + return err + } + + // Generate a blurHash + _, _ = srcf.Seek(0, io.SeekStart) + list.BackgroundBlurHash, err = CreateBlurHash(srcf) + if err != nil { + return err + } + + // Save it + p := upload.Provider{} + img := &background.Image{ID: strconv.FormatInt(f.ID, 10)} + err = p.Set(s, img, list, auth) + return err +} + func checkListBackgroundRights(s *xorm.Session, c echo.Context) (list *models.List, auth web.Auth, err error) { auth, err = auth2.GetAuthFromClaims(c) if err != nil { diff --git a/pkg/modules/migration/create_from_structure.go b/pkg/modules/migration/create_from_structure.go index e523efe52..e45224612 100644 --- a/pkg/modules/migration/create_from_structure.go +++ b/pkg/modules/migration/create_from_structure.go @@ -25,7 +25,6 @@ import ( "xorm.io/xorm" "code.vikunja.io/api/pkg/db" - "code.vikunja.io/api/pkg/files" "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/user" @@ -108,26 +107,19 @@ func insertFromStructure(s *xorm.Session, str []*models.NamespaceWithListsAndTas log.Debugf("[creating structure] Created list %d", l.ID) - backgroundFile, is := originalBackgroundInformation.(*bytes.Buffer) + bf, is := originalBackgroundInformation.(*bytes.Buffer) if is { + + backgroundFile := bytes.NewReader(bf.Bytes()) + log.Debugf("[creating structure] Creating a background file for list %d", l.ID) - file, err := files.Create(backgroundFile, "", uint64(backgroundFile.Len()), user) + err = handler.SaveBackgroundFile(s, user, &l.List, backgroundFile, "", uint64(backgroundFile.Len())) if err != nil { return err } - hash, err := handler.CreateBlurHash(backgroundFile) - if err != nil { - return err - } - - err = models.SetListBackground(s, l.ID, file, hash) - if err != nil { - return err - } - - log.Debugf("[creating structure] Created a background file as new file %d for list %d", file.ID, l.ID) + log.Debugf("[creating structure] Created a background file for list %d", l.ID) } // Create all buckets -- 2.45.1 From 440ccc39c04577d9ccb79be2a6dd4d5c35d53f1c Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 20 Dec 2021 19:42:02 +0100 Subject: [PATCH 10/11] fix: lint --- pkg/modules/background/handler/background.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/modules/background/handler/background.go b/pkg/modules/background/handler/background.go index 6c8a8a2f1..282e0578d 100644 --- a/pkg/modules/background/handler/background.go +++ b/pkg/modules/background/handler/background.go @@ -18,9 +18,9 @@ package handler import ( "image" - _ "image/gif" - _ "image/jpeg" - _ "image/png" + _ "image/gif" // To make sure the decoder used for generating blurHashes recognizes gifs + _ "image/jpeg" // To make sure the decoder used for generating blurHashes recognizes jpgs + _ "image/png" // To make sure the decoder used for generating blurHashes recognizes pngs "io" "net/http" "strconv" -- 2.45.1 From 287a6ea927051400cbecc715bddbc272715ff8b3 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 27 Mar 2022 22:44:03 +0200 Subject: [PATCH 11/11] chore: go mod tidy --- go.sum | 1 + 1 file changed, 1 insertion(+) diff --git a/go.sum b/go.sum index 46cd63303..272909f9b 100644 --- a/go.sum +++ b/go.sum @@ -533,6 +533,7 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -- 2.45.1