Skip to content

Commit

Permalink
Improvements to image endpoints (#96)
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
AlDu2407 authored Nov 3, 2024
1 parent 8e125a9 commit a927e08
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 30 deletions.
17 changes: 12 additions & 5 deletions admin-app/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ import (
"net/http"
"os"
"path/filepath"
"slices"

"github.com/fossoreslp/go-uuid-v4"
"github.com/gin-gonic/gin"
"github.com/matheusgomes28/urchin/common"
"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))
Expand All @@ -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
Expand All @@ -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
Expand Down
44 changes: 26 additions & 18 deletions app/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"os"
"path"
"slices"
"strconv"

"github.com/gin-gonic/gin"
Expand All @@ -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 {
Expand All @@ -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)
Expand All @@ -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 {
Expand All @@ -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)
Expand All @@ -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)
Expand Down
7 changes: 3 additions & 4 deletions common/image.go
Original file line number Diff line number Diff line change
@@ -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"`
}
3 changes: 1 addition & 2 deletions views/image.templ
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ templ MakeImagePage(image Image, links []Link) {
<main>
<article>
<h3>{ image.Name }</h3>
<img src={fmt.Sprintf("/images/data/%s", image.Name)} alt={image.AltText} />
<p>{ image.AltText }</p>
<img src={fmt.Sprintf("/images/data/%s", image.Name)} />
</article>
</main>
<a href={templ.URL("/images")}>Back</a>
Expand Down
2 changes: 1 addition & 1 deletion views/images.templ
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ templ MakeImagesPage(images []Image, links []Link) {
for _, image := range images {
<a href={templ.URL("/images/" + image.Name)}>
<div>
<img src={fmt.Sprintf("/images/data/%s", image.Name)} alt={image.AltText} />
<img src={fmt.Sprintf("/images/data/%s", image.Name)} />
<span>{image.Name}</span>
</div>
</a>
Expand Down

0 comments on commit a927e08

Please sign in to comment.