mirror of
https://github.com/Afilmory/afilmory
synced 2026-04-24 23:05:05 +00:00
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:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
/**
|
||||
* 列出存储中的所有图片文件
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user