2019-03-20 19:50:44 +00:00
|
|
|
import * as fs from 'fs';
|
2020-04-11 09:28:40 +00:00
|
|
|
import * as stream from 'stream';
|
|
|
|
import * as util from 'util';
|
2020-04-09 14:42:23 +00:00
|
|
|
import fetch from 'node-fetch';
|
2020-04-12 11:32:34 +00:00
|
|
|
import { getAgentByUrl } from './fetch';
|
2020-04-11 09:28:40 +00:00
|
|
|
import { AbortController } from 'abort-controller';
|
2021-03-23 08:43:07 +00:00
|
|
|
import config from '@/config';
|
2019-11-24 08:09:32 +00:00
|
|
|
import * as chalk from 'chalk';
|
2019-03-20 19:50:44 +00:00
|
|
|
import Logger from '../services/logger';
|
|
|
|
|
2020-04-11 09:28:40 +00:00
|
|
|
const pipeline = util.promisify(stream.pipeline);
|
|
|
|
|
2019-03-20 19:50:44 +00:00
|
|
|
export async function downloadUrl(url: string, path: string) {
|
2019-06-30 18:25:31 +00:00
|
|
|
const logger = new Logger('download');
|
2019-03-20 19:50:44 +00:00
|
|
|
|
2020-04-09 14:42:23 +00:00
|
|
|
logger.info(`Downloading ${chalk.cyan(url)} ...`);
|
2020-04-11 09:28:40 +00:00
|
|
|
const controller = new AbortController();
|
|
|
|
setTimeout(() => {
|
|
|
|
controller.abort();
|
2020-07-06 14:55:59 +00:00
|
|
|
}, 60 * 1000);
|
2020-04-09 14:42:23 +00:00
|
|
|
|
|
|
|
const response = await fetch(new URL(url).href, {
|
|
|
|
headers: {
|
|
|
|
'User-Agent': config.userAgent
|
|
|
|
},
|
|
|
|
timeout: 10 * 1000,
|
2020-04-11 09:28:40 +00:00
|
|
|
signal: controller.signal,
|
2020-04-12 11:32:34 +00:00
|
|
|
agent: getAgentByUrl,
|
2020-04-09 14:42:23 +00:00
|
|
|
});
|
2019-03-20 19:50:44 +00:00
|
|
|
|
2020-04-11 09:28:40 +00:00
|
|
|
if (!response.ok) {
|
|
|
|
logger.error(`Got ${response.status} (${url})`);
|
|
|
|
throw response.status;
|
|
|
|
}
|
2019-03-20 19:50:44 +00:00
|
|
|
|
2020-04-11 09:28:40 +00:00
|
|
|
await pipeline(response.body, fs.createWriteStream(path));
|
2019-03-20 19:50:44 +00:00
|
|
|
|
2020-04-11 09:28:40 +00:00
|
|
|
logger.succ(`Download finished: ${chalk.cyan(url)}`);
|
2019-03-20 19:50:44 +00:00
|
|
|
}
|