This commit is contained in:
Executable
+59
@@ -0,0 +1,59 @@
|
||||
import { existsSync, createWriteStream, mkdirSync } from 'fs';
|
||||
import { dirname } from 'path';
|
||||
import axios from 'axios';
|
||||
import { Logger } from '@nestjs/common';
|
||||
|
||||
export class ImageUtils {
|
||||
private static readonly logger = new Logger('ImageUtils');
|
||||
|
||||
/**
|
||||
* Downloads an image from a URL and saves it to a local path.
|
||||
* Skips download if file already exists.
|
||||
*/
|
||||
static async downloadImage(url: string, localPath: string): Promise<boolean> {
|
||||
try {
|
||||
// Check if file exists
|
||||
if (existsSync(localPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
const dir = dirname(localPath);
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
|
||||
// Download
|
||||
const response = await axios({
|
||||
url,
|
||||
method: 'GET',
|
||||
responseType: 'stream',
|
||||
timeout: 5000,
|
||||
validateStatus: (status) => status === 200, // Only save if 200 OK
|
||||
});
|
||||
|
||||
const writer = createWriteStream(localPath);
|
||||
|
||||
response.data.pipe(writer);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on('finish', () => resolve(true));
|
||||
writer.on('error', (err) => {
|
||||
this.logger.warn(
|
||||
`Failed to write image to ${localPath}: ${err.message}`,
|
||||
);
|
||||
reject(new Error(`Failed to write image to ${localPath}`));
|
||||
});
|
||||
});
|
||||
} catch (error: any) {
|
||||
// Log warning but don't break the application
|
||||
// 404s are common for missing logos
|
||||
if (error.response?.status !== 404) {
|
||||
this.logger.warn(
|
||||
`Failed to download image from ${url}: ${error.message}`,
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user