Replace VIP starting with 1000 votes with locked submissions

This commit is contained in:
Ajay Ramachandran 2021-02-18 20:24:04 -05:00
parent ef21ceb332
commit 57adcd3c65
5 changed files with 81 additions and 20 deletions

View file

@ -50,7 +50,7 @@ function getSegmentsByVideoID(req: Request, videoID: string, categories: Categor
const segmentsByCategory: SBRecord<Category, DBSegment[]> = db
.prepare(
'all',
`SELECT startTime, endTime, votes, UUID, category, shadowHidden FROM sponsorTimes WHERE videoID = ? AND category IN (${Array(categories.length).fill('?').join()}) ORDER BY startTime`,
`SELECT startTime, endTime, votes, locked, UUID, category, shadowHidden FROM sponsorTimes WHERE videoID = ? AND category IN (${Array(categories.length).fill('?').join()}) ORDER BY startTime`,
[videoID, categories]
).reduce((acc: SBRecord<Category, DBSegment[]>, segment: DBSegment) => {
acc[segment.category] = acc[segment.category] || [];
@ -82,7 +82,7 @@ function getSegmentsByHash(req: Request, hashedVideoIDPrefix: VideoIDHash, categ
const segmentPerVideoID: SegmentWithHashPerVideoID = db
.prepare(
'all',
`SELECT videoID, startTime, endTime, votes, UUID, category, shadowHidden, hashedVideoID FROM sponsorTimes WHERE hashedVideoID LIKE ? AND category IN (${Array(categories.length).fill('?').join()}) ORDER BY startTime`,
`SELECT videoID, startTime, endTime, votes, locked, UUID, category, shadowHidden, hashedVideoID FROM sponsorTimes WHERE hashedVideoID LIKE ? AND category IN (${Array(categories.length).fill('?').join()}) ORDER BY startTime`,
[hashedVideoIDPrefix + '%', categories]
).reduce((acc: SegmentWithHashPerVideoID, segment: DBSegment) => {
acc[segment.videoID] = acc[segment.videoID] || {
@ -176,7 +176,7 @@ function chooseSegments(segments: DBSegment[]): DBSegment[] {
let cursor = -1; //-1 to make sure that, even if the 1st segment starts at 0, a new group is created
segments.forEach(segment => {
if (segment.startTime > cursor) {
currentGroup = {segments: [], votes: 0};
currentGroup = {segments: [], votes: 0, locked: false};
overlappingSegmentsGroups.push(currentGroup);
}
@ -186,9 +186,19 @@ function chooseSegments(segments: DBSegment[]): DBSegment[] {
currentGroup.votes += segment.votes;
}
if (segment.locked) {
currentGroup.locked = true;
}
cursor = Math.max(cursor, segment.endTime);
});
overlappingSegmentsGroups.forEach((group) => {
if (group.locked) {
group.segments = group.segments.filter((segment) => segment.locked);
}
});
//if there are too many groups, find the best 8
return getWeightedRandomChoice(overlappingSegmentsGroups, 32).map(
//randomly choose 1 good segment per group and return them

View file

@ -433,10 +433,6 @@ export async function postSkipSegments(req: Request, res: Response) {
}
let startingVotes = 0 + decreaseVotes;
if (isVIP) {
//this user is a vip, start them at a higher approval rating
startingVotes = 10000;
}
if (config.youtubeAPIKey !== null) {
let {err, data} = await new Promise((resolve) => {
@ -489,11 +485,12 @@ export async function postSkipSegments(req: Request, res: Response) {
//also better for duplication checking
const UUID = getSubmissionUUID(videoID, segmentInfo.category, userID, segmentInfo.segment[0], segmentInfo.segment[1]);
const startingLocked = isVIP ? 1 : 0;
try {
db.prepare('run', "INSERT INTO sponsorTimes " +
"(videoID, startTime, endTime, votes, UUID, userID, timeSubmitted, views, category, shadowHidden, hashedVideoID)" +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
videoID, segmentInfo.segment[0], segmentInfo.segment[1], startingVotes, UUID, userID, timeSubmitted, 0, segmentInfo.category, shadowBanned, getHash(videoID, 1),
"(videoID, startTime, endTime, votes, locked, UUID, userID, timeSubmitted, views, category, shadowHidden, hashedVideoID)" +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
videoID, segmentInfo.segment[0], segmentInfo.segment[1], startingVotes, startingLocked, UUID, userID, timeSubmitted, 0, segmentInfo.category, shadowBanned, getHash(videoID, 1),
],
);

View file

@ -25,6 +25,7 @@ export interface DBSegment {
endTime: number;
UUID: SegmentUUID;
votes: number;
locked: boolean;
shadowHidden: Visibility;
videoID: VideoID;
hashedVideoID: VideoIDHash;
@ -33,6 +34,7 @@ export interface DBSegment {
export interface OverlappingSegmentGroup {
segments: DBSegment[],
votes: number;
locked: boolean; // Contains a locked segment
}
export interface VotableObject {

View file

@ -5,14 +5,16 @@ import {getHash} from '../../src/utils/getHash';
describe('getSkipSegments', () => {
before(() => {
let startOfQuery = "INSERT INTO sponsorTimes (videoID, startTime, endTime, votes, UUID, userID, timeSubmitted, views, category, shadowHidden, hashedVideoID) VALUES";
db.exec(startOfQuery + "('testtesttest', 1, 11, 2, '1-uuid-0', 'testman', 0, 50, 'sponsor', 0, '" + getHash('testtesttest', 1) + "')");
db.exec(startOfQuery + "('testtesttest', 20, 33, 2, '1-uuid-2', 'testman', 0, 50, 'intro', 0, '" + getHash('testtesttest', 1) + "')");
db.exec(startOfQuery + "('testtesttest,test', 1, 11, 2, '1-uuid-1', 'testman', 0, 50, 'sponsor', 0, '" + getHash('testtesttest,test', 1) + "')");
db.exec(startOfQuery + "('test3', 1, 11, 2, '1-uuid-4', 'testman', 0, 50, 'sponsor', 0, '" + getHash('test3', 1) + "')");
db.exec(startOfQuery + "('test3', 7, 22, -3, '1-uuid-5', 'testman', 0, 50, 'sponsor', 0, '" + getHash('test3', 1) + "')");
db.exec(startOfQuery + "('multiple', 1, 11, 2, '1-uuid-6', 'testman', 0, 50, 'intro', 0, '" + getHash('multiple', 1) + "')");
db.exec(startOfQuery + "('multiple', 20, 33, 2, '1-uuid-7', 'testman', 0, 50, 'intro', 0, '" + getHash('multiple', 1) + "')");
let startOfQuery = "INSERT INTO sponsorTimes (videoID, startTime, endTime, votes, locked, UUID, userID, timeSubmitted, views, category, shadowHidden, hashedVideoID) VALUES";
db.exec(startOfQuery + "('testtesttest', 1, 11, 2, 0, '1-uuid-0', 'testman', 0, 50, 'sponsor', 0, '" + getHash('testtesttest', 1) + "')");
db.exec(startOfQuery + "('testtesttest', 20, 33, 2, 0, '1-uuid-2', 'testman', 0, 50, 'intro', 0, '" + getHash('testtesttest', 1) + "')");
db.exec(startOfQuery + "('testtesttest,test', 1, 11, 2, 0, '1-uuid-1', 'testman', 0, 50, 'sponsor', 0, '" + getHash('testtesttest,test', 1) + "')");
db.exec(startOfQuery + "('test3', 1, 11, 2, 0, '1-uuid-4', 'testman', 0, 50, 'sponsor', 0, '" + getHash('test3', 1) + "')");
db.exec(startOfQuery + "('test3', 7, 22, -3, 0, '1-uuid-5', 'testman', 0, 50, 'sponsor', 0, '" + getHash('test3', 1) + "')");
db.exec(startOfQuery + "('multiple', 1, 11, 2, 0, '1-uuid-6', 'testman', 0, 50, 'intro', 0, '" + getHash('multiple', 1) + "')");
db.exec(startOfQuery + "('multiple', 20, 33, 2, 0, '1-uuid-7', 'testman', 0, 50, 'intro', 0, '" + getHash('multiple', 1) + "')");
db.exec(startOfQuery + "('locked', 20, 33, 2, 1, '1-uuid-locked-8', 'testman', 0, 50, 'intro', 0, '" + getHash('locked', 1) + "')");
db.exec(startOfQuery + "('locked', 20, 34, 100000, 0, '1-uuid-9', 'testman', 0, 50, 'intro', 0, '" + getHash('locked', 1) + "')");
});
@ -207,4 +209,21 @@ describe('getSkipSegments', () => {
.catch(err => done("Couldn't call endpoint"));
});
it('Should always get locked segment', (done: Done) => {
fetch(getbaseURL() + "/api/skipSegments?videoID=locked&category=intro")
.then(async res => {
if (res.status !== 200) done("Status code was: " + res.status);
else {
const data = await res.json();
if (data.length === 1 && data[0].segment[0] === 20 && data[0].segment[1] === 33
&& data[0].category === "intro" && data[0].UUID === "1-uuid-locked-8") {
done();
} else {
done("Received incorrect body: " + (await res.text()));
}
}
})
.catch(err => done("Couldn't call endpoint"));
});
});

View file

@ -39,6 +39,8 @@ describe('postSkipSegments', () => {
db.exec(startOfWarningQuery + "('" + warnUser03Hash + "', '" + (now - 1000) + "', '" + warnVip01Hash + "', 0)");
db.exec(startOfWarningQuery + "('" + warnUser03Hash + "', '" + (now - 2000) + "', '" + warnVip01Hash + "', 1)");
db.exec(startOfWarningQuery + "('" + warnUser03Hash + "', '" + (now - 3601000) + "', '" + warnVip01Hash + "', 1)");
db.exec("INSERT INTO vipUsers (userID) VALUES ('" + getHash("VIPUserSubmission") + "')");
});
it('Should be able to submit a single time (Params method)', (done: Done) => {
@ -82,8 +84,8 @@ describe('postSkipSegments', () => {
})
.then(res => {
if (res.status === 200) {
const row = db.prepare('get', "SELECT startTime, endTime, category FROM sponsorTimes WHERE videoID = ?", ["dQw4w9WgXcF"]);
if (row.startTime === 0 && row.endTime === 10 && row.category === "sponsor") {
const row = db.prepare('get', "SELECT startTime, endTime, locked, category FROM sponsorTimes WHERE videoID = ?", ["dQw4w9WgXcF"]);
if (row.startTime === 0 && row.endTime === 10 && row.locked === 0 && row.category === "sponsor") {
done();
} else {
done("Submitted times were not saved. Actual submission: " + JSON.stringify(row));
@ -95,6 +97,37 @@ describe('postSkipSegments', () => {
.catch(err => done(err));
});
it('VIP submission should start locked', (done: Done) => {
fetch(getbaseURL()
+ "/api/postVideoSponsorTimes", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
userID: "VIPUserSubmission",
videoID: "vipuserIDSubmission",
segments: [{
segment: [0, 10],
category: "sponsor",
}],
}),
})
.then(res => {
if (res.status === 200) {
const row = db.prepare('get', "SELECT startTime, endTime, locked, category FROM sponsorTimes WHERE videoID = ?", ["vipuserIDSubmission"]);
if (row.startTime === 0 && row.endTime === 10 && row.locked === 1 && row.category === "sponsor") {
done();
} else {
done("Submitted times were not saved. Actual submission: " + JSON.stringify(row));
}
} else {
done("Status code was " + res.status);
}
})
.catch(err => done(err));
});
it('Should be able to submit multiple times (JSON method)', (done: Done) => {
fetch(getbaseURL()
+ "/api/postVideoSponsorTimes", {