From 0a17c01d5ecb89d182ba7bd605c70ac93c05390f Mon Sep 17 00:00:00 2001 From: Innei Date: Mon, 23 Jun 2025 12:43:15 +0800 Subject: [PATCH] refactor: streamline logging in image processing and EXIF extraction - Removed optional logger parameters in several functions, replacing them with global loggers for consistency. - Updated logging statements to ensure they are always executed, enhancing the visibility of processing steps and errors. - Cleaned up unused imports and commented-out code to improve code clarity and maintainability. Signed-off-by: Innei --- packages/builder/src/image/exif.ts | 31 ++++++------------- packages/builder/src/image/processor.ts | 8 ++--- packages/builder/src/index.ts | 1 - packages/builder/src/manifest/manager.ts | 2 +- packages/builder/src/photo/cache-manager.ts | 6 +--- packages/builder/src/photo/image-pipeline.ts | 12 ++----- packages/builder/src/photo/index.ts | 15 --------- packages/builder/src/photo/info-extractor.ts | 17 +++++----- .../src/storage/providers/s3-provider.ts | 18 +++++------ 9 files changed, 33 insertions(+), 77 deletions(-) diff --git a/packages/builder/src/image/exif.ts b/packages/builder/src/image/exif.ts index 0f9a5230..dc3c9029 100644 --- a/packages/builder/src/image/exif.ts +++ b/packages/builder/src/image/exif.ts @@ -8,7 +8,7 @@ import { exiftool } from 'exiftool-vendored' import type { Metadata } from 'sharp' import sharp from 'sharp' -import type { Logger } from '../logger/index.js' +import { getGlobalLoggers } from '../photo/logger-adapter.js' import type { PickedExif } from '../types/photo.js' const baseImageBuffer = sharp({ @@ -26,28 +26,27 @@ const baseImageBuffer = sharp({ export async function extractExifData( imageBuffer: Buffer, originalBuffer?: Buffer, - exifLogger?: Logger['exif'], ): Promise { - const log = exifLogger + const log = getGlobalLoggers().exif try { - log?.info('开始提取 EXIF 数据') + log.info('开始提取 EXIF 数据') // 首先尝试从处理后的图片中提取 EXIF let metadata = await sharp(imageBuffer).metadata() // 如果处理后的图片没有 EXIF 数据,且提供了原始 buffer,尝试从原始图片提取 if (!metadata.exif && originalBuffer) { - log?.info('处理后的图片缺少 EXIF 数据,尝试从原始图片提取') + log.info('处理后的图片缺少 EXIF 数据,尝试从原始图片提取') try { metadata = await sharp(originalBuffer).metadata() } catch (error) { - log?.warn('从原始图片提取 EXIF 失败,可能是不支持的格式:', error) + log.warn('从原始图片提取 EXIF 失败,可能是不支持的格式:', error) } } if (!metadata.exif) { - log?.warn('未找到 EXIF 数据') + log.warn('未找到 EXIF 数据') return null } @@ -89,21 +88,11 @@ export async function extractExifData( const exifData = await exiftool.read(tempImagePath) const result = handleExifData(exifData, metadata) - // const makerNote = exifReader(exifBuffer).Photo?.MakerNote - - // if (makerNote) { - // const recipe = getRecipe(makerNote) - - // if (recipe) { - // ;(exifData as any).FujiRecipe = recipe - // log?.info('检测到富士胶片配方信息') - // } - // } await unlink(tempImagePath).catch(noop) if (!exifData) { - log?.warn('EXIF 数据解析失败') + log.warn('EXIF 数据解析失败') return null } @@ -112,12 +101,10 @@ export async function extractExifData( delete exifData.warnings delete exifData.errors - // const cleanedExifData = cleanExifData(exifData) - - log?.success('EXIF 数据提取完成') + log.success('EXIF 数据提取完成') return result } catch (error) { - log?.error('提取 EXIF 数据失败:', error) + log.error('提取 EXIF 数据失败:', error) return null } } diff --git a/packages/builder/src/image/processor.ts b/packages/builder/src/image/processor.ts index 092244ae..c0bbef6c 100644 --- a/packages/builder/src/image/processor.ts +++ b/packages/builder/src/image/processor.ts @@ -6,6 +6,7 @@ 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 实例) @@ -86,9 +87,8 @@ export async function convertHeicToJpeg( export async function preprocessImageBuffer( buffer: Buffer, key: string, - imageLogger?: Logger['image'], ): Promise { - const log = imageLogger + const log = getGlobalLoggers().image.originalLogger const ext = path.extname(key).toLowerCase() // 如果是 HEIC/HEIF 格式,先转换为 JPEG @@ -135,9 +135,9 @@ export async function convertBmpToJpegSharpInstance( // 创建 Sharp 实例 // Calculate the number of channels in the BMP image - const channels = bmpImage.data.length / (bmpImage.width * bmpImage.height); + const channels = bmpImage.data.length / (bmpImage.width * bmpImage.height) if (channels !== 3 && channels !== 4) { - throw new Error(`Unsupported BMP channel count: ${channels}`); + throw new Error(`Unsupported BMP channel count: ${channels}`) } // Create Sharp instance with the correct channel count diff --git a/packages/builder/src/index.ts b/packages/builder/src/index.ts index 9bc394f5..15c29b6c 100644 --- a/packages/builder/src/index.ts +++ b/packages/builder/src/index.ts @@ -19,7 +19,6 @@ export type { // S3 操作 export { generateBlurhash } from './image/blurhash.js' -export { extractExifData } from './image/exif.js' export { getImageMetadataWithSharp, preprocessImageBuffer, diff --git a/packages/builder/src/manifest/manager.ts b/packages/builder/src/manifest/manager.ts index f89d535e..e104adbb 100644 --- a/packages/builder/src/manifest/manager.ts +++ b/packages/builder/src/manifest/manager.ts @@ -63,7 +63,7 @@ export async function saveManifest(items: PhotoManifestItem[]): Promise { ), ) - logger.fs.info(`📁 Manifest 保存至:${manifestPath}`) + logger.fs.info(`📁 Manifest 保存至: ${manifestPath}`) } // 检测并处理已删除的图片 diff --git a/packages/builder/src/photo/cache-manager.ts b/packages/builder/src/photo/cache-manager.ts index 3dfe9e6c..e191beb0 100644 --- a/packages/builder/src/photo/cache-manager.ts +++ b/packages/builder/src/photo/cache-manager.ts @@ -119,11 +119,7 @@ export async function processExifData( const ext = path.extname(photoKey).toLowerCase() const originalBuffer = HEIC_FORMATS.has(ext) ? rawImageBuffer : undefined - return await extractExifData( - imageBuffer, - originalBuffer, - loggers.exif.originalLogger, - ) + return await extractExifData(imageBuffer, originalBuffer) } /** diff --git a/packages/builder/src/photo/image-pipeline.ts b/packages/builder/src/photo/image-pipeline.ts index da56571a..4f3da135 100644 --- a/packages/builder/src/photo/image-pipeline.ts +++ b/packages/builder/src/photo/image-pipeline.ts @@ -57,11 +57,7 @@ export async function preprocessImage( // 预处理图片(处理 HEIC/HEIF 格式) let imageBuffer: Buffer try { - imageBuffer = await preprocessImageBuffer( - rawImageBuffer, - photoKey, - loggers.image.originalLogger, - ) + imageBuffer = await preprocessImageBuffer(rawImageBuffer, photoKey) } catch (error) { loggers.image.error(`预处理图片失败:${photoKey}`, error) return null @@ -182,11 +178,7 @@ export async function executePhotoProcessingPipeline( ) // 6. 提取照片信息 - const photoInfo = extractPhotoInfo( - photoKey, - exifData, - loggers.image.originalLogger, - ) + const photoInfo = extractPhotoInfo(photoKey, exifData) // 7. 处理 Live Photo const livePhotoResult = processLivePhoto(photoKey, livePhotoMap) diff --git a/packages/builder/src/photo/index.ts b/packages/builder/src/photo/index.ts index 70882da9..d19c0d53 100644 --- a/packages/builder/src/photo/index.ts +++ b/packages/builder/src/photo/index.ts @@ -2,18 +2,6 @@ export type { PhotoProcessorOptions } from './processor.js' export { processPhoto } from './processor.js' -// 图片处理管道 -export type { - PhotoProcessingContext, - ProcessedImageData, -} from './image-pipeline.js' -export { - executePhotoProcessingPipeline, - preprocessImage, - processImageWithSharp, - processPhotoWithPipeline, -} from './image-pipeline.js' - // 缓存管理 export type { CacheableData, ThumbnailResult } from './cache-manager.js' export { @@ -27,9 +15,6 @@ export { export type { LivePhotoResult } from './live-photo-handler.js' export { createLivePhotoMap, processLivePhoto } from './live-photo-handler.js' -// 信息提取 -export { extractPhotoInfo } from './info-extractor.js' - // Logger 适配器 export type { PhotoLogger, PhotoProcessingLoggers } from './logger-adapter.js' export { diff --git a/packages/builder/src/photo/info-extractor.ts b/packages/builder/src/photo/info-extractor.ts index faa90c56..99cca301 100644 --- a/packages/builder/src/photo/info-extractor.ts +++ b/packages/builder/src/photo/info-extractor.ts @@ -2,18 +2,17 @@ import path from 'node:path' import { env } from '@env' -import type { Logger } from '../logger/index.js' import type { PhotoInfo, PickedExif } from '../types/photo.js' +import { getGlobalLoggers } from './logger-adapter.js' // 从文件名提取照片信息 export function extractPhotoInfo( key: string, exifData?: PickedExif | null, - imageLogger?: Logger['image'], ): PhotoInfo { - const log = imageLogger + const log = getGlobalLoggers().image - log?.debug(`提取照片信息:${key}`) + log.info(`提取照片信息:${key}`) const fileName = path.basename(key, path.extname(key)) @@ -42,7 +41,7 @@ export function extractPhotoInfo( .filter((part) => part.trim() !== '') tags = pathParts.map((part) => part.trim()) - log?.debug(`从路径提取标签:[${tags.join(', ')}]`) + log.info(`从路径提取标签:[${tags.join(', ')}]`) } } @@ -54,7 +53,7 @@ export function extractPhotoInfo( // 如果是 Date 对象,直接使用 if (dateTimeOriginal instanceof Date) { dateTaken = dateTimeOriginal.toISOString() - log?.debug('使用 EXIF Date 对象作为拍摄时间') + log.info('使用 EXIF Date 对象作为拍摄时间') } else { log?.warn( `未知的 DateTimeOriginal 类型:${typeof dateTimeOriginal}`, @@ -72,7 +71,7 @@ export function extractPhotoInfo( const dateMatch = fileName.match(/(\d{4}-\d{2}-\d{2})/) if (dateMatch) { dateTaken = new Date(dateMatch[1]).toISOString() - log?.debug(`从文件名提取拍摄时间:${dateMatch[1]}`) + log.info(`从文件名提取拍摄时间:${dateMatch[1]}`) } } @@ -80,7 +79,7 @@ export function extractPhotoInfo( const viewsMatch = fileName.match(/(\d+)views?/i) if (viewsMatch) { views = Number.parseInt(viewsMatch[1]) - log?.debug(`从文件名提取浏览次数:${views}`) + log.info(`从文件名提取浏览次数:${views}`) } // 从文件名中提取标题(移除日期和浏览次数) @@ -95,7 +94,7 @@ export function extractPhotoInfo( title = path.basename(key, path.extname(key)) } - log?.debug(`照片信息提取完成:"${title}"`) + log.info(`照片信息提取完成:"${title}"`) return { title, diff --git a/packages/builder/src/storage/providers/s3-provider.ts b/packages/builder/src/storage/providers/s3-provider.ts index 6725a463..1daf4140 100644 --- a/packages/builder/src/storage/providers/s3-provider.ts +++ b/packages/builder/src/storage/providers/s3-provider.ts @@ -4,7 +4,7 @@ import type { _Object } from '@aws-sdk/client-s3' import { GetObjectCommand, ListObjectsV2Command } from '@aws-sdk/client-s3' import { SUPPORTED_FORMATS } from '../../constants/index.js' -import type { Logger } from '../../logger/index.js' +import { logger } from '../../logger/index.js' import { s3Client } from '../../s3/client.js' import type { S3Config, StorageObject, StorageProvider } from '../interfaces' @@ -25,11 +25,9 @@ export class S3StorageProvider implements StorageProvider { this.config = config } - async getFile(key: string, logger?: Logger['s3']): Promise { - const log = logger - + async getFile(key: string): Promise { try { - log?.info(`下载文件:${key}`) + logger.s3.info(`下载文件:${key}`) const startTime = Date.now() const command = new GetObjectCommand({ @@ -40,7 +38,7 @@ export class S3StorageProvider implements StorageProvider { const response = await s3Client.send(command) if (!response.Body) { - log?.error(`S3 响应中没有 Body: ${key}`) + logger.s3.error(`S3 响应中没有 Body: ${key}`) return null } @@ -48,7 +46,7 @@ export class S3StorageProvider implements StorageProvider { if (response.Body instanceof Buffer) { const duration = Date.now() - startTime const sizeKB = Math.round(response.Body.length / 1024) - log?.success(`下载完成:${key} (${sizeKB}KB, ${duration}ms)`) + logger.s3.success(`下载完成:${key} (${sizeKB}KB, ${duration}ms)`) return response.Body } @@ -65,17 +63,17 @@ export class S3StorageProvider implements StorageProvider { const buffer = Buffer.concat(chunks) const duration = Date.now() - startTime const sizeKB = Math.round(buffer.length / 1024) - log?.success(`下载完成:${key} (${sizeKB}KB, ${duration}ms)`) + logger.s3.success(`下载完成:${key} (${sizeKB}KB, ${duration}ms)`) resolve(buffer) }) stream.on('error', (error) => { - log?.error(`下载失败:${key}`, error) + logger.s3.error(`下载失败:${key}`, error) reject(error) }) }) } catch (error) { - log?.error(`下载失败:${key}`, error) + logger.s3.error(`下载失败:${key}`, error) return null } }