From be7aed64a902365ff06372202307927499633231 Mon Sep 17 00:00:00 2001 From: wood chen Date: Tue, 22 Oct 2024 21:45:47 +0800 Subject: [PATCH] refactor(encoder): Update log messages and helper functions for better readability and maintainability --- encoder/encoder.go | 10 +++---- encoder/prefetch.go | 2 +- encoder/rawconvert.go | 5 ++++ handler/router.go | 64 +++++++++++++++++++++---------------------- helper/helper.go | 59 ++++++++++++++++++++++++++++++--------- 5 files changed, 88 insertions(+), 52 deletions(-) diff --git a/encoder/encoder.go b/encoder/encoder.go index 5d2afe1..0c01b09 100644 --- a/encoder/encoder.go +++ b/encoder/encoder.go @@ -39,7 +39,7 @@ func ConvertFilter(rawPath, jxlPath, avifPath, webpPath string, extraParams conf for { if _, found := config.ConvertLock.Get(rawPath); found { - log.Debugf("file %s is locked under conversion, retrying in %s", rawPath, retryDelay) + log.Debugf("文件 %s 在转换过程中被锁定,请在 %s 后重试", rawPath, retryDelay) time.Sleep(retryDelay) } else { // The lock is released, indicating that the conversion is complete @@ -212,7 +212,7 @@ func avifEncoder(img *vips.ImageRef, rawPath string, optimizedPath string) error } if err != nil { - log.Warnf("Can't encode source image: %v to AVIF", err) + log.Warnf("无法将源图像:%v 编码为 AVIF", err) return err } @@ -253,9 +253,9 @@ func webpEncoder(img *vips.ImageRef, rawPath string, optimizedPath string) error ep.ReductionEffort = i buf, _, err = img.ExportWebp(&ep) if err != nil && strings.Contains(err.Error(), "unable to encode") { - log.Warnf("Can't encode image to WebP with ReductionEffort %d, trying higher value...", i) + log.Warnf("无法使用 ReductionEffort %d 将图像编码为 WebP,请尝试更高的值...", i) } else if err != nil { - log.Warnf("Can't encode source image to WebP:%v", err) + log.Warnf("无法将源图像编码为 WebP:%v", err) } else { break } @@ -264,7 +264,7 @@ func webpEncoder(img *vips.ImageRef, rawPath string, optimizedPath string) error } if err != nil { - log.Warnf("Can't encode source image: %v to WebP", err) + log.Warnf("无法将源图像:%v 编码为 WebP", err) return err } diff --git a/encoder/prefetch.go b/encoder/prefetch.go index 4369444..44a1ed0 100644 --- a/encoder/prefetch.go +++ b/encoder/prefetch.go @@ -38,7 +38,7 @@ func PrefetchImages() { log.Debugf("跳过目录: %s", picAbsPath) return nil } - if !helper.CheckAllowedType(picAbsPath) { + if !helper.IsAllowedImageFile(picAbsPath) { log.Debugf("跳过不支持的文件类型: %s", picAbsPath) return nil } diff --git a/encoder/rawconvert.go b/encoder/rawconvert.go index c55a013..a611f86 100644 --- a/encoder/rawconvert.go +++ b/encoder/rawconvert.go @@ -6,6 +6,11 @@ import ( "github.com/jeremytorres/rawparser" ) +// ConvertRawToJPG 将原始图像文件转换为JPEG格式,并保存到优化路径。 +// rawPath: 原始图像文件的路径。 +// optimizedPath: 转换后的JPEG文件保存路径。 +// 返回值: 成功时返回转换后的JPEG文件路径和true;失败时返回原始路径和false。 + func ConvertRawToJPG(rawPath, optimizedPath string) (string, bool) { parser, _ := rawparser.NewNefParser(true) info := &rawparser.RawFileInfo{ diff --git a/handler/router.go b/handler/router.go index e1d2b41..50bebb3 100644 --- a/handler/router.go +++ b/handler/router.go @@ -1,7 +1,6 @@ package handler import ( - "net/http" "net/url" "path" "strconv" @@ -84,7 +83,7 @@ func Convert(c *fiber.Ctx) error { metadata = helper.ReadMetadata(reqURIwithQuery, "", reqHostname) if metadata.Checksum != helper.HashFile(rawImageAbs) { log.Info("本地文件已更改,更新元数据...") - helper.WriteMetadata(reqURIwithQuery, "", reqHostname) + metadata = helper.WriteMetadata(reqURIwithQuery, "", reqHostname) } } else { // 处理远程URL @@ -100,9 +99,9 @@ func Convert(c *fiber.Ctx) error { rawImageAbs = path.Join(config.Config.RemoteRawPath, targetHostName, metadata.Id) } - // 处理非图片文件 - if !helper.IsImageFile(filename) { - log.Infof("Non-image file requested: %s", reqURI) + // 检查是否为允许的图片文件 + if !helper.IsAllowedImageFile(filename) { + log.Infof("不允许的文件类型或非图片文件: %s", reqURI) if isLocalPath { return c.SendFile(rawImageAbs) } else { @@ -111,16 +110,6 @@ func Convert(c *fiber.Ctx) error { } } - // 检查允许的文件类型 - if !helper.CheckAllowedType(filename) { - msg := "不允许的文件扩展名 " + filename - log.Warn(msg) - return c.Status(http.StatusBadRequest).SendString(msg) - } - - // 后续的图像处理逻辑 - supportedFormats := helper.GuessSupportedFormat(reqHeader) - // 检查原始图像是否存在 if !helper.ImageExists(rawImageAbs) { helper.DeleteMetadata(reqURIwithQuery, targetHostName) @@ -136,27 +125,36 @@ func Convert(c *fiber.Ctx) error { return c.SendStatus(fiber.StatusInternalServerError) } + var finalFilename string if isSmall { - log.Infof("文件 %s 小于100KB,跳过转换", rawImageAbs) - return c.SendFile(rawImageAbs) + log.Infof("文件 %s 小于100KB,直接缓存到 EXHAUST_PATH", rawImageAbs) + finalFilename = path.Join(config.Config.ExhaustPath, targetHostName, metadata.Id) + if err := helper.CopyFile(rawImageAbs, finalFilename); err != nil { + log.Errorf("复制小文件到 EXHAUST_PATH 失败: %v", err) + return c.SendStatus(fiber.StatusInternalServerError) + } + } else { + avifAbs, webpAbs, jxlAbs := helper.GenOptimizedAbsPath(metadata, targetHostName) + + // 确定支持的格式 + supportedFormats := helper.GuessSupportedFormat(reqHeader) + // 根据支持的格式和配置进行转换 + encoder.ConvertFilter(rawImageAbs, jxlAbs, avifAbs, webpAbs, extraParams, supportedFormats, nil) + + var availableFiles = []string{rawImageAbs} + if supportedFormats["avif"] { + availableFiles = append(availableFiles, avifAbs) + } + if supportedFormats["webp"] { + availableFiles = append(availableFiles, webpAbs) + } + if supportedFormats["jxl"] { + availableFiles = append(availableFiles, jxlAbs) + } + + finalFilename = helper.FindSmallestFiles(availableFiles) } - avifAbs, webpAbs, jxlAbs := helper.GenOptimizedAbsPath(metadata, targetHostName) - // 根据支持的格式和配置进行转换 - encoder.ConvertFilter(rawImageAbs, jxlAbs, avifAbs, webpAbs, extraParams, supportedFormats, nil) - - var availableFiles = []string{rawImageAbs} - if supportedFormats["avif"] { - availableFiles = append(availableFiles, avifAbs) - } - if supportedFormats["webp"] { - availableFiles = append(availableFiles, webpAbs) - } - if supportedFormats["jxl"] { - availableFiles = append(availableFiles, jxlAbs) - } - - finalFilename := helper.FindSmallestFiles(availableFiles) contentType := helper.GetFileContentType(finalFilename) c.Set("Content-Type", contentType) diff --git a/helper/helper.go b/helper/helper.go index 78af66a..99c4d69 100644 --- a/helper/helper.go +++ b/helper/helper.go @@ -2,6 +2,7 @@ package helper import ( "fmt" + "io" "os" "path" "path/filepath" @@ -84,14 +85,14 @@ func ImageExists(filename string) bool { return !info.IsDir() } -func CheckAllowedType(imgFilename string) bool { - if config.Config.AllowedTypes[0] == "*" { - return true - } - imgFilenameExtension := strings.ToLower(path.Ext(imgFilename)) - imgFilenameExtension = strings.TrimPrefix(imgFilenameExtension, ".") // .jpg -> jpg - return slices.Contains(config.Config.AllowedTypes, imgFilenameExtension) -} +// func CheckAllowedType(imgFilename string) bool { +// if config.Config.AllowedTypes[0] == "*" { +// return true +// } +// imgFilenameExtension := strings.ToLower(path.Ext(imgFilename)) +// imgFilenameExtension = strings.TrimPrefix(imgFilenameExtension, ".") // .jpg -> jpg +// return slices.Contains(config.Config.AllowedTypes, imgFilenameExtension) +// } func GenOptimizedAbsPath(metadata config.MetaFile, subdir string) (string, string, string) { webpFilename := fmt.Sprintf("%s.webp", metadata.Id) @@ -219,8 +220,10 @@ func IsFileSizeSmall(filepath string, sizeLimit int64) (bool, error) { return fileInfo.Size() <= sizeLimit, nil } -// 新增:检查文件是否为图片的辅助函数 -func IsImageFile(filename string) bool { +// 新增:检查文件是否为允许的图片的辅助函数 +var defaultAllowedTypes = []string{"jpg", "png", "jpeg", "bmp", "gif", "svg", "nef", "heic", "webp"} + +func IsAllowedImageFile(filename string) bool { ext := strings.ToLower(path.Ext(filename)) if ext == "" { return false @@ -228,10 +231,40 @@ func IsImageFile(filename string) bool { ext = ext[1:] // 移除开头的点 allowedTypes := config.Config.AllowedTypes - if len(allowedTypes) == 1 && allowedTypes[0] == "*" { - // 如果允许所有类型,则使用默认的图片类型列表 - allowedTypes = config.NewWebPConfig().AllowedTypes + if len(allowedTypes) == 0 { + // 如果配置中的 AllowedTypes 为空,使用默认列表 + allowedTypes = defaultAllowedTypes + } else if len(allowedTypes) == 1 && allowedTypes[0] == "*" { + // 如果允许所有类型,直接返回 true + return true } return slices.Contains(allowedTypes, ext) } + +// 小于100KB文件直接复制到EXHAUST_PATH +func CopyFile(src, dst string) error { + sourceFileStat, err := os.Stat(src) + if err != nil { + return err + } + + if !sourceFileStat.Mode().IsRegular() { + return fmt.Errorf("%s 不是常规文件", src) + } + + source, err := os.Open(src) + if err != nil { + return err + } + defer source.Close() + + destination, err := os.Create(dst) + if err != nil { + return err + } + defer destination.Close() + + _, err = io.Copy(destination, source) + return err +}