refactor: remove optional logger parameter from getFile methods across storage providers and update logging implementation

- Simplified getFile method signatures in StorageProvider and its implementations by removing the optional logger parameter.
- Updated logging calls to use a global logger instance instead of passing a logger as an argument.
- Ensured consistent logging behavior across different storage providers.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2025-10-28 20:03:22 +08:00
parent af170a43bb
commit e99b211ac6
6 changed files with 47 additions and 47 deletions

View File

@@ -5,22 +5,20 @@ import heicConvert from 'heic-convert'
import sharp from 'sharp'
import { HEIC_FORMATS } from '../constants/index.js'
import type { Logger } from '../logger/index.js'
import { getGlobalLoggers } from '../photo/logger-adapter.js'
import type { ImageMetadata } from '../types/photo.js'
// 获取图片元数据(复用 Sharp 实例)
export async function getImageMetadataWithSharp(
sharpInstance: sharp.Sharp,
imageLogger?: Logger['image'],
): Promise<ImageMetadata | null> {
const log = imageLogger
const log = getGlobalLoggers().image
try {
const metadata = await sharpInstance.metadata()
if (!metadata.width || !metadata.height || !metadata.format) {
log?.error('图片元数据不完整')
log.error('图片元数据不完整')
return null
}
@@ -37,7 +35,7 @@ export async function getImageMetadataWithSharp(
) {
// 对于需要旋转 90°的图片需要交换宽高
;[width, height] = [height, width]
log?.info(
log.info(
`检测到需要旋转 90°的图片 (orientation: ${orientation}),交换宽高:${width}x${height}`,
)
}
@@ -48,20 +46,17 @@ export async function getImageMetadataWithSharp(
format: metadata.format,
}
} catch (error) {
log?.error('获取图片元数据失败:', error)
log.error('获取图片元数据失败:', error)
return null
}
}
// 转换 HEIC/HEIF 格式到 JPEG
export async function convertHeicToJpeg(
heicBuffer: Buffer,
imageLogger?: Logger['image'],
): Promise<Buffer> {
const log = imageLogger
export async function convertHeicToJpeg(heicBuffer: Buffer): Promise<Buffer> {
const log = getGlobalLoggers().image
try {
log?.info(
log.info(
`开始 HEIC/HEIF → JPEG 转换 (${Math.round(heicBuffer.length / 1024)}KB)`,
)
const startTime = Date.now()
@@ -74,11 +69,11 @@ export async function convertHeicToJpeg(
const duration = Date.now() - startTime
const outputSizeKB = Math.round(jpegBuffer.byteLength / 1024)
log?.success(`HEIC/HEIF 转换完成 (${outputSizeKB}KB, ${duration}ms)`)
log.success(`HEIC/HEIF 转换完成 (${outputSizeKB}KB, ${duration}ms)`)
return Buffer.from(jpegBuffer)
} catch (error) {
log?.error('HEIC/HEIF 转换失败:', error)
log.error('HEIC/HEIF 转换失败:', error)
throw error
}
}
@@ -88,13 +83,13 @@ export async function preprocessImageBuffer(
buffer: Buffer,
key: string,
): Promise<Buffer> {
const log = getGlobalLoggers().image.originalLogger
const log = getGlobalLoggers().image
const ext = path.extname(key).toLowerCase()
// 如果是 HEIC/HEIF 格式,先转换为 JPEG
if (HEIC_FORMATS.has(ext)) {
log?.info(`检测到 HEIC/HEIF 格式:${key}`)
return await convertHeicToJpeg(buffer, log)
log.info(`检测到 HEIC/HEIF 格式:${key}`)
return await convertHeicToJpeg(buffer)
}
// 其他格式直接返回原始 buffer
@@ -114,17 +109,15 @@ export function isBitmap(buf: Buffer): boolean {
/**
* 将 BMP Buffer 转换为 Sharp 实例
* @param bmpBuffer Buffer
* @param imageLogger 日志记录器
* @returns Sharp 实例
*/
export async function convertBmpToJpegSharpInstance(
bmpBuffer: Buffer,
imageLogger?: Logger['image'],
): Promise<sharp.Sharp> {
const log = imageLogger
const log = getGlobalLoggers().image
try {
log?.info(`开始 BMP → JPEG 转换 (${Math.round(bmpBuffer.length / 1024)}KB)`)
log.info(`开始 BMP → JPEG 转换 (${Math.round(bmpBuffer.length / 1024)}KB)`)
const startTime = Date.now()
// 使用 @vingle/bmp-js 解析 BMP
@@ -146,11 +139,11 @@ export async function convertBmpToJpegSharpInstance(
}).jpeg()
const duration = Date.now() - startTime
log?.success(`BMP 转换完成 (${duration}ms)`)
log.success(`BMP 转换完成 (${duration}ms)`)
return sharpInstance
} catch (error) {
log?.error('BMP 转换失败:', error)
log.error('BMP 转换失败:', error)
throw error
}
}

View File

@@ -1,4 +1,3 @@
import type { Logger } from '../logger/index.js'
// 扫描进度接口
export interface ScanProgress {
@@ -26,7 +25,7 @@ export interface StorageProvider {
* @param logger 可选的日志记录器
* @returns 文件的 Buffer 数据,如果不存在则返回 null
*/
getFile: (key: string, logger?: Logger['s3']) => Promise<Buffer | null>
getFile: (key: string) => Promise<Buffer | null>
/**
* 列出存储中的所有图片文件

View File

@@ -1,4 +1,3 @@
import type { Logger } from '../logger/index.js'
import { StorageFactory } from './factory.js'
import type {
StorageConfig,
@@ -19,8 +18,8 @@ export class StorageManager {
* @param logger 可选的日志记录器
* @returns 文件的 Buffer 数据,如果不存在则返回 null
*/
async getFile(key: string, logger?: Logger['s3']): Promise<Buffer | null> {
return this.provider.getFile(key, logger)
async getFile(key: string): Promise<Buffer | null> {
return this.provider.getFile(key)
}
/**

View File

@@ -3,8 +3,8 @@ import path from 'node:path'
import { SUPPORTED_FORMATS } from '@afilmory/builder/constants/index.js'
import { workdir } from '@afilmory/builder/path.js'
import { getGlobalLoggers } from '@afilmory/builder/photo/logger-adapter.js'
import type { Logger } from '../../logger/index.js'
import { logger } from '../../logger/index.js'
import type {
EagleConfig,
@@ -146,7 +146,8 @@ export class EagleStorageProvider implements StorageProvider {
this.folderIndex = buildFolderIndexes(libraryMetadata.folders ?? [])
}
async getFile(key: string, logger?: Logger['s3']): Promise<Buffer | null> {
async getFile(key: string): Promise<Buffer | null> {
const logger = getGlobalLoggers().s3
await this.initialize()
const imageInfoPath = path.resolve(
@@ -156,7 +157,7 @@ export class EagleStorageProvider implements StorageProvider {
)
const infoStats = await fs.stat(imageInfoPath)
if (!infoStats.isDirectory()) {
logger?.error?.(
logger.error(
`EagleStorageProvider: 请求的文件路径不安全。key: ${key}, 路径: ${imageInfoPath}`,
)
return null
@@ -166,7 +167,7 @@ export class EagleStorageProvider implements StorageProvider {
key,
)
if (!SUPPORTED_FORMATS.has(`.${imageMetadata.ext.toLowerCase()}`)) {
logger?.error?.(
logger.error(
`EagleStorageProvider: 不支持的图片格式。key: ${key}, 格式: .${imageMetadata.ext}`,
)
return null
@@ -177,7 +178,7 @@ export class EagleStorageProvider implements StorageProvider {
const buffer = await fs.readFile(imageFilePath)
return buffer
} catch (error) {
logger?.error?.(
logger.error(
`EagleStorageProvider: 读取图片文件失败。key: ${key}, 路径: ${imageFilePath}, 错误: ${error}`,
)
return null

View File

@@ -1,7 +1,8 @@
import path from 'node:path'
import { getGlobalLoggers } from '@afilmory/builder/photo/logger-adapter.js'
import { SUPPORTED_FORMATS } from '../../constants/index.js'
import type { Logger } from '../../logger/index.js'
import type {
GitHubConfig,
ProgressCallback,
@@ -85,11 +86,11 @@ export class GitHubStorageProvider implements StorageProvider {
return normalizedKey
}
async getFile(key: string, logger?: Logger['s3']): Promise<Buffer | null> {
const log = logger
async getFile(key: string): Promise<Buffer | null> {
const logger = getGlobalLoggers().s3
try {
log?.info(`下载文件:${key}`)
logger.info(`下载文件:${key}`)
const startTime = Date.now()
const fullPath = this.getFullPath(key)
@@ -101,7 +102,7 @@ export class GitHubStorageProvider implements StorageProvider {
if (!response.ok) {
if (response.status === 404) {
log?.warn(`文件不存在:${key}`)
logger.warn(`文件不存在:${key}`)
return null
}
throw new Error(
@@ -112,7 +113,7 @@ export class GitHubStorageProvider implements StorageProvider {
const data = (await response.json()) as GitHubFileContent
if (data.type !== 'file') {
log?.error(`路径不是文件:${key}`)
logger.error(`路径不是文件:${key}`)
return null
}
@@ -137,11 +138,11 @@ export class GitHubStorageProvider implements StorageProvider {
const duration = Date.now() - startTime
const sizeKB = Math.round(fileBuffer.length / 1024)
log?.success(`下载完成:${key} (${sizeKB}KB, ${duration}ms)`)
logger.success(`下载完成:${key} (${sizeKB}KB, ${duration}ms)`)
return fileBuffer
} catch (error) {
log?.error(`下载失败:${key}`, error)
logger.error(`下载失败:${key}`, error)
return null
}
}

View File

@@ -3,6 +3,11 @@ import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import {
CompatibleLoggerAdapter,
} from '@afilmory/builder/photo/logger-adapter.js'
import consola from 'consola'
import { SUPPORTED_FORMATS } from '../../constants/index.js'
import { logger } from '../../logger/index.js'
import type { LocalConfig, StorageObject, StorageProvider } from '../interfaces'
@@ -24,6 +29,8 @@ export class LocalStorageProvider implements StorageProvider {
filesScanned: 0,
}
private logger = new CompatibleLoggerAdapter(consola.withTag('LOCAL'))
constructor(config: LocalConfig) {
if (!config.basePath || config.basePath.trim() === '') {
throw new Error('LocalStorageProvider: basePath 不能为空')
@@ -68,9 +75,9 @@ export class LocalStorageProvider implements StorageProvider {
}
}
async getFile(key: string, logger?: any): Promise<Buffer | null> {
async getFile(key: string): Promise<Buffer | null> {
try {
logger?.info(`读取本地文件:${key}`)
this.logger.info(`读取本地文件:${key}`)
const startTime = Date.now()
const filePath = path.join(this.basePath, key)
@@ -80,7 +87,7 @@ export class LocalStorageProvider implements StorageProvider {
const resolvedBasePath = path.resolve(this.basePath)
if (!resolvedPath.startsWith(resolvedBasePath)) {
logger?.error(`文件路径不安全:${key}`)
this.logger.error(`文件路径不安全:${key}`)
return null
}
@@ -88,7 +95,7 @@ export class LocalStorageProvider implements StorageProvider {
try {
await fs.access(filePath)
} catch {
logger?.warn(`文件不存在:${key}`)
this.logger.warn(`文件不存在:${key}`)
return null
}
@@ -96,14 +103,14 @@ export class LocalStorageProvider implements StorageProvider {
const duration = Date.now() - startTime
const sizeKB = Math.round(buffer.length / 1024)
logger?.success(`读取完成:${key} (${sizeKB}KB, ${duration}ms)`)
this.logger.success(`读取完成:${key} (${sizeKB}KB, ${duration}ms)`)
return buffer
} catch (error) {
const errorType = error instanceof Error ? error.name : 'UnknownError'
const errorMessage =
error instanceof Error ? error.message : String(error)
logger?.error(`[${errorType}] 读取文件失败:${key} - ${errorMessage}`)
this.logger.error(`[${errorType}] 读取文件失败:${key} - ${errorMessage}`)
return null
}
}