Add component to upload book cover images

This commit is contained in:
2025-10-27 22:51:28 +01:00
parent d407b41c9f
commit 8b8eee8210
11 changed files with 152 additions and 12 deletions

View File

@@ -3,6 +3,7 @@ package appcontext
import (
"errors"
"git.artlef.fr/PersonalLibraryManager/internal/config"
"git.artlef.fr/PersonalLibraryManager/internal/model"
"github.com/gin-gonic/gin"
"github.com/nicksnyder/go-i18n/v2/i18n"
@@ -10,9 +11,10 @@ import (
)
type AppContext struct {
C *gin.Context
Db *gorm.DB
I18n *i18n.Bundle
C *gin.Context
Db *gorm.DB
I18n *i18n.Bundle
Config *config.Config
}
func (ac AppContext) GetAuthenticatedUser() (model.User, error) {

View File

@@ -13,6 +13,7 @@ type Config struct {
DatabaseFilePath string `toml:"database_file_path" comment:"Path to sqlite database file."`
DemoDataPath string `toml:"demo_data_path" comment:"The path to the sql file to load for demo data."`
JWTKey string `toml:"jwt_key" comment:"The key used to encrypt the generated JWT. Encoded in base64. If empty a random one will be generated on every restart."`
ImageFolderPath string `toml:"image_folder_path" comment:"Folder where uploaded files will be stored."`
}
func defaultConfig() Config {
@@ -21,6 +22,7 @@ func defaultConfig() Config {
DatabaseFilePath: "plm.db",
DemoDataPath: "",
JWTKey: "",
ImageFolderPath: "img",
}
}

View File

@@ -17,6 +17,11 @@ func Auth() gin.HandlerFunc {
return
}
//do not check static files
if strings.HasPrefix(c.FullPath(), "/bookcover") {
return
}
username, err := parseUserFromJwt(c)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized,

View File

@@ -0,0 +1,24 @@
package routes
import (
"net/http"
"git.artlef.fr/PersonalLibraryManager/internal/appcontext"
"git.artlef.fr/PersonalLibraryManager/internal/myvalidator"
"github.com/gin-gonic/gin"
)
func PostUploadBookCoverHandler(ac appcontext.AppContext) {
file, err := ac.C.FormFile("file")
if err != nil {
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
return
}
filepath := file.Filename
err = ac.C.SaveUploadedFile(file, ac.Config.ImageFolderPath+"/"+filepath)
if err != nil {
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
return
}
ac.C.JSON(http.StatusOK, gin.H{"filepath": "/bookcover/" + filepath})
}

View File

@@ -22,27 +22,31 @@ func Setup(config *config.Config) *gin.Engine {
r := gin.Default()
r.Use(cors.New(configureCors())) // All origins allowed by default
r.Use(middleware.Auth())
r.Static("/bookcover", config.ImageFolderPath)
bundle := i18nresource.InitializeI18n()
r.GET("/mybooks", func(c *gin.Context) {
routes.GetMyBooksHanderl(appcontext.AppContext{C: c, Db: db, I18n: bundle})
routes.GetMyBooksHanderl(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/search/:searchterm", func(c *gin.Context) {
routes.GetSearchBooksHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle})
routes.GetSearchBooksHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/book/:id", func(c *gin.Context) {
routes.GetBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle})
routes.GetBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/book", func(c *gin.Context) {
routes.PostBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle})
routes.PostBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/book/read", func(c *gin.Context) {
routes.PostBookReadHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle})
routes.PostBookReadHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/auth/signup", func(c *gin.Context) {
routes.PostSignupHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle})
routes.PostSignupHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/auth/login", func(c *gin.Context) {
routes.PostLoginHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle})
routes.PostLoginHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/upload/cover", func(c *gin.Context) {
routes.PostUploadBookCoverHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
return r
}