mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-14 07:27:01 +03:00
fix docker build, add proper mocks to tests, remove YouTubeAPI dependency on youtube test mock, move index.ts and test.ts to /src ant /test folders
This commit is contained in:
198
src/app.ts
198
src/app.ts
@@ -1,4 +1,4 @@
|
||||
import express, {Request, RequestHandler, Response} from 'express';
|
||||
import express, {Express, Request, RequestHandler, Response} from 'express';
|
||||
import {config} from './config';
|
||||
import {oldSubmitSponsorTimes} from './routes/oldSubmitSponsorTimes';
|
||||
import {oldGetVideoSponsorTimes} from './routes/oldGetVideoSponsorTimes';
|
||||
@@ -22,108 +22,112 @@ import {voteOnSponsorTime} from './routes/voteOnSponsorTime';
|
||||
import {getSkipSegmentsByHash} from './routes/getSkipSegmentsByHash';
|
||||
import {postSkipSegments} from './routes/postSkipSegments';
|
||||
import {endpoint as getSkipSegments} from './routes/getSkipSegments';
|
||||
|
||||
import {userCounter} from './middleware/userCounter';
|
||||
import {loggerMiddleware} from './middleware/logger';
|
||||
import {corsMiddleware} from './middleware/cors';
|
||||
import {rateLimitMiddleware} from './middleware/requestRateLimit';
|
||||
|
||||
// Create a service (the app object is just a callback).
|
||||
const app = express();
|
||||
// Rate limit endpoint lists
|
||||
const voteEndpoints: RequestHandler[] = [voteOnSponsorTime];
|
||||
const viewEndpoints: RequestHandler[] = [viewedVideoSponsorTime];
|
||||
if (config.rateLimit) {
|
||||
if (config.rateLimit.vote) voteEndpoints.unshift(rateLimitMiddleware(config.rateLimit.vote));
|
||||
if (config.rateLimit.view) viewEndpoints.unshift(rateLimitMiddleware(config.rateLimit.view));
|
||||
}
|
||||
|
||||
//setup CORS correctly
|
||||
app.use(corsMiddleware);
|
||||
app.use(loggerMiddleware);
|
||||
app.use(express.json());
|
||||
|
||||
if (config.userCounterURL) app.use(userCounter);
|
||||
|
||||
// Setup pretty JSON
|
||||
if (config.mode === "development") app.set('json spaces', 2);
|
||||
|
||||
// Set production mode
|
||||
app.set('env', config.mode || 'production');
|
||||
|
||||
//add the get function
|
||||
app.get('/api/getVideoSponsorTimes', oldGetVideoSponsorTimes);
|
||||
|
||||
//add the oldpost function
|
||||
app.get('/api/postVideoSponsorTimes', oldSubmitSponsorTimes);
|
||||
app.post('/api/postVideoSponsorTimes', oldSubmitSponsorTimes);
|
||||
|
||||
//add the skip segments functions
|
||||
app.get('/api/skipSegments', getSkipSegments);
|
||||
app.post('/api/skipSegments', postSkipSegments);
|
||||
|
||||
// add the privacy protecting skip segments functions
|
||||
app.get('/api/skipSegments/:prefix', getSkipSegmentsByHash);
|
||||
|
||||
//voting endpoint
|
||||
app.get('/api/voteOnSponsorTime', ...voteEndpoints);
|
||||
app.post('/api/voteOnSponsorTime', ...voteEndpoints);
|
||||
|
||||
//Endpoint when a submission is skipped
|
||||
app.get('/api/viewedVideoSponsorTime', ...viewEndpoints);
|
||||
app.post('/api/viewedVideoSponsorTime', ...viewEndpoints);
|
||||
|
||||
//To set your username for the stats view
|
||||
app.post('/api/setUsername', setUsername);
|
||||
|
||||
//get what username this user has
|
||||
app.get('/api/getUsername', getUsername);
|
||||
|
||||
//Endpoint used to hide a certain user's data
|
||||
app.post('/api/shadowBanUser', shadowBanUser);
|
||||
|
||||
//Endpoint used to make a user a VIP user with special privileges
|
||||
app.post('/api/addUserAsVIP', addUserAsVIP);
|
||||
|
||||
//Gets all the views added up for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
app.get('/api/getViewsForUser', getViewsForUser);
|
||||
|
||||
//Gets all the saved time added up (views * sponsor length) for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
//In minutes
|
||||
app.get('/api/getSavedTimeForUser', getSavedTimeForUser);
|
||||
|
||||
app.get('/api/getTopUsers', getTopUsers);
|
||||
|
||||
//send out totals
|
||||
//send the total submissions, total views and total minutes saved
|
||||
app.get('/api/getTotalStats', getTotalStats);
|
||||
|
||||
app.get('/api/getUserInfo', getUserInfo);
|
||||
|
||||
//send out a formatted time saved total
|
||||
app.get('/api/getDaysSavedFormatted', getDaysSavedFormatted);
|
||||
|
||||
//submit video containing no segments
|
||||
app.post('/api/noSegments', postNoSegments);
|
||||
|
||||
app.delete('/api/noSegments', deleteNoSegments);
|
||||
|
||||
//get if user is a vip
|
||||
app.get('/api/isUserVIP', getIsUserVIP);
|
||||
|
||||
//sent user a warning
|
||||
app.post('/api/warnUser', postWarning);
|
||||
|
||||
//get if user is a vip
|
||||
app.post('/api/segmentShift', postSegmentShift);
|
||||
|
||||
app.get('/database.db', function (req: Request, res: Response) {
|
||||
res.sendFile("./databases/sponsorTimes.db", {root: "./"});
|
||||
});
|
||||
|
||||
// Create an HTTP service.
|
||||
export function createServer(callback: () => void) {
|
||||
// Create a service (the app object is just a callback).
|
||||
const app = express();
|
||||
|
||||
//setup CORS correctly
|
||||
app.use(corsMiddleware);
|
||||
app.use(loggerMiddleware);
|
||||
app.use(express.json());
|
||||
|
||||
if (config.userCounterURL) app.use(userCounter);
|
||||
|
||||
// Setup pretty JSON
|
||||
if (config.mode === "development") app.set('json spaces', 2);
|
||||
|
||||
// Set production mode
|
||||
app.set('env', config.mode || 'production');
|
||||
|
||||
setupRoutes(app);
|
||||
|
||||
return app.listen(config.port, callback);
|
||||
}
|
||||
|
||||
function setupRoutes(app: Express) {
|
||||
// Rate limit endpoint lists
|
||||
const voteEndpoints: RequestHandler[] = [voteOnSponsorTime];
|
||||
const viewEndpoints: RequestHandler[] = [viewedVideoSponsorTime];
|
||||
if (config.rateLimit) {
|
||||
if (config.rateLimit.vote) voteEndpoints.unshift(rateLimitMiddleware(config.rateLimit.vote));
|
||||
if (config.rateLimit.view) viewEndpoints.unshift(rateLimitMiddleware(config.rateLimit.view));
|
||||
}
|
||||
|
||||
//add the get function
|
||||
app.get('/api/getVideoSponsorTimes', oldGetVideoSponsorTimes);
|
||||
|
||||
//add the oldpost function
|
||||
app.get('/api/postVideoSponsorTimes', oldSubmitSponsorTimes);
|
||||
app.post('/api/postVideoSponsorTimes', oldSubmitSponsorTimes);
|
||||
|
||||
//add the skip segments functions
|
||||
app.get('/api/skipSegments', getSkipSegments);
|
||||
app.post('/api/skipSegments', postSkipSegments);
|
||||
|
||||
// add the privacy protecting skip segments functions
|
||||
app.get('/api/skipSegments/:prefix', getSkipSegmentsByHash);
|
||||
|
||||
//voting endpoint
|
||||
app.get('/api/voteOnSponsorTime', ...voteEndpoints);
|
||||
app.post('/api/voteOnSponsorTime', ...voteEndpoints);
|
||||
|
||||
//Endpoint when a submission is skipped
|
||||
app.get('/api/viewedVideoSponsorTime', ...viewEndpoints);
|
||||
app.post('/api/viewedVideoSponsorTime', ...viewEndpoints);
|
||||
|
||||
//To set your username for the stats view
|
||||
app.post('/api/setUsername', setUsername);
|
||||
|
||||
//get what username this user has
|
||||
app.get('/api/getUsername', getUsername);
|
||||
|
||||
//Endpoint used to hide a certain user's data
|
||||
app.post('/api/shadowBanUser', shadowBanUser);
|
||||
|
||||
//Endpoint used to make a user a VIP user with special privileges
|
||||
app.post('/api/addUserAsVIP', addUserAsVIP);
|
||||
|
||||
//Gets all the views added up for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
app.get('/api/getViewsForUser', getViewsForUser);
|
||||
|
||||
//Gets all the saved time added up (views * sponsor length) for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
//In minutes
|
||||
app.get('/api/getSavedTimeForUser', getSavedTimeForUser);
|
||||
|
||||
app.get('/api/getTopUsers', getTopUsers);
|
||||
|
||||
//send out totals
|
||||
//send the total submissions, total views and total minutes saved
|
||||
app.get('/api/getTotalStats', getTotalStats);
|
||||
|
||||
app.get('/api/getUserInfo', getUserInfo);
|
||||
|
||||
//send out a formatted time saved total
|
||||
app.get('/api/getDaysSavedFormatted', getDaysSavedFormatted);
|
||||
|
||||
//submit video containing no segments
|
||||
app.post('/api/noSegments', postNoSegments);
|
||||
|
||||
app.delete('/api/noSegments', deleteNoSegments);
|
||||
|
||||
//get if user is a vip
|
||||
app.get('/api/isUserVIP', getIsUserVIP);
|
||||
|
||||
//sent user a warning
|
||||
app.post('/api/warnUser', postWarning);
|
||||
|
||||
//get if user is a vip
|
||||
app.post('/api/segmentShift', postSegmentShift);
|
||||
|
||||
app.get('/database.db', function (req: Request, res: Response) {
|
||||
res.sendFile("./databases/sponsorTimes.db", {root: "./"});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs';
|
||||
import {SBSConfig} from "./types/config.model";
|
||||
|
||||
const isTestMode = process.env.npm_lifecycle_script === 'ts-node test.ts';
|
||||
const isTestMode = process.env.npm_lifecycle_script === 'ts-node test/test.ts';
|
||||
const configFile = isTestMode ? 'test.json' : 'config.json';
|
||||
export const config: SBSConfig = JSON.parse(fs.readFileSync(configFile).toString('utf8'));
|
||||
|
||||
|
||||
9
src/index.ts
Normal file
9
src/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import {config} from "./config";
|
||||
import {initDb} from './databases/databases';
|
||||
import {createServer} from "./app";
|
||||
import {Logger} from "./utils/logger";
|
||||
|
||||
initDb();
|
||||
createServer(() => {
|
||||
Logger.info("Server started on port " + config.port + ".");
|
||||
});
|
||||
@@ -13,9 +13,5 @@ export function rateLimitMiddleware(limitConfig: RateLimitConfig): rateLimit.Rat
|
||||
keyGenerator: (req) => {
|
||||
return getHash(getIP(req), 1);
|
||||
},
|
||||
skip: (/*req, res*/) => {
|
||||
// skip rate limit if running in test mode
|
||||
return process.env.npm_lifecycle_script === 'ts-node test.ts';
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,28 +2,15 @@ import {config} from '../config';
|
||||
import {Logger} from './logger';
|
||||
import * as redis from './redis';
|
||||
// @ts-ignore
|
||||
import YouTubeAPI from 'youtube-api';
|
||||
import _youTubeAPI from 'youtube-api';
|
||||
|
||||
import {YouTubeAPI as youtubeApiTest} from '../../test/youtubeMock';
|
||||
_youTubeAPI.authenticate({
|
||||
type: "key",
|
||||
key: config.youtubeAPIKey,
|
||||
});
|
||||
|
||||
let _youtubeApi: {
|
||||
listVideos: (videoID: string, callback: (err: string | boolean, data: any) => void) => void
|
||||
};
|
||||
// If in test mode, return a mocked youtube object
|
||||
// otherwise return an authenticated youtube api
|
||||
if (config.mode === "test") {
|
||||
_youtubeApi = youtubeApiTest;
|
||||
}
|
||||
else {
|
||||
_youtubeApi = YouTubeAPI;
|
||||
|
||||
YouTubeAPI.authenticate({
|
||||
type: "key",
|
||||
key: config.youtubeAPIKey,
|
||||
});
|
||||
|
||||
// YouTubeAPI.videos.list wrapper with cacheing
|
||||
_youtubeApi.listVideos = (videoID: string, callback: (err: string | boolean, data: any) => void) => {
|
||||
export class YouTubeAPI {
|
||||
static listVideos(videoID: string, callback: (err: string | boolean, data: any) => void) {
|
||||
const part = 'contentDetails,snippet';
|
||||
if (videoID.length !== 11 || videoID.includes(".")) {
|
||||
callback("Invalid video ID", undefined);
|
||||
@@ -34,7 +21,7 @@ else {
|
||||
redis.get(redisKey, (getErr: string, result: string) => {
|
||||
if (getErr || !result) {
|
||||
Logger.debug("redis: no cache for video information: " + videoID);
|
||||
YouTubeAPI.videos.list({
|
||||
_youTubeAPI.videos.list({
|
||||
part,
|
||||
id: videoID,
|
||||
}, (ytErr: boolean | string, data: any) => {
|
||||
@@ -63,7 +50,3 @@ else {
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export {
|
||||
_youtubeApi as YouTubeAPI
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user