mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-06 11:36:58 +03:00
Compare commits
2 Commits
1eedc9fa09
...
6d5b6dd3ae
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d5b6dd3ae | ||
|
|
0412386870 |
@@ -1,16 +1,18 @@
|
||||
import { db } from "../databases/databases";
|
||||
import { Request, Response } from "express";
|
||||
import { getService } from "../utils/getService";
|
||||
|
||||
export async function getSegmentID(req: Request, res: Response): Promise<Response> {
|
||||
const partialUUID = req.query?.UUID;
|
||||
const videoID = req.query?.videoID;
|
||||
const service = getService(req.query?.service as string);
|
||||
|
||||
if (!partialUUID || !videoID) {
|
||||
//invalid request
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
const data = await db.prepare("get", `SELECT "UUID" from "sponsorTimes" WHERE "UUID" LIKE ? AND "videoID" = ?`, [`${partialUUID}%`, videoID]);
|
||||
const data = await db.prepare("get", `SELECT "UUID" from "sponsorTimes" WHERE "UUID" LIKE ? AND "videoID" = ? AND "service" = ?`, [`${partialUUID}%`, videoID, service]);
|
||||
|
||||
if (data) {
|
||||
return res.status(200).send(data.UUID);
|
||||
|
||||
@@ -141,8 +141,8 @@ async function autoModerateSubmission(apiVideoDetails: videoDetails,
|
||||
.map(segment => [parseFloat(segment.segment[0]), parseFloat(segment.segment[1])]);
|
||||
|
||||
// add previous submissions by this user
|
||||
const allSubmittedByUser = await db.prepare("all", `SELECT "startTime", "endTime" FROM "sponsorTimes" WHERE "userID" = ? AND "videoID" = ? AND "votes" > -1 AND "actionType" != 'chapter' AND "hidden" = 0`
|
||||
, [submission.userID, submission.videoID]) as { startTime: string, endTime: string }[];
|
||||
const allSubmittedByUser = await db.prepare("all", `SELECT "startTime", "endTime" FROM "sponsorTimes" WHERE "userID" = ? AND "videoID" = ? AND "service" = ? AND "votes" > -1 AND "actionType" != 'chapter' AND "hidden" = 0`
|
||||
, [submission.userID, submission.videoID, submission.service]) as { startTime: string, endTime: string }[];
|
||||
|
||||
if (allSubmittedByUser) {
|
||||
//add segments the user has previously submitted
|
||||
@@ -195,12 +195,17 @@ async function checkInvalidFields(videoID: VideoID, userID: UserID, hashedUserID
|
||||
if (typeof videoID !== "string" || videoID?.length == 0) {
|
||||
invalidFields.push("videoID");
|
||||
}
|
||||
if (service === Service.YouTube && config.mode !== "test") {
|
||||
const sanitizedVideoID = youtubeID.validate(videoID) ? videoID : youtubeID.sanitize(videoID);
|
||||
if (!youtubeID.validate(sanitizedVideoID)) {
|
||||
invalidFields.push("videoID");
|
||||
errors.push("YouTube videoID could not be extracted");
|
||||
if (service === Service.YouTube) {
|
||||
if (config.mode !== "test") {
|
||||
const sanitizedVideoID = youtubeID.validate(videoID) ? videoID : youtubeID.sanitize(videoID);
|
||||
if (!youtubeID.validate(sanitizedVideoID)) {
|
||||
invalidFields.push("videoID");
|
||||
errors.push("YouTube videoID could not be extracted");
|
||||
}
|
||||
}
|
||||
} else if (service !== Service.Spotify) {
|
||||
invalidFields.push("service");
|
||||
errors.push("Service is not supported");
|
||||
}
|
||||
const minLength = config.minUserIDLength;
|
||||
if (typeof userID !== "string" || userID?.length < minLength) {
|
||||
@@ -360,6 +365,15 @@ async function checkByAutoModerator(videoID: VideoID, userID: HashedUserID, segm
|
||||
async function updateDataIfVideoDurationChange(videoID: VideoID, service: Service, videoDuration: VideoDuration, videoDurationParam: VideoDuration) {
|
||||
let lockedCategoryList = await db.prepare("all", 'SELECT category, "actionType", reason from "lockCategories" where "videoID" = ? AND "service" = ?', [videoID, service]);
|
||||
|
||||
if (service === Service.Spotify) {
|
||||
// Don't handle changed durations
|
||||
return {
|
||||
videoDuration,
|
||||
apiVideoDetails: null,
|
||||
lockedCategoryList
|
||||
};
|
||||
}
|
||||
|
||||
const previousSubmissions = await db.prepare("all",
|
||||
`SELECT "videoDuration", "UUID"
|
||||
FROM "sponsorTimes"
|
||||
@@ -617,10 +631,12 @@ export async function postSkipSegments(req: Request, res: Response): Promise<Res
|
||||
//add to private db as well
|
||||
await privateDB.prepare("run", `INSERT INTO "sponsorTimes" VALUES(?, ?, ?, ?)`, [videoID, hashedIP, timeSubmitted, service]);
|
||||
|
||||
await db.prepare("run", `INSERT INTO "videoInfo" ("videoID", "channelID", "title", "published")
|
||||
SELECT ?, ?, ?, ?
|
||||
WHERE NOT EXISTS (SELECT 1 FROM "videoInfo" WHERE "videoID" = ?)`, [
|
||||
videoID, apiVideoDetails?.authorId || "", apiVideoDetails?.title || "", apiVideoDetails?.published || 0, videoID]);
|
||||
if (service === Service.YouTube) {
|
||||
await db.prepare("run", `INSERT INTO "videoInfo" ("videoID", "channelID", "title", "published")
|
||||
SELECT ?, ?, ?, ?
|
||||
WHERE NOT EXISTS (SELECT 1 FROM "videoInfo" WHERE "videoID" = ?)`, [
|
||||
videoID, apiVideoDetails?.authorId || "", apiVideoDetails?.title || "", apiVideoDetails?.published || 0, videoID]);
|
||||
}
|
||||
|
||||
// Clear redis cache for this video
|
||||
QueryCacher.clearSegmentCache({
|
||||
|
||||
@@ -22,7 +22,8 @@ export enum ActionType {
|
||||
// Uncomment as needed
|
||||
export enum Service {
|
||||
YouTube = "YouTube",
|
||||
PeerTube = "PeerTube",
|
||||
Spotify = "Spotify",
|
||||
PeerTube = "PeerTube"
|
||||
// Twitch = 'Twitch',
|
||||
// Nebula = 'Nebula',
|
||||
// RSS = 'RSS',
|
||||
|
||||
@@ -30,6 +30,7 @@ describe("getSkipSegments", () => {
|
||||
await db.prepare("run", query, ["chapterVid", 71, 75, 2, 0, "chapterVid-3", "testman", 0, 50, "chapter", "chapter", "YouTube", 0, 0, 0, "Chapter 3"]);
|
||||
await db.prepare("run", query, ["requiredSegmentHashVid", 10, 20, -2, 0, "1d04b98f48e8f8bcc15c6ae5ac050801cd6dcfd428fb5f9e65c4e16e7807340fa", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, 0, ""]);
|
||||
await db.prepare("run", query, ["requiredSegmentHashVid", 20, 30, -2, 0, "1ebde8e8ae03096b6c866aa2c8cc7ee1d720ca1fca27bea3f39a6a1b876577e71", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, 0, ""]);
|
||||
await db.prepare("run", query, ["getSkipSegmentID0", 1, 12, 1, 0, "uuid01-spot", "testman", 0, 50, "sponsor", "skip", "Spotify", 100, 0, 0, ""]);
|
||||
return;
|
||||
});
|
||||
|
||||
@@ -495,4 +496,22 @@ describe("getSkipSegments", () => {
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to get a time by category for spotify service", (done) => {
|
||||
client.get(endpoint, { params: { videoID: "getSkipSegmentID0", category: "sponsor", service: "spotify" } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
assert.strictEqual(data.length, 1);
|
||||
assert.strictEqual(data[0].segment[0], 1);
|
||||
assert.strictEqual(data[0].segment[1], 12);
|
||||
assert.strictEqual(data[0].category, "sponsor");
|
||||
assert.strictEqual(data[0].UUID, "uuid01-spot");
|
||||
assert.strictEqual(data[0].votes, 1);
|
||||
assert.strictEqual(data[0].locked, 0);
|
||||
assert.strictEqual(data[0].videoDuration, 100);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,8 +46,8 @@ describe("postSkipSegments", () => {
|
||||
|
||||
const submitVIPuser = `VIPPostSkipUser${".".repeat(16)}`;
|
||||
|
||||
const queryDatabase = (videoID: string) => db.prepare("get", `SELECT "startTime", "endTime", "votes", "userID", "locked", "category", "actionType" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoID]);
|
||||
const queryDatabaseActionType = (videoID: string) => db.prepare("get", `SELECT "startTime", "endTime", "locked", "category", "actionType" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoID]);
|
||||
const queryDatabase = (videoID: string, service = "YouTube") => db.prepare("get", `SELECT "startTime", "endTime", "votes", "userID", "locked", "category", "actionType" FROM "sponsorTimes" WHERE "videoID" = ? AND "service" = ?`, [videoID, service]);
|
||||
const queryDatabaseActionType = (videoID: string, service = "YouTube") => db.prepare("get", `SELECT "startTime", "endTime", "locked", "category", "actionType" FROM "sponsorTimes" WHERE "videoID" = ? AND "service" = ?`, [videoID, service]);
|
||||
const queryDatabaseVideoInfo = (videoID: string) => db.prepare("get", `SELECT * FROM "videoInfo" WHERE "videoID" = ?`, [videoID]);
|
||||
|
||||
before(async () => {
|
||||
@@ -142,33 +142,6 @@ describe("postSkipSegments", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to submit a single time under a different service (JSON method)", (done) => {
|
||||
const videoID = "postSkip7";
|
||||
postSkipSegmentJSON({
|
||||
userID: submitUserOne,
|
||||
videoID,
|
||||
service: "PeerTube",
|
||||
segments: [{
|
||||
segment: [0, 10],
|
||||
category: "sponsor",
|
||||
}],
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await db.prepare("get", `SELECT "startTime", "endTime", "locked", "category", "service" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoID]);
|
||||
const expected = {
|
||||
startTime: 0,
|
||||
endTime: 10,
|
||||
locked: 0,
|
||||
category: "sponsor",
|
||||
service: "PeerTube",
|
||||
};
|
||||
assert.ok(partialDeepEquals(row, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("VIP submission should start locked", (done) => {
|
||||
const videoID = "vipuserIDSubmission";
|
||||
postSkipSegmentJSON({
|
||||
@@ -374,4 +347,55 @@ describe("postSkipSegments", () => {
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to submit for spotify service", (done) => {
|
||||
const videoID = "postSkipParamSingle";
|
||||
postSkipSegmentParam({
|
||||
videoID,
|
||||
startTime: 23,
|
||||
endTime: 105,
|
||||
userID: submitUserOne,
|
||||
category: "sponsor",
|
||||
service: "Spotify"
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await queryDatabase(videoID, "Spotify");
|
||||
const expected = {
|
||||
startTime: 23,
|
||||
endTime: 105,
|
||||
category: "sponsor",
|
||||
};
|
||||
assert.ok(partialDeepEquals(row, expected));
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to submit a time for spotify service (JSON method)", (done) => {
|
||||
const videoID = "postSkipJSONSingle";
|
||||
postSkipSegmentJSON({
|
||||
userID: submitUserOne,
|
||||
videoID,
|
||||
segments: [{
|
||||
segment: [22, 103],
|
||||
category: "sponsor",
|
||||
}],
|
||||
service: "Spotify"
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await queryDatabase(videoID, "Spotify");
|
||||
const expected = {
|
||||
startTime: 22,
|
||||
endTime: 103,
|
||||
locked: 0,
|
||||
category: "sponsor",
|
||||
};
|
||||
assert.ok(partialDeepEquals(row, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user