1
0
mirror of https://github.com/snobu/destreamer.git synced 2026-01-21 23:42:16 +00:00

Major code refactoring (#164)

* Added Chromium caching of identity provider cookies

* Moved token expiry check in standalone method

* Created refreshSession function

* Session is now refreshed if the token expires

* Linting fixes

* Removed debug console.log()

* Added CC support

* Created function to prompt user for download parameters (interactive mode)

* Fix data folder for puppeteer

* Fixed multiple session error

* Fix token expire time

* Moved session refreshing to a more sensible place

* Changed Metadata name to Video (to better reflect the data structure)

* Complete CLI refactoring

* Removed useless sleep function

* Added outDir check from CLI

* Complete input parsing refactoring (both inline and file)

* Fixed and improved tests to work with the new input parsing

* Moved and improved output path generation to videoUtils

* Main code refactoring, added outpath to video type

* Minor changes in spacing and type definition style

* Updated readme after code refactoring

* Fix if inputFile doesn't start with url on line 1

* Minor naming change

* Use module 'winston' for logging

* Created logge, changed all console.log and similar to use the logger

* Added verbose logging, changed posterUrl property name on Video type

* Moved GUID extraction to input parsing

* Added support for group links

* Fixed test after last input parsing update

* Removed debug proces.exit()

* Changed from desc to asc order for group videos

* Updated test to reflect GUIDs output after parsing

* Added couple of comments and restyled some imports

* More readable verbose GUIDs logging

* Removed unused errors

* Temporary fix for timeout not working in ApiClient

* Explicit class member accessibility

* Defined array naming schema to be Array<T>

* Defined type/interface schema to be type only

* A LOT of type definitions
This commit is contained in:
lukaarma
2020-07-18 21:49:36 +02:00
committed by GitHub
parent 89a942eb24
commit 7bfc565a05
19 changed files with 981 additions and 638 deletions

View File

@@ -1,56 +1,104 @@
import * as fs from 'fs';
import { chromeCacheFolder } from './destreamer';
import { ERROR_CODE } from './Errors';
import { logger } from './Logger';
import { getPuppeteerChromiumPath } from './PuppeteerHelper';
import { Session } from './Types';
import { bgGreen, bgYellow, green } from 'colors';
import fs from 'fs';
import jwtDecode from 'jwt-decode';
import puppeteer from 'puppeteer';
export class TokenCache {
private tokenCacheFile: string = '.token_cache';
private tokenCacheFile = '.token_cache';
public Read(): Session | null {
let j = null;
if (!fs.existsSync(this.tokenCacheFile)) {
console.warn(bgYellow.black(`${this.tokenCacheFile} not found.\n`));
logger.warn(`${this.tokenCacheFile} not found. \n`);
return null;
}
let f = fs.readFileSync(this.tokenCacheFile, 'utf8');
j = JSON.parse(f);
interface Jwt {
let session: Session = JSON.parse(fs.readFileSync(this.tokenCacheFile, 'utf8'));
type Jwt = {
[key: string]: any
}
const decodedJwt: Jwt = jwtDecode(session.AccessToken);
const decodedJwt: Jwt = jwtDecode(j.AccessToken);
let now: number = Math.floor(Date.now() / 1000);
let exp: number = decodedJwt['exp'];
let timeLeft: number = exp - now;
let now = Math.floor(Date.now() / 1000);
let exp = decodedJwt['exp'];
let timeLeft = exp - now;
let timeLeftInMinutes = Math.floor(timeLeft / 60);
if (timeLeft < 120) {
console.warn(bgYellow.black('\nAccess token has expired.'));
logger.warn('Access token has expired! \n');
return null;
}
console.info(bgGreen.black(`\nAccess token still good for ${timeLeftInMinutes} minutes.\n`));
let session: Session = {
AccessToken: j.AccessToken,
ApiGatewayUri: j.ApiGatewayUri,
ApiGatewayVersion: j.ApiGatewayVersion
};
logger.info(`Access token still good for ${Math.floor(timeLeft / 60)} minutes.\n`.green);
return session;
}
public Write(session: Session): void {
let s = JSON.stringify(session, null, 4);
let s: string = JSON.stringify(session, null, 4);
fs.writeFile('.token_cache', s, (err: any) => {
if (err) {
return console.error(err);
return logger.error(err);
}
console.info(green('Fresh access token dropped into .token_cache'));
logger.info('Fresh access token dropped into .token_cachen \n'.green);
});
}
}
}
export async function refreshSession(): Promise<Session> {
const url = 'https://web.microsoftstream.com';
const browser: puppeteer.Browser = await puppeteer.launch({
executablePath: getPuppeteerChromiumPath(),
headless: false, // NEVER TRUE OR IT DOES NOT WORK
userDataDir: chromeCacheFolder,
args: [
'--disable-dev-shm-usage',
'--fast-start',
'--no-sandbox'
]
});
const page: puppeteer.Page = (await browser.pages())[0];
await page.goto(url, { waitUntil: 'load' });
await browser.waitForTarget((target: puppeteer.Target) => target.url().includes(url), { timeout: 30000 });
let session: Session | null = null;
let tries = 1;
while (!session) {
try {
let sessionInfo: any;
session = await page.evaluate(
() => {
return {
AccessToken: sessionInfo.AccessToken,
ApiGatewayUri: sessionInfo.ApiGatewayUri,
ApiGatewayVersion: sessionInfo.ApiGatewayVersion
};
}
);
}
catch (error) {
if (tries > 5) {
process.exit(ERROR_CODE.NO_SESSION_INFO);
}
session = null;
tries++;
await page.waitFor(3000);
}
}
browser.close();
return session;
}