From ab724b309510e365fe703facbdd7ecd624c5fd86 Mon Sep 17 00:00:00 2001 From: Al Du Date: Fri, 1 Nov 2024 21:41:20 +0100 Subject: [PATCH] Improvements to image endpoints - Removed `AltText` from Image definition since it is no longer used. - Added `Maps` to check for valid file types and content types to make use of O(1) checks for Sets/Maps. --- admin-app/image.go | 17 ++++++++++++----- app/image.go | 44 ++++++++++++++++++++++++++------------------ common/image.go | 7 +++---- views/image.templ | 3 +-- views/images.templ | 2 +- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/admin-app/image.go b/admin-app/image.go index 5843416..5c4143f 100644 --- a/admin-app/image.go +++ b/admin-app/image.go @@ -6,7 +6,6 @@ import ( "net/http" "os" "path/filepath" - "slices" "github.com/fossoreslp/go-uuid-v4" "github.com/gin-gonic/gin" @@ -14,6 +13,14 @@ import ( "github.com/rs/zerolog/log" ) +var allowed_extensions = map[string]bool{ + ".jpeg": true, ".jpg": true, ".png": true, +} + +var allowed_content_types = map[string]bool{ + "image/jpeg": true, "image/png": true, "image/gif": true, +} + // TODO : need these endpoints // r.POST("/images", postImageHandler(&database)) // r.DELETE("/images", deleteImageHandler(&database)) @@ -38,9 +45,9 @@ func postImageHandler(app_settings common.AppSettings) func(*gin.Context) { } file := file_array[0] - allowed_types := []string{"image/jpeg", "image/png", "image/gif"} file_content_type := file.Header.Get("content-type") - if !slices.Contains(allowed_types, file_content_type) { + _, ok := allowed_content_types[file_content_type] + if !ok { log.Error().Msgf("file type not supported") c.JSON(http.StatusBadRequest, common.MsgErrorRes("file type not supported")) return @@ -60,10 +67,10 @@ func postImageHandler(app_settings common.AppSettings) func(*gin.Context) { return } - allowed_extensions := []string{"jpeg", "jpg", "png"} ext := filepath.Ext(file.Filename) // check ext is supported - if ext == "" && slices.Contains(allowed_extensions, ext) { + _, ok = allowed_extensions[ext] + if ext == "" || !ok { log.Error().Msgf("file extension is not supported %v", err) c.JSON(http.StatusBadRequest, common.ErrorRes("file extension is not supported", err)) return diff --git a/app/image.go b/app/image.go index f917251..984efc7 100644 --- a/app/image.go +++ b/app/image.go @@ -4,7 +4,6 @@ import ( "bytes" "os" "path" - "slices" "strconv" "github.com/gin-gonic/gin" @@ -14,9 +13,18 @@ import ( "github.com/rs/zerolog/log" ) +// Since there are no builtin sets in go, we are using a map to improve the performance when checking for valid extensions +// by creating a map with the valid extensions as keys and using an existence check. +var valid_extensions = map[string]bool{ + ".jpg": true, + ".jpeg": true, + ".png": true, + ".gif": true, +} + func imagesHandler(c *gin.Context, app_settings common.AppSettings, database database.Database) ([]byte, error) { // TODO: Implement rendering. - pageNum := 0 // Default to page 0 + pageNum := 1 // Default to page 0 if pageNumQuery := c.Param("num"); pageNumQuery != "" { num, err := strconv.Atoi(pageNumQuery) if err == nil && num > 0 { @@ -27,7 +35,7 @@ func imagesHandler(c *gin.Context, app_settings common.AppSettings, database dat } limit := 10 // or whatever limit you want - offset := max((pageNum-1)*limit, 0) + offset := (pageNum - 1) * limit // Get all the files inside the image directory files, err := os.ReadDir(app_settings.ImageDirectory) @@ -38,9 +46,7 @@ func imagesHandler(c *gin.Context, app_settings common.AppSettings, database dat // Filter all the non-images out of the list valid_images := make([]common.Image, 0) - valid_extensions := []string{".jpg", ".jpeg", ".png", ".gif"} for n, file := range files { - // TODO : This is surely not the best way // to implement pagination in for loops if n >= limit { @@ -53,16 +59,19 @@ func imagesHandler(c *gin.Context, app_settings common.AppSettings, database dat filename := file.Name() ext := path.Ext(file.Name()) - if slices.Contains(valid_extensions, ext) { - - image := common.Image{ - Uuid: filename[:len(filename)-len(ext)], - Name: filename, - AltText: "undefined", // TODO : perhaps remove this - Ext: ext, - } - valid_images = append(valid_images, image) + // Checking for the existence of a value in a map takes O(1) and therefore it's faster than + // iterating over a string slice + _, ok := valid_extensions[ext] + if !ok { + continue + } + + image := common.Image{ + Uuid: filename[:len(filename)-len(ext)], + Name: filename, + Ext: ext, } + valid_images = append(valid_images, image) } index_view := views.MakeImagesPage(valid_images, app_settings.AppNavbar.Links) @@ -89,10 +98,9 @@ func imageHandler(c *gin.Context, app_settings common.AppSettings, database data name := filename[:len(filename)-len(ext)] image := common.Image{ - Uuid: name, - Name: filename, - AltText: "undefined", - Ext: ext, + Uuid: name, + Name: filename, + Ext: ext, } index_view := views.MakeImagePage(image, app_settings.AppNavbar.Links) html_buffer := bytes.NewBuffer(nil) diff --git a/common/image.go b/common/image.go index 42d4223..42ed552 100644 --- a/common/image.go +++ b/common/image.go @@ -1,8 +1,7 @@ package common type Image struct { - Uuid string `json:"uuid"` - Name string `json:"name"` - AltText string `json:"alt_text"` - Ext string `json:"extension"` + Uuid string `json:"uuid"` + Name string `json:"name"` + Ext string `json:"extension"` } diff --git a/views/image.templ b/views/image.templ index 0cfe63d..7c2a163 100644 --- a/views/image.templ +++ b/views/image.templ @@ -23,8 +23,7 @@ templ MakeImagePage(image Image, links []Link) {

{ image.Name }

- {image.AltText} -

{ image.AltText }

+
Back diff --git a/views/images.templ b/views/images.templ index 488899c..8968ca9 100644 --- a/views/images.templ +++ b/views/images.templ @@ -48,7 +48,7 @@ templ MakeImagesPage(images []Image, links []Link) { for _, image := range images {
- {image.AltText} + {image.Name}