Add more strict requirements for voting for original thumbnails

This commit is contained in:
Ajay 2024-09-01 18:56:29 -04:00
parent 13b8a988db
commit 258749ac31
2 changed files with 67 additions and 3 deletions

View file

@ -120,7 +120,7 @@ export async function postBranding(req: Request, res: Response) {
})(), (async () => { })(), (async () => {
if (thumbnail) { if (thumbnail) {
// ignore original submissions from banned users - hiding those would cause issues // ignore original submissions from banned users - hiding those would cause issues
if (thumbnail.original && isBanned) return; if (thumbnail.original && (isBanned || !await canSubmitOriginal(hashedUserID, isVip))) return;
const existingUUID = thumbnail.original const existingUUID = thumbnail.original
? (await db.prepare("get", `SELECT "UUID" from "thumbnails" where "videoID" = ? AND "original" = 1`, [videoID]))?.UUID ? (await db.prepare("get", `SELECT "UUID" from "thumbnails" where "videoID" = ? AND "original" = 1`, [videoID]))?.UUID
@ -299,6 +299,14 @@ export async function verifyOldSubmissions(hashedUserID: HashedUserID, verificat
} }
} }
async function canSubmitOriginal(hashedUserID: HashedUserID, isVip: boolean): Promise<boolean> {
const upvotedThumbs = (await db.prepare("get", `SELECT count(*) as upvotedThumbs FROM "thumbnails" JOIN "thumbnailVotes" ON "thumbnails"."UUID" = "thumbnailVotes"."UUID" WHERE "thumbnailVotes"."votes" > 0 AND "thumbnails"."original" = 0 AND "thumbnails"."userID" = ?`, [hashedUserID])).upvotedThumbs;
const customThumbs = (await db.prepare("get", `SELECT count(*) as customThumbs FROM "thumbnails" JOIN "thumbnailVotes" ON "thumbnails"."UUID" = "thumbnailVotes"."UUID" WHERE "thumbnailVotes"."votes" >= 0 AND "thumbnails"."original" = 0 AND "thumbnails"."userID" = ?`, [hashedUserID])).customThumbs;
const originalThumbs = (await db.prepare("get", `SELECT count(*) as originalThumbs FROM "thumbnails" JOIN "thumbnailVotes" ON "thumbnails"."UUID" = "thumbnailVotes"."UUID" WHERE "thumbnailVotes"."votes" >= 0 AND "thumbnails"."original" = 1 AND "thumbnails"."userID" = ?`, [hashedUserID])).originalThumbs;
return isVip || (upvotedThumbs > 1 && customThumbs > 1 && originalThumbs / customThumbs < 0.4);
}
async function sendWebhooks(videoID: VideoID, UUID: BrandingUUID, voteType: BrandingVoteType) { async function sendWebhooks(videoID: VideoID, UUID: BrandingUUID, voteType: BrandingVoteType) {
const currentSubmission = await db.prepare( const currentSubmission = await db.prepare(
"get", "get",

View file

@ -49,10 +49,23 @@ describe("postBranding", () => {
const insertThumbnailQuery = 'INSERT INTO "thumbnails" ("videoID", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?)'; const insertThumbnailQuery = 'INSERT INTO "thumbnails" ("videoID", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?)';
await db.prepare("run", insertThumbnailQuery, ["postBrandLocked1", 0, getHash(userID3), Service.YouTube, getHash("postBrandLocked1"), Date.now(), "postBrandLocked1"]); await db.prepare("run", insertThumbnailQuery, ["postBrandLocked1", 0, getHash(userID3), Service.YouTube, getHash("postBrandLocked1"), Date.now(), "postBrandLocked1"]);
await db.prepare("run", insertThumbnailQuery, ["postBrandLocked2", 1, getHash(userID4), Service.YouTube, getHash("postBrandLocked2"), Date.now(), "postBrandLocked2"]); await db.prepare("run", insertThumbnailQuery, ["postBrandLocked2", 1, getHash(userID4), Service.YouTube, getHash("postBrandLocked2"), Date.now(), "postBrandLocked2"]);
const insertThumbnailVotesQuery = 'INSERT INTO "thumbnailVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, ?, ?, ?);'; const insertThumbnailVotesQuery = 'INSERT INTO "thumbnailVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, ?, ?, ?);';
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandLocked1", 0, 1, 0]); await db.prepare("run", insertThumbnailVotesQuery, ["postBrandLocked1", 0, 1, 0]);
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandLocked2", 0, 1, 0]); await db.prepare("run", insertThumbnailVotesQuery, ["postBrandLocked2", 0, 1, 0]);
// Approved original thumbnail submitter
await db.prepare("run", insertThumbnailQuery, ["postBrandOriginThumb", 0, getHash(userID4), Service.YouTube, getHash("postBrandOriginThumb"), Date.now(), "postBrandOriginThumb"]);
await db.prepare("run", insertThumbnailQuery, ["postBrandOriginThumb2", 0, getHash(userID4), Service.YouTube, getHash("postBrandOriginThumb2"), Date.now(), "postBrandOriginThumb2"]);
await db.prepare("run", insertThumbnailQuery, ["postBrandOriginThumb3", 0, getHash(userID4), Service.YouTube, getHash("postBrandOriginThumb3"), Date.now(), "postBrandOriginThumb3"]);
await db.prepare("run", insertThumbnailQuery, ["postBrandOriginThumb4", 0, getHash(userID4), Service.YouTube, getHash("postBrandOriginThumb4"), Date.now(), "postBrandOriginThumb4"]);
await db.prepare("run", insertThumbnailQuery, ["postBrandOriginThumb5", 0, getHash(userID4), Service.YouTube, getHash("postBrandOriginThumb5"), Date.now(), "postBrandOriginThumb5"]);
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandOriginThumb", 4, 0, 0]);
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandOriginThumb2", 1, 0, 0]);
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandOriginThumb3", 0, 0, 0]);
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandOriginThumb4", 0, 0, 0]);
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandOriginThumb5", 0, 0, 0]);
// Testing vip submission removal // Testing vip submission removal
await db.prepare("run", insertTitleQuery, ["postBrandRemoved1", "Some title", 0, getHash(userID1), Service.YouTube, getHash("postBrandRemoved1"), Date.now(), "postBrandRemoved1"]); await db.prepare("run", insertTitleQuery, ["postBrandRemoved1", "Some title", 0, getHash(userID1), Service.YouTube, getHash("postBrandRemoved1"), Date.now(), "postBrandRemoved1"]);
await db.prepare("run", insertTitleVotesQuery, ["postBrandRemoved1", 0, 1, 0, 0]); await db.prepare("run", insertTitleVotesQuery, ["postBrandRemoved1", 0, 1, 0, 0]);
@ -139,7 +152,7 @@ describe("postBranding", () => {
assert.strictEqual(dbVotes.shadowHidden, 0); assert.strictEqual(dbVotes.shadowHidden, 0);
}); });
it("Submit only original thumbnail", async () => { it("Submit only original thumbnail without permission", async () => {
const videoID = "postBrand3"; const videoID = "postBrand3";
const thumbnail = { const thumbnail = {
original: true original: true
@ -152,6 +165,25 @@ describe("postBranding", () => {
videoID videoID
}); });
assert.strictEqual(res.status, 200);
const dbThumbnail = await queryThumbnailByVideo(videoID);
assert.strictEqual(dbThumbnail, undefined);
});
it("Submit only original thumbnail with permission", async () => {
const videoID = "postBrand3";
const thumbnail = {
original: true
};
const res = await postBranding({
thumbnail,
userID: userID4,
service: Service.YouTube,
videoID
});
assert.strictEqual(res.status, 200); assert.strictEqual(res.status, 200);
const dbThumbnail = await queryThumbnailByVideo(videoID); const dbThumbnail = await queryThumbnailByVideo(videoID);
const dbVotes = await queryThumbnailVotesByUUID(dbThumbnail.UUID); const dbVotes = await queryThumbnailVotesByUUID(dbThumbnail.UUID);
@ -163,6 +195,30 @@ describe("postBranding", () => {
assert.strictEqual(dbVotes.shadowHidden, 0); assert.strictEqual(dbVotes.shadowHidden, 0);
}); });
it("Submit only original thumbnail as VIP", async () => {
const videoID = "postBrandV3";
const thumbnail = {
original: true
};
const res = await postBranding({
thumbnail,
userID: vipUser,
service: Service.YouTube,
videoID
});
assert.strictEqual(res.status, 200);
const dbThumbnail = await queryThumbnailByVideo(videoID);
const dbVotes = await queryThumbnailVotesByUUID(dbThumbnail.UUID);
assert.strictEqual(dbThumbnail.original, thumbnail.original ? 1 : 0);
assert.strictEqual(dbVotes.votes, 0);
assert.strictEqual(dbVotes.locked, 1);
assert.strictEqual(dbVotes.shadowHidden, 0);
});
it("Submit only custom thumbnail", async () => { it("Submit only custom thumbnail", async () => {
const videoID = "postBrand4"; const videoID = "postBrand4";
const thumbnail = { const thumbnail = {
@ -873,7 +929,7 @@ describe("postBranding", () => {
const res = await postBranding({ const res = await postBranding({
thumbnail, thumbnail,
userID: userID3, userID: userID4,
service: Service.YouTube, service: Service.YouTube,
videoID videoID
}); });