Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into fullVideoLabels

This commit is contained in:
Michael C
2022-10-28 16:49:50 -04:00
78 changed files with 2035 additions and 326 deletions

View File

@@ -3,6 +3,9 @@ import { Request } from "express";
import { IPAddress } from "../types/segments.model";
export function getIP(req: Request): IPAddress {
// if in testing mode, return immediately
if (config.mode === "test") return "127.0.0.1" as IPAddress;
if (config.behindProxy === true || config.behindProxy === "true") {
config.behindProxy = "X-Forwarded-For";
}
@@ -15,6 +18,6 @@ export function getIP(req: Request): IPAddress {
case "X-Real-IP":
return req.headers["x-real-ip"] as IPAddress;
default:
return (req.connection?.remoteAddress || req.socket?.remoteAddress) as IPAddress;
return req.socket?.remoteAddress as IPAddress;
}
}

View File

@@ -18,6 +18,7 @@ async function getFromITube (videoID: string): Promise<innerTubeVideoDetails> {
const result = await axios.post(url, data, {
timeout: 3500
});
/* istanbul ignore else */
if (result.status === 200) {
return result.data.videoDetails;
} else {
@@ -39,6 +40,7 @@ export async function getPlayerData (videoID: string, ignoreCache = false): Prom
return data as innerTubeVideoDetails;
}
} catch (err) {
/* istanbul ignore next */
return Promise.reject(err);
}
}

View File

@@ -9,7 +9,7 @@ import { getReputation } from "./reputation";
interface CanSubmitResult {
canSubmit: boolean;
reason?: string;
reason: string;
}
async function lowDownvotes(userID: HashedUserID): Promise<boolean> {
@@ -27,11 +27,13 @@ export async function canSubmit(userID: HashedUserID, category: Category): Promi
lowDownvotes(userID),
(async () => (await getReputation(userID)) > config.minReputationToSubmitChapter)(),
hasFeature(userID, Feature.ChapterSubmitter)
])
]),
reason: "Submitting chapters requires a minimum reputation. You can ask on Discord/Matrix to get permission with less reputation."
};
default:
return {
canSubmit: true
canSubmit: true,
reason: ""
};
}
}

View File

@@ -25,19 +25,40 @@ let exportClient: RedisSB = {
quit: () => new Promise((resolve) => resolve(null)),
};
let lastClientFail = 0;
let lastReadFail = 0;
let activeRequests = 0;
if (config.redis?.enabled) {
Logger.info("Connected to redis");
const client = createClient(config.redis);
const readClient = config.redisRead?.enabled ? createClient(config.redisRead) : null;
void client.connect(); // void as we don't care about the promise
void readClient?.connect();
exportClient = client as RedisSB;
const get = client.get.bind(client);
const getRead = readClient?.get?.bind(readClient);
exportClient.get = (key) => new Promise((resolve, reject) => {
activeRequests++;
const timeout = config.redis.getTimeout ? setTimeout(() => reject(), config.redis.getTimeout) : null;
get(key).then((reply) => {
const chosenGet = pickChoice(get, getRead);
chosenGet(key).then((reply) => {
if (timeout !== null) clearTimeout(timeout);
activeRequests--;
resolve(reply);
}).catch((err) => reject(err));
}).catch((err) => {
if (chosenGet === get) {
lastClientFail = Date.now();
} else {
lastReadFail = Date.now();
}
activeRequests--;
reject(err);
});
});
exportClient.increment = (key) => new Promise((resolve, reject) =>
void client.multi()
@@ -48,11 +69,35 @@ if (config.redis?.enabled) {
.catch((err) => reject(err))
);
client.on("error", function(error) {
lastClientFail = Date.now();
Logger.error(`Redis Error: ${error}`);
});
client.on("reconnect", () => {
Logger.info("Redis: trying to reconnect");
});
readClient?.on("error", function(error) {
lastReadFail = Date.now();
Logger.error(`Redis Read-Only Error: ${error}`);
});
readClient?.on("reconnect", () => {
Logger.info("Redis Read-Only: trying to reconnect");
});
}
function pickChoice<T>(client: T, readClient: T): T {
const readAvailable = !!readClient;
const ignoreReadDueToFailure = lastReadFail > Date.now() - 1000 * 30;
const readDueToFailure = lastClientFail > Date.now() - 1000 * 30;
if (readAvailable && !ignoreReadDueToFailure && (readDueToFailure ||
Math.random() > 1 / (config.redisRead?.weight + 1))) {
return readClient;
} else {
return client;
}
}
export function getRedisActiveRequests(): number {
return activeRequests;
}
export default exportClient;

View File

@@ -58,12 +58,11 @@ export async function createAndSaveToken(type: TokenType, code?: string): Promis
return licenseKey;
}
} catch (e) {
break;
} catch (e) /* istanbul ignore next */ {
Logger.error(`token creation: ${e}`);
return null;
}
break;
}
case TokenType.local: {
const licenseKey = generateToken();
@@ -74,7 +73,6 @@ export async function createAndSaveToken(type: TokenType, code?: string): Promis
return licenseKey;
}
}
return null;
}
@@ -102,15 +100,12 @@ export async function refreshToken(type: TokenType, licenseKey: string, refreshT
return true;
}
} catch (e) {
} catch (e) /* istanbul ignore next */ {
Logger.error(`token refresh: ${e}`);
return false;
}
break;
}
}
return false;
}
@@ -136,9 +131,8 @@ export async function getPatreonIdentity(accessToken: string): Promise<PatreonId
if (identityRequest.status === 200) {
return identityRequest.data;
}
} catch (e) {
} catch (e) /* istanbul ignore next */ {
Logger.error(`identity request: ${e}`);
}
return null;
}