- Continuazione del Catalogo
This commit is contained in:
@@ -423,44 +423,99 @@ class ImageDownloader {
|
||||
* @param {number} delay - Ritardo in millisecondi tra i tentativi (default: 1000)
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async downloadImage(url, filepath, maxRetries = 1, delay = 1000) {
|
||||
async downloadImage(url, filepath, options = {}) {
|
||||
const {
|
||||
maxRetries = 3, // Aumentato il numero di tentativi predefiniti
|
||||
initialDelay = 1000, // Ritardo iniziale
|
||||
maxDelay = 10000, // Ritardo massimo
|
||||
timeout = 30000, // Timeout della richiesta
|
||||
validateContentType = true // Verifica del tipo di contenuto
|
||||
} = options;
|
||||
|
||||
// Funzione per il backoff esponenziale
|
||||
const getDelay = (attempt) => {
|
||||
return Math.min(initialDelay * Math.pow(2, attempt - 1), maxDelay);
|
||||
};
|
||||
|
||||
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
const writer = fs.createWriteStream(filepath);
|
||||
// Verifica se il filepath esiste già
|
||||
if (fs.existsSync(filepath)) {
|
||||
fs.unlinkSync(filepath);
|
||||
}
|
||||
|
||||
console.log('url da scaricare:', url);
|
||||
const writer = fs.createWriteStream(filepath);
|
||||
if (attempt > 1)
|
||||
console.log(`📥 Tentativo ${attempt}/${maxRetries} - Scaricamento: ${url}`);
|
||||
|
||||
const response = await axios({
|
||||
url,
|
||||
method: 'GET',
|
||||
responseType: 'stream',
|
||||
timeout: timeout,
|
||||
maxRedirects: 5,
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
'Accept': 'image/jpeg,image/png,image/webp,image/gif,image/*', // Specifico per immagini
|
||||
'Cache-Control': 'no-cache', // Evita problemi di caching
|
||||
'Connection': 'keep-alive'
|
||||
},
|
||||
validateStatus: (status) => status === 200, // Per immagini ci aspettiamo 200
|
||||
maxContentLength: 10 * 1024 * 1024 // Limite di 10MB per immagine
|
||||
});
|
||||
|
||||
// Verifica del content-type se richiesto
|
||||
if (validateContentType) {
|
||||
const contentType = response.headers['content-type'];
|
||||
if (!contentType || !contentType.startsWith('image/')) {
|
||||
throw new Error(`Content-Type non valido: ${contentType}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Verifica della dimensione del file
|
||||
const contentLength = parseInt(response.headers['content-length']);
|
||||
if (contentLength && contentLength > 100 * 1024 * 1024) { // 100MB limit
|
||||
throw new Error('File troppo grande');
|
||||
}
|
||||
|
||||
let downloadedBytes = 0;
|
||||
response.data.on('data', chunk => {
|
||||
downloadedBytes += chunk.length;
|
||||
});
|
||||
|
||||
response.data.pipe(writer);
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
writer.on('finish', () => {
|
||||
console.info('✅ Immagine scaricata ' + url + ' in ' + filepath);
|
||||
resolve(true);
|
||||
writer.on('finish', resolve);
|
||||
writer.on('error', error => {
|
||||
fs.unlink(filepath, () => { }); // Pulizia in caso di errore
|
||||
reject(error);
|
||||
});
|
||||
response.data.on('error', error => {
|
||||
fs.unlink(filepath, () => { });
|
||||
reject(error);
|
||||
});
|
||||
writer.on('error', reject);
|
||||
});
|
||||
|
||||
|
||||
console.info(`✅ Immagine scaricata con successo in ${filepath}`);
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
console.error(`❌ Tentativo ${attempt} fallito per l'URL ${url}. Errore:`, error.message);
|
||||
console.error(`❌ Errore nel tentativo ${attempt}/${maxRetries}:`, error.message);
|
||||
|
||||
// Pulizia del file in caso di errore
|
||||
if (fs.existsSync(filepath)) {
|
||||
fs.unlinkSync(filepath);
|
||||
}
|
||||
|
||||
if (attempt === maxRetries) {
|
||||
console.error('❌ Tutti i tentativi sono falliti. Scaricamento interrotto.');
|
||||
console.error(`Download fallito dopo ${maxRetries} tentativi: ${error.message}`);
|
||||
return false;
|
||||
} else {
|
||||
console.info(`🔁 Ritentando... (${attempt + 1} di ${maxRetries})`);
|
||||
await sleep(delay);
|
||||
}
|
||||
|
||||
const delay = getDelay(attempt);
|
||||
console.info(`🔄 Attendo ${delay}ms prima del prossimo tentativo...`);
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user