repo: move api src from root to own subdir
This commit is contained in:
38
api/src/util/generate-youtube-tokens.js
Normal file
38
api/src/util/generate-youtube-tokens.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Innertube } from 'youtubei.js';
|
||||
import { Red } from '../modules/sub/consoleText.js'
|
||||
|
||||
const bail = (...msg) => {
|
||||
console.error(...msg);
|
||||
throw new Error(msg);
|
||||
};
|
||||
|
||||
const tube = await Innertube.create();
|
||||
|
||||
tube.session.once(
|
||||
'auth-pending',
|
||||
({ verification_url, user_code }) => {
|
||||
console.log(`${Red('[!]')} The token generated by this script is sensitive and you should not share it with anyone!`);
|
||||
console.log(` By using this token, you are risking your Google account getting terminated.`);
|
||||
console.log(` You should ${Red('NOT')} use your personal account!`);
|
||||
console.log();
|
||||
console.log(`Open ${verification_url} in a browser and enter ${user_code} when asked for the code.`);
|
||||
}
|
||||
);
|
||||
|
||||
tube.session.once('auth-error', (err) => bail('An error occurred:', err));
|
||||
tube.session.once('auth', ({ credentials }) => {
|
||||
if (!credentials.access_token) {
|
||||
bail('something went wrong');
|
||||
}
|
||||
|
||||
console.log(
|
||||
'add this cookie to the youtube_oauth array in your cookies file:',
|
||||
JSON.stringify(
|
||||
Object.entries(credentials)
|
||||
.map(([k, v]) => `${k}=${v instanceof Date ? v.toISOString() : v}`)
|
||||
.join('; ')
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
await tube.session.signIn();
|
||||
81
api/src/util/test-ci.js
Normal file
81
api/src/util/test-ci.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import { env } from "../modules/config.js";
|
||||
import { runTest } from "../modules/test.js";
|
||||
import { loadLoc } from "../localization/manager.js";
|
||||
import { loadJSON } from "../modules/sub/loadFromFs.js";
|
||||
import { Red, Bright } from "../modules/sub/consoleText.js";
|
||||
|
||||
const tests = loadJSON('./src/util/tests.json');
|
||||
const services = loadJSON('./src/modules/processing/servicesConfig.json');
|
||||
|
||||
// services that are known to frequently fail due to external
|
||||
// factors (e.g. rate limiting)
|
||||
const finnicky = new Set(['bilibili', 'instagram', 'youtube'])
|
||||
|
||||
const action = process.argv[2];
|
||||
switch (action) {
|
||||
case "get-services":
|
||||
const fromConfig = Object.keys(services.config);
|
||||
|
||||
const missingTests = fromConfig.filter(
|
||||
service => !tests[service] || tests[service].length === 0
|
||||
);
|
||||
|
||||
if (missingTests.length) {
|
||||
console.error('services have no tests:', missingTests);
|
||||
console.log('[]');
|
||||
process.exitCode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(fromConfig));
|
||||
break;
|
||||
|
||||
case "run-tests-for":
|
||||
const service = process.argv[3];
|
||||
let failed = false;
|
||||
|
||||
if (!tests[service]) {
|
||||
console.error('no such service:', service);
|
||||
}
|
||||
|
||||
await loadLoc();
|
||||
env.streamLifespan = 10000;
|
||||
env.apiURL = 'http://x';
|
||||
|
||||
for (const test of tests[service]) {
|
||||
const { name, url, params, expected } = test;
|
||||
const canFail = test.canFail || finnicky.has(service);
|
||||
|
||||
try {
|
||||
await runTest(url, params, expected);
|
||||
console.log(`${service}/${name}: ok`);
|
||||
|
||||
} catch(e) {
|
||||
failed = !canFail;
|
||||
|
||||
let failText = canFail ? `${Red('FAIL')} (ignored)` : Bright(Red('FAIL'));
|
||||
if (canFail && process.env.GITHUB_ACTION) {
|
||||
console.log(`::warning title=${service}/${name.replace(/,/g, ';')}::failed and was ignored`);
|
||||
}
|
||||
|
||||
console.error(`${service}/${name}: ${failText}`);
|
||||
const errorString = e.toString().split('\n');
|
||||
let c = '┃';
|
||||
errorString.forEach((line, index) => {
|
||||
line = line.replace('!=', Red('!='));
|
||||
|
||||
if (index === errorString.length - 1) {
|
||||
c = '┗';
|
||||
}
|
||||
|
||||
console.error(` ${c}`, line);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
process.exitCode = Number(failed);
|
||||
break;
|
||||
default:
|
||||
console.error('invalid action:', action);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
79
api/src/util/test.js
Normal file
79
api/src/util/test.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import "dotenv/config";
|
||||
import "../modules/sub/alias-envs.js";
|
||||
|
||||
import { services } from "../modules/config.js";
|
||||
import { extract } from "../modules/processing/url.js";
|
||||
import match from "../modules/processing/match.js";
|
||||
import { loadJSON } from "../modules/sub/loadFromFs.js";
|
||||
import { normalizeRequest } from "../modules/processing/request.js";
|
||||
import { env } from "../modules/config.js";
|
||||
|
||||
env.apiURL = 'http://localhost:9000'
|
||||
let tests = loadJSON('./src/util/tests.json');
|
||||
|
||||
let noTest = [];
|
||||
let failed = [];
|
||||
let success = 0;
|
||||
|
||||
function addToFail(service, testName, url, status, response) {
|
||||
failed.push({
|
||||
service: service,
|
||||
name: testName,
|
||||
url: url,
|
||||
status: status,
|
||||
response: response
|
||||
})
|
||||
}
|
||||
for (let i in services) {
|
||||
if (tests[i]) {
|
||||
console.log(`\nRunning tests for ${i}...\n`)
|
||||
for (let k = 0; k < tests[i].length; k++) {
|
||||
let test = tests[i][k];
|
||||
|
||||
console.log(`Running test ${k+1}: ${test.name}`);
|
||||
console.log('params:');
|
||||
let params = {...{url: test.url}, ...test.params};
|
||||
console.log(params);
|
||||
|
||||
let chck = normalizeRequest(params);
|
||||
if (chck) {
|
||||
const parsed = extract(chck.url);
|
||||
if (parsed === null) {
|
||||
throw `Invalid URL: ${chck.url}`
|
||||
}
|
||||
|
||||
let j = await match(parsed.host, parsed.patternMatch, "en", chck);
|
||||
console.log('\nReceived:');
|
||||
console.log(j)
|
||||
if (j.status === test.expected.code && j.body.status === test.expected.status) {
|
||||
console.log("\n✅ Success.\n");
|
||||
success++
|
||||
} else {
|
||||
console.log(`\n❌ Fail. Expected: ${test.expected.code} & ${test.expected.status}, received: ${j.status} & ${j.body.status}\n`);
|
||||
addToFail(i, test.name, test.url, j.body.status, j)
|
||||
}
|
||||
} else {
|
||||
console.log("\n❌ couldn't validate the request JSON.\n");
|
||||
addToFail(i, test.name, test.url, "unknown", {})
|
||||
}
|
||||
}
|
||||
console.log("\n\n")
|
||||
} else {
|
||||
console.warn(`No tests found for ${i}.`);
|
||||
noTest.push(i)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`✅ ${success} tests succeeded.`);
|
||||
console.log(`❌ ${failed.length} tests failed.`);
|
||||
console.log(`❔ ${noTest.length} services weren't tested.`);
|
||||
|
||||
if (failed.length > 0) {
|
||||
console.log(`\nFailed tests:`);
|
||||
console.log(failed)
|
||||
}
|
||||
|
||||
if (noTest.length > 0) {
|
||||
console.log(`\nMissing tests:`);
|
||||
console.log(noTest)
|
||||
}
|
||||
70
api/src/util/testFilenamePresets.js
Normal file
70
api/src/util/testFilenamePresets.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import createFilename from "../modules/processing/createFilename.js";
|
||||
|
||||
let tests = [
|
||||
{
|
||||
f: {
|
||||
service: 'youtube',
|
||||
id: 'MMK3L4W70g4',
|
||||
title: "Loossemble (루셈블) - 'Sensitive' MV",
|
||||
author: 'Loossemble',
|
||||
youtubeDubName: false,
|
||||
qualityLabel: '2160p',
|
||||
resolution: '3840x2160',
|
||||
extension: 'webm',
|
||||
youtubeFormat: 'vp9'
|
||||
},
|
||||
isAudioOnly: false,
|
||||
isAudioMuted: false
|
||||
},
|
||||
{
|
||||
f: {
|
||||
service: 'youtube',
|
||||
id: 'MMK3L4W70g4',
|
||||
title: "Loossemble (루셈블) - 'Sensitive' MV",
|
||||
author: 'Loossemble',
|
||||
youtubeDubName: false,
|
||||
qualityLabel: '2160p',
|
||||
resolution: '3840x2160',
|
||||
extension: 'webm',
|
||||
youtubeFormat: 'vp9'
|
||||
},
|
||||
isAudioOnly: true,
|
||||
isAudioMuted: false
|
||||
},
|
||||
{
|
||||
f: {
|
||||
service: 'youtube',
|
||||
id: 'MMK3L4W70g4',
|
||||
title: "Loossemble (루셈블) - 'Sensitive' MV",
|
||||
author: 'Loossemble',
|
||||
youtubeDubName: false,
|
||||
qualityLabel: '2160p',
|
||||
resolution: '3840x2160',
|
||||
extension: 'webm',
|
||||
youtubeFormat: 'vp9'
|
||||
},
|
||||
isAudioOnly: false,
|
||||
isAudioMuted: true
|
||||
},
|
||||
{
|
||||
f: {
|
||||
service: 'vimeo',
|
||||
id: 'MMK3L4W70g4',
|
||||
title: "Loossemble (루셈블) - 'Sensitive' MV",
|
||||
author: 'Loossemble',
|
||||
qualityLabel: '2160p',
|
||||
resolution: '3840x2160',
|
||||
extension: 'mp4'
|
||||
},
|
||||
isAudioOnly: false,
|
||||
isAudioMuted: true
|
||||
}
|
||||
]
|
||||
|
||||
for (let i = 0; i < tests.length; i++) {
|
||||
console.log(`---${i}---`)
|
||||
console.log(createFilename(tests[i].f, "classic", tests[i].isAudioOnly, tests[i].isAudioMuted))
|
||||
console.log(createFilename(tests[i].f, "basic", tests[i].isAudioOnly, tests[i].isAudioMuted))
|
||||
console.log(createFilename(tests[i].f, "pretty", tests[i].isAudioOnly, tests[i].isAudioMuted))
|
||||
console.log(createFilename(tests[i].f, "nerdy", tests[i].isAudioOnly, tests[i].isAudioMuted))
|
||||
}
|
||||
1273
api/src/util/tests.json
Normal file
1273
api/src/util/tests.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user