Fix curly braces to comply with eslint rules (#141)
This commit is contained in:
parent
6132f895f3
commit
fa310661e9
6 changed files with 103 additions and 64 deletions
|
@ -107,52 +107,62 @@ function hasNoArgs() {
|
|||
}
|
||||
|
||||
function isShowHelpRequest() {
|
||||
if (hasNoArgs())
|
||||
if (hasNoArgs()) {
|
||||
throw new Error(CLI_ERROR.GRACEFULLY_STOP);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkRequiredArgument(argv: any) {
|
||||
if (hasNoArgs())
|
||||
if (hasNoArgs()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!argv.videoUrls && !argv.videoUrlsFile)
|
||||
if (!argv.videoUrls && !argv.videoUrlsFile) {
|
||||
throw new Error(colors.red(CLI_ERROR.MISSING_REQUIRED_ARG));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkVideoUrlsArgConflict(argv: any) {
|
||||
if (hasNoArgs())
|
||||
if (hasNoArgs()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argv.videoUrls && argv.videoUrlsFile)
|
||||
if (argv.videoUrls && argv.videoUrlsFile) {
|
||||
throw new Error(colors.red(CLI_ERROR.VIDEOURLS_ARG_CONFLICT));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkOutputDirArgConflict(argv: any) {
|
||||
if (hasNoArgs())
|
||||
if (hasNoArgs()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argv.outputDirectory && argv.outputDirectories)
|
||||
if (argv.outputDirectory && argv.outputDirectories) {
|
||||
throw new Error(colors.red(CLI_ERROR.OUTPUTDIR_ARG_CONFLICT));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkVideoUrlsInput(argv: any) {
|
||||
if (hasNoArgs() || !argv.videoUrls)
|
||||
if (hasNoArgs() || !argv.videoUrls) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!argv.videoUrls.length)
|
||||
if (!argv.videoUrls.length) {
|
||||
throw new Error(colors.red(CLI_ERROR.MISSING_REQUIRED_ARG));
|
||||
}
|
||||
|
||||
const t = argv.videoUrls[0] as string;
|
||||
if (t.substring(t.length-4) === '.txt')
|
||||
if (t.substring(t.length-4) === '.txt') {
|
||||
throw new Error(colors.red(CLI_ERROR.FILE_INPUT_VIDEOURLS_ARG));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -164,8 +174,9 @@ function checkVideoUrlsInput(argv: any) {
|
|||
* Optimize and make this transparent to destreamer
|
||||
*/
|
||||
function mergeVideoUrlsArguments(argv: any) {
|
||||
if (!argv.videoUrlsFile)
|
||||
if (!argv.videoUrlsFile) {
|
||||
return true;
|
||||
}
|
||||
|
||||
argv.videoUrls = [argv.videoUrlsFile]; // noone will notice ;)
|
||||
|
||||
|
@ -183,13 +194,16 @@ function mergeVideoUrlsArguments(argv: any) {
|
|||
* Optimize and make this transparent to destreamer
|
||||
*/
|
||||
function mergeOutputDirArguments(argv: any) {
|
||||
if (!argv.outputDirectories && argv.outputDirectory)
|
||||
if (!argv.outputDirectories && argv.outputDirectory) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!argv.outputDirectory && !argv.outputDirectories)
|
||||
if (!argv.outputDirectory && !argv.outputDirectories) {
|
||||
argv.outputDirectory = 'videos'; // default out dir
|
||||
else if (argv.outputDirectories)
|
||||
}
|
||||
else if (argv.outputDirectories) {
|
||||
argv.outputDirectory = argv.outputDirectories;
|
||||
}
|
||||
|
||||
if (argv.outputDirectories) {
|
||||
// these are not valid anymore
|
||||
|
@ -202,14 +216,17 @@ function mergeOutputDirArguments(argv: any) {
|
|||
|
||||
// yeah this is for windows, but lets check everyone, who knows...
|
||||
function windowsFileExtensionBadBehaviorFix(argv: any) {
|
||||
if (hasNoArgs() || !argv.videoUrlsFile || !argv.outputDirectories)
|
||||
if (hasNoArgs() || !argv.videoUrlsFile || !argv.outputDirectories) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(argv.videoUrlsFile)) {
|
||||
if (fs.existsSync(argv.videoUrlsFile + '.txt'))
|
||||
if (fs.existsSync(argv.videoUrlsFile + '.txt')) {
|
||||
argv.videoUrlsFile += '.txt';
|
||||
else
|
||||
}
|
||||
else {
|
||||
throw new Error(colors.red(CLI_ERROR.INPUT_URLS_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -12,8 +12,9 @@ import colors from 'colors';
|
|||
export function setProcessEvents() {
|
||||
// set exit event first so that we can always print cute errors
|
||||
process.on('exit', (code) => {
|
||||
if (code == 0)
|
||||
if (code == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const msg = code in Error ? `\n\n${Error[code]} \n` : `\n\nUnknown error: exit code ${code} \n`;
|
||||
|
||||
|
|
|
@ -9,8 +9,9 @@ function publishedDateToString(date: string) {
|
|||
const dateJs = new Date(date);
|
||||
const day = dateJs.getDate().toString().padStart(2, '0');
|
||||
const month = (dateJs.getMonth() + 1).toString(10).padStart(2, '0');
|
||||
const publishedDate = day + '-' + month + '-' + dateJs.getFullYear();
|
||||
|
||||
return day+'-'+month+'-'+dateJs.getFullYear();
|
||||
return publishedDate;
|
||||
}
|
||||
|
||||
function durationToTotalChunks(duration: string) {
|
||||
|
@ -39,7 +40,9 @@ export async function getVideoMetadata(videoGuids: string[], session: Session):
|
|||
playbackUrl = response?.data['playbackUrls']
|
||||
.filter((item: { [x: string]: string; }) =>
|
||||
item['mimeType'] == 'application/vnd.apple.mpegurl')
|
||||
.map((item: { [x: string]: string }) => { return item['playbackUrl']; })[0];
|
||||
.map((item: { [x: string]: string }) => {
|
||||
return item['playbackUrl'];
|
||||
})[0];
|
||||
|
||||
posterImage = response?.data['posterImage']['medium']['url'];
|
||||
date = publishedDateToString(response?.data['publishedDate']);
|
||||
|
|
|
@ -8,10 +8,12 @@ export function getPuppeteerChromiumPath() {
|
|||
const win32_rex = /^.*?\\node_modules\\puppeteer\\\.local-chromium/;
|
||||
const replaceRegex = process.platform === 'win32' ? win32_rex : macOS_Linux_rex;
|
||||
|
||||
if (!isPkg)
|
||||
if (!isPkg) {
|
||||
return puppeteer.executablePath();
|
||||
}
|
||||
|
||||
return puppeteer
|
||||
.executablePath()
|
||||
const browserPath = puppeteer.executablePath()
|
||||
.replace(replaceRegex, path.join(path.dirname(process.execPath), 'chromium'));
|
||||
|
||||
return browserPath;
|
||||
}
|
67
src/Utils.ts
67
src/Utils.ts
|
@ -10,24 +10,27 @@ function sanitizeUrls(urls: string[]) {
|
|||
const rex = new RegExp(/(?:https:\/\/)?.*\/video\/[a-z0-9]{8}-(?:[a-z0-9]{4}\-){3}[a-z0-9]{12}$/, 'i');
|
||||
const sanitized: string[] = [];
|
||||
|
||||
for (let i=0, l=urls.length; i<l; ++i) {
|
||||
for (let i = 0, l = urls.length; i < l; ++i) {
|
||||
let url = urls[i].split('?')[0];
|
||||
|
||||
if (!rex.test(url)) {
|
||||
if (url !== '')
|
||||
console.warn(colors.yellow('Invalid URL at line ' + (i+1) + ', skip..'));
|
||||
if (url !== '') {
|
||||
console.warn(colors.yellow('Invalid URL at line ' + (i + 1) + ', skip..'));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (url.substring(0, 8) !== 'https://')
|
||||
url = 'https://'+url;
|
||||
if (url.substring(0, 8) !== 'https://') {
|
||||
url = 'https://' + url;
|
||||
}
|
||||
|
||||
sanitized.push(url);
|
||||
}
|
||||
|
||||
if (!sanitized.length)
|
||||
if (!sanitized.length) {
|
||||
process.exit(ERROR_CODE.INVALID_INPUT_URLS);
|
||||
}
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
@ -36,8 +39,9 @@ function sanitizeOutDirsList(dirsList: string[]) {
|
|||
const sanitized: string[] = [];
|
||||
|
||||
dirsList.forEach(dir => {
|
||||
if (dir !== '')
|
||||
if (dir !== '') {
|
||||
sanitized.push(dir);
|
||||
}
|
||||
});
|
||||
|
||||
return sanitized;
|
||||
|
@ -48,92 +52,95 @@ function readFileToArray(path: string) {
|
|||
}
|
||||
|
||||
export async function forEachAsync(array: any, callback: any) {
|
||||
for (let i=0, l=array.length; i<l; ++i)
|
||||
for (let i = 0, l = array.length; i < l; ++i) {
|
||||
await callback(array[i], i, array);
|
||||
}
|
||||
}
|
||||
|
||||
export function parseVideoUrls(videoUrls: any) {
|
||||
let t = videoUrls[0] as string;
|
||||
const isPath = t.substring(t.length-4) === '.txt';
|
||||
let input = videoUrls[0] as string;
|
||||
const isPath = input.substring(input.length - 4) === '.txt';
|
||||
let urls: string[];
|
||||
|
||||
if (isPath)
|
||||
urls = readFileToArray(t);
|
||||
else
|
||||
if (isPath) {
|
||||
urls = readFileToArray(input);
|
||||
}
|
||||
else {
|
||||
urls = videoUrls as string[];
|
||||
}
|
||||
|
||||
return sanitizeUrls(urls);
|
||||
}
|
||||
|
||||
|
||||
export function getOutputDirectoriesList(outDirArg: string) {
|
||||
const isList = outDirArg.substring(outDirArg.length-4) === '.txt';
|
||||
const isList = outDirArg.substring(outDirArg.length - 4) === '.txt';
|
||||
let dirsList: string[];
|
||||
|
||||
if (isList)
|
||||
if (isList) {
|
||||
dirsList = sanitizeOutDirsList(readFileToArray(outDirArg));
|
||||
else
|
||||
}
|
||||
else {
|
||||
dirsList = [outDirArg];
|
||||
}
|
||||
|
||||
return dirsList;
|
||||
}
|
||||
|
||||
|
||||
export function makeOutputDirectories(dirsList: string[]) {
|
||||
dirsList.forEach(dir => {
|
||||
if (!fs.existsSync(dir)) {
|
||||
console.info(colors.yellow('Creating output directory:'));
|
||||
console.info(colors.green(dir)+'\n');
|
||||
console.info(colors.green(dir) + '\n');
|
||||
|
||||
try {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
|
||||
} catch(e) {
|
||||
}
|
||||
catch (e) {
|
||||
process.exit(ERROR_CODE.INVALID_OUTPUT_DIR);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function checkOutDirsUrlsMismatch(dirsList: string[], urlsList: string[]) {
|
||||
const dirsListL = dirsList.length;
|
||||
const urlsListL = urlsList.length;
|
||||
|
||||
if (dirsListL == 1) // one out dir, treat this as the chosen one for all
|
||||
// single out dir, treat this as the chosen one for all
|
||||
if (dirsListL == 1) {
|
||||
return;
|
||||
else if (dirsListL != urlsListL)
|
||||
}
|
||||
else if (dirsListL != urlsListL) {
|
||||
process.exit(ERROR_CODE.OUTDIRS_URLS_MISMATCH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
|
||||
export function checkRequirements() {
|
||||
try {
|
||||
const ffmpegVer = execSync('ffmpeg -version').toString().split('\n')[0];
|
||||
console.info(colors.green(`Using ${ffmpegVer}\n`));
|
||||
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
process.exit(ERROR_CODE.MISSING_FFMPEG);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function makeUniqueTitle(title: string, outDir: string, skip?: boolean, format?: string) {
|
||||
let ntitle = title;
|
||||
let k = 0;
|
||||
|
||||
while (!skip && fs.existsSync(outDir + path.sep + ntitle + '.' + format))
|
||||
while (!skip && fs.existsSync(outDir + path.sep + ntitle + '.' + format)) {
|
||||
ntitle = title + ' - ' + (++k).toString();
|
||||
}
|
||||
|
||||
return ntitle;
|
||||
}
|
||||
|
||||
|
||||
export function ffmpegTimemarkToChunk(timemark: string) {
|
||||
const timeVals: string[] = timemark.split(':');
|
||||
const hrs = parseInt(timeVals[0]);
|
||||
|
|
|
@ -26,16 +26,19 @@ const tokenCache = new TokenCache();
|
|||
async function init() {
|
||||
setProcessEvents(); // must be first!
|
||||
|
||||
if (await isElevated())
|
||||
if (await isElevated()) {
|
||||
process.exit(ERROR_CODE.ELEVATED_SHELL);
|
||||
}
|
||||
|
||||
checkRequirements();
|
||||
|
||||
if (argv.username)
|
||||
if (argv.username) {
|
||||
console.info('Username: %s', argv.username);
|
||||
}
|
||||
|
||||
if (argv.simulate)
|
||||
if (argv.simulate) {
|
||||
console.info(colors.yellow('Simulate mode, there will be no video download.\n'));
|
||||
}
|
||||
|
||||
if (argv.verbose) {
|
||||
console.info('Video URLs:');
|
||||
|
@ -65,7 +68,8 @@ async function DoInteractiveLogin(url: string, username?: string): Promise<Sessi
|
|||
await page.waitForSelector('input[type="email"]');
|
||||
await page.keyboard.type(username);
|
||||
await page.click('input[type="submit"]');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// If a username was not provided we let the user take actions that
|
||||
// lead up to the video page.
|
||||
}
|
||||
|
@ -88,9 +92,11 @@ async function DoInteractiveLogin(url: string, username?: string): Promise<Sessi
|
|||
};
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
if (tries > 5)
|
||||
}
|
||||
catch (error) {
|
||||
if (tries > 5) {
|
||||
process.exit(ERROR_CODE.NO_SESSION_INFO);
|
||||
}
|
||||
|
||||
session = null;
|
||||
tries++;
|
||||
|
@ -126,13 +132,15 @@ function extractVideoGuid(videoUrls: string[]): string[] {
|
|||
try {
|
||||
const urlObj = new URL(url);
|
||||
guid = urlObj.pathname.split('/').pop();
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`Unrecognized URL format in ${url}: ${e.message}`);
|
||||
process.exit(ERROR_CODE.INVALID_VIDEO_GUID);
|
||||
}
|
||||
|
||||
if (guid)
|
||||
if (guid) {
|
||||
videoGuids.push(guid);
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.verbose) {
|
||||
|
@ -184,7 +192,6 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
|||
|
||||
video.title = makeUniqueTitle(sanitize(video.title) + ' - ' + video.date, outputDirectories[j], argv.skip, argv.format);
|
||||
|
||||
|
||||
console.info('Spawning ffmpeg with access token and HLS URL. This may take a few seconds...');
|
||||
if (!process.stdout.columns) {
|
||||
console.info(colors.red('Unable to get number of columns from terminal.\n' +
|
||||
|
@ -214,8 +221,9 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
|||
const cleanupFn = (): void => {
|
||||
pbar.stop();
|
||||
|
||||
if (argv.noCleanup)
|
||||
if (argv.noCleanup) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.unlinkSync(outputPath);
|
||||
|
@ -255,7 +263,8 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
|||
pbar.update(video.totalChunks); // set progress bar to 100%
|
||||
console.log(colors.yellow(`\nFile already exists, skipping: ${outputPath}`));
|
||||
resolve();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cleanupFn();
|
||||
|
||||
console.log(`\nffmpeg returned an error: ${error.message}`);
|
||||
|
|
Loading…
Reference in a new issue