Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into stricter-eslint

This commit is contained in:
Michael C
2021-07-13 15:55:03 -04:00
18 changed files with 145 additions and 48 deletions

View File

@@ -13,11 +13,15 @@ export async function getLockCategories(req: Request, res: Response): Promise<Re
try {
// Get existing lock categories markers
const lockedCategories = await db.prepare("all", 'SELECT "category" from "lockCategories" where "videoID" = ?', [videoID]) as {category: Category}[];
if (lockedCategories.length === 0 || !lockedCategories[0]) return res.sendStatus(404);
// map to array in JS becaues of SQL incompatibilities
const categories = Object.values(lockedCategories).map((entry) => entry.category);
const row = await db.prepare("all", 'SELECT "category", "reason" from "lockCategories" where "videoID" = ?', [videoID]) as {category: Category, reason: string}[];
// map categories to array in JS becaues of SQL incompatibilities
const categories = row.map(item => item.category);
if (categories.length === 0 || !categories[0]) return res.sendStatus(404);
// Get longest lock reason
const reason = row.map(item => item.reason)
.reduce((a,b) => (a.length > b.length) ? a : b);
return res.send({
reason,
categories
});
} catch (err) {

View File

@@ -7,13 +7,15 @@ import { Category, VideoID, VideoIDHash } from "../types/segments.model";
interface LockResultByHash {
videoID: VideoID,
hash: VideoIDHash,
reason: string,
categories: Category[]
}
interface DBLock {
videoID: VideoID,
hash: VideoIDHash,
category: Category
category: Category,
reason: string,
}
const mergeLocks = (source: DBLock[]) => {
@@ -22,12 +24,15 @@ const mergeLocks = (source: DBLock[]) => {
// videoID already exists
const destMatch = dest.find(s => s.videoID === obj.videoID);
if (destMatch) {
// override longer reason
if (obj.reason.length > destMatch.reason.length) destMatch.reason = obj.reason;
// push to categories
destMatch.categories.push(obj.category);
} else {
dest.push({
videoID: obj.videoID,
hash: obj.hash,
reason: obj.reason,
categories: [obj.category]
});
}

View File

@@ -275,6 +275,10 @@ async function chooseSegments(segments: DBSegment[], max: number): Promise<DBSeg
*/
async function handleGetSegments(req: Request, res: Response): Promise<Segment[] | false> {
const videoID = req.query.videoID as VideoID;
if (!videoID) {
res.status(400).send("videoID not specified");
return false;
}
// Default to sponsor
// If using params instead of JSON, only one category can be pulled
const categories: Category[] = req.query.categories

View File

@@ -5,7 +5,7 @@ import { ActionType, Category, SegmentUUID, Service, VideoIDHash } from "../type
export async function getSkipSegmentsByHash(req: Request, res: Response): Promise<Response> {
let hashPrefix = req.params.prefix as VideoIDHash;
if (!hashPrefixTester(req.params.prefix)) {
if (!req.params.prefix || !hashPrefixTester(req.params.prefix)) {
return res.status(400).send("Hash prefix does not match format requirements."); // Exit early on faulty prefix
}
hashPrefix = hashPrefix.toLowerCase() as VideoIDHash;

View File

@@ -6,6 +6,8 @@ import {getHash} from "../utils/getHash";
import { HashedUserID, UserID } from "../types/user.model";
export async function postWarning(req: Request, res: Response): Promise<Response> {
// exit early if no body passed in
if (!req.body.userID && !req.body.issuerUserID) return res.status(400).json({"message": "Missing parameters"});
// Collect user input data
const issuerUserID: HashedUserID = getHash(<UserID> req.body.issuerUserID);
const userID: UserID = req.body.userID;

View File

@@ -10,9 +10,9 @@ export function skipSegmentsHashKey(hashedVideoIDPrefix: VideoIDHash, service: S
hashedVideoIDPrefix = hashedVideoIDPrefix.substring(0, 4) as VideoIDHash;
if (hashedVideoIDPrefix.length !== 4) Logger.warn(`Redis skip segment hash-prefix key is not length 4! ${hashedVideoIDPrefix}`);
return `segments.v2.${ service }.${ hashedVideoIDPrefix}`;
return `segments.v2.${service}.${hashedVideoIDPrefix}`;
}
export function reputationKey(userID: UserID): string {
return `reputation.user.${ userID}`;
return `reputation.user.${userID}`;
}

View File

@@ -7,12 +7,14 @@ interface ReputationDBResult {
totalSubmissions: number,
downvotedSubmissions: number,
nonSelfDownvotedSubmissions: number,
upvotedSum: number,
votedSum: number,
lockedSum: number,
semiOldUpvotedSubmissions: number,
oldUpvotedSubmissions: number
}
export async function getReputation(userID: UserID): Promise<number> {
const weekAgo = Date.now() - 1000 * 60 * 60 * 24 * 45; // 45 days ago
const pastDate = Date.now() - 1000 * 60 * 60 * 24 * 45; // 45 days ago
// 1596240000000 is August 1st 2020, a little after auto upvote was disabled
const fetchFromDB = () => db.prepare("get",
@@ -23,10 +25,11 @@ export async function getReputation(userID: UserID): Promise<number> {
WHERE b."userID" = ?
AND b."votes" > 0 AND b."category" = "a"."category" AND b."videoID" = "a"."videoID" LIMIT 1)
THEN 1 ELSE 0 END) AS "nonSelfDownvotedSubmissions",
SUM(CASE WHEN "votes" > 0 AND "timeSubmitted" > 1596240000000 THEN "votes" ELSE 0 END) AS "upvotedSum",
SUM(CASE WHEN "timeSubmitted" > 1596240000000 THEN "votes" ELSE 0 END) AS "votedSum",
SUM(locked) AS "lockedSum",
SUM(CASE WHEN "timeSubmitted" < ? AND "timeSubmitted" > 1596240000000 AND "votes" > 0 THEN 1 ELSE 0 END) AS "semiOldUpvotedSubmissions",
SUM(CASE WHEN "timeSubmitted" < ? AND "timeSubmitted" > 1596240000000 AND "votes" > 0 THEN 1 ELSE 0 END) AS "oldUpvotedSubmissions"
FROM "sponsorTimes" as "a" WHERE "userID" = ?`, [userID, pastDate, userID]) as Promise<ReputationDBResult>;
FROM "sponsorTimes" as "a" WHERE "userID" = ?`, [userID, weekAgo, pastDate, userID]) as Promise<ReputationDBResult>;
const result = await QueryCacher.get(fetchFromDB, reputationKey(userID));
@@ -45,11 +48,19 @@ export async function getReputation(userID: UserID): Promise<number> {
return convertRange(Math.min(nonSelfDownvoteRatio, 0.4), 0.05, 0.4, -0.5, -2.5);
}
if (result.oldUpvotedSubmissions < 3 || result.upvotedSum < 5) {
if (result.votedSum < 5) {
return 0;
}
return convertRange(Math.min(result.upvotedSum, 150), 5, 150, 0, 7) + convertRange(Math.min(result.lockedSum ?? 0, 50), 0, 50, 0, 20);
if (result.oldUpvotedSubmissions < 3) {
if (result.semiOldUpvotedSubmissions > 3) {
return convertRange(Math.min(result.votedSum, 150), 5, 150, 0, 2) + convertRange(Math.min(result.lockedSum ?? 0, 50), 0, 50, 0, 5);
} else {
return 0;
}
}
return convertRange(Math.min(result.votedSum, 150), 5, 150, 0, 7) + convertRange(Math.min(result.lockedSum ?? 0, 50), 0, 50, 0, 20);
}
function convertRange(value: number, currentMin: number, currentMax: number, targetMin: number, targetMax: number): number {