diff --git a/databases/_upgrade_sponsorTimes_30.sql b/databases/_upgrade_sponsorTimes_30.sql new file mode 100644 index 0000000..f9b9a39 --- /dev/null +++ b/databases/_upgrade_sponsorTimes_30.sql @@ -0,0 +1,7 @@ +BEGIN TRANSACTION; + +UPDATE "sponsorTimes" SET "actionType" = 'poi' WHERE "category" = 'poi_highlight'; + +UPDATE "config" SET value = 30 WHERE key = 'version'; + +COMMIT; \ No newline at end of file diff --git a/src/routes/getSkipSegments.ts b/src/routes/getSkipSegments.ts index 81c0af2..6f3f898 100644 --- a/src/routes/getSkipSegments.ts +++ b/src/routes/getSkipSegments.ts @@ -66,6 +66,12 @@ async function getSegmentsByVideoID(req: Request, videoID: VideoID, categories: actionTypes: ActionType[], requiredSegments: SegmentUUID[], service: Service): Promise { const cache: SegmentCache = { shadowHiddenSegmentIPs: {} }; + // For old clients + const forcePoiAsSkip = !actionTypes.includes(ActionType.Poi) && categories.includes("poi_highlight" as Category); + if (forcePoiAsSkip) { + actionTypes.push(ActionType.Poi); + } + try { categories = categories.filter((category) => !/[^a-z|_|-]/.test(category)); if (categories.length === 0) return null; @@ -77,9 +83,17 @@ async function getSegmentsByVideoID(req: Request, videoID: VideoID, categories: }, {}); const canUseCache = requiredSegments.length === 0; - const processedSegments: Segment[] = await prepareCategorySegments(req, videoID, service, segments, cache, canUseCache); + let processedSegments: Segment[] = (await prepareCategorySegments(req, videoID, service, segments, cache, canUseCache)) + .filter((segment: Segment) => categories.includes(segment?.category) && (actionTypes.includes(segment?.actionType))); - return processedSegments.filter((segment: Segment) => categories.includes(segment?.category) && actionTypes.includes(segment?.actionType)); + if (forcePoiAsSkip) { + processedSegments = processedSegments.map((segment) => ({ + ...segment, + actionType: ActionType.Skip + })); + } + + return processedSegments; } catch (err) { if (err) { Logger.error(err as string); @@ -93,6 +107,12 @@ async function getSegmentsByHash(req: Request, hashedVideoIDPrefix: VideoIDHash, const cache: SegmentCache = { shadowHiddenSegmentIPs: {} }; const segments: SBRecord = {}; + // For old clients + const forcePoiAsSkip = !actionTypes.includes(ActionType.Poi) && categories.includes("poi_highlight" as Category); + if (forcePoiAsSkip) { + actionTypes.push(ActionType.Poi); + } + try { type SegmentWithHashPerVideoID = SBRecord; @@ -123,6 +143,13 @@ async function getSegmentsByHash(req: Request, hashedVideoIDPrefix: VideoIDHash, data.segments = (await prepareCategorySegments(req, videoID as VideoID, service, videoData.segments, cache, canUseCache)) .filter((segment: Segment) => categories.includes(segment?.category) && actionTypes.includes(segment?.actionType)); + if (forcePoiAsSkip) { + data.segments = data.segments.map((segment) => ({ + ...segment, + actionType: ActionType.Skip + })); + } + if (data.segments.length > 0) { segments[videoID] = data; } diff --git a/src/types/segments.model.ts b/src/types/segments.model.ts index 04c5d1a..f2e6103 100644 --- a/src/types/segments.model.ts +++ b/src/types/segments.model.ts @@ -14,7 +14,8 @@ export enum ActionType { Skip = "skip", Mute = "mute", Chapter = "chapter", - Full = "full" + Full = "full", + Poi = "poi" } // Uncomment as needed diff --git a/test/cases/getSkipSegmentsByHash.ts b/test/cases/getSkipSegmentsByHash.ts index 0161906..4d18a0a 100644 --- a/test/cases/getSkipSegmentsByHash.ts +++ b/test/cases/getSkipSegmentsByHash.ts @@ -28,8 +28,8 @@ describe("getSkipSegmentsByHash", () => { await db.prepare("run", query, ["getSegmentsByHash-noMatchHash", 40, 50, 2, 0, "getSegmentsByHash-noMatchHash", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, "fdaffnoMatchHash", ""]); await db.prepare("run", query, ["getSegmentsByHash-1", 60, 70, 2, 0, "getSegmentsByHash-1", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, "3272fa85ee0927f6073ef6f07ad5f3146047c1abba794cfa364d65ab9921692b", ""]); await db.prepare("run", query, ["onlyHidden", 60, 70, 2, 0, "onlyHidden", "testman", 0, 50, "sponsor", "skip", "YouTube", 1, 0, "f3a199e1af001d716cdc6599360e2b062c2d2b3fa2885f6d9d2fd741166cbbd3", ""]); - await db.prepare("run", query, ["highlightVid", 60, 60, 2, 0, "highlightVid-1", "testman", 0, 50, "poi_highlight", "skip", "YouTube", 0, 0, getHash("highlightVid", 1), ""]); - await db.prepare("run", query, ["highlightVid", 70, 70, 2, 0, "highlightVid-2", "testman", 0, 50, "poi_highlight", "skip", "YouTube", 0, 0, getHash("highlightVid", 1), ""]); + await db.prepare("run", query, ["highlightVid", 60, 60, 2, 0, "highlightVid-1", "testman", 0, 50, "poi_highlight", "poi", "YouTube", 0, 0, getHash("highlightVid", 1), ""]); + await db.prepare("run", query, ["highlightVid", 70, 70, 2, 0, "highlightVid-2", "testman", 0, 50, "poi_highlight", "poi", "YouTube", 0, 0, getHash("highlightVid", 1), ""]); await db.prepare("run", query, ["requiredSegmentVid", 60, 70, 2, 0, "requiredSegmentVid-1", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, requiredSegmentVidHash, ""]); await db.prepare("run", query, ["requiredSegmentVid", 60, 70, -2, 0, "requiredSegmentVid-2", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, requiredSegmentVidHash, ""]); await db.prepare("run", query, ["requiredSegmentVid", 80, 90, -2, 0, "requiredSegmentVid-3", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, requiredSegmentVidHash, ""]); @@ -276,12 +276,28 @@ describe("getSkipSegmentsByHash", () => { }); it("Should only return one segment when fetching highlight segments", (done) => { + client.get(`${endpoint}/c962`, { params: { category: "poi_highlight", actionType: "poi" } }) + .then(res => { + assert.strictEqual(res.status, 200); + const data = res.data; + assert.strictEqual(data.length, 1); + assert.strictEqual(data[0].segments.length, 1); + assert.strictEqual(data[0].segments[0].category, "poi_highlight"); + assert.strictEqual(data[0].segments[0].actionType, "poi"); + done(); + }) + .catch(err => done(err)); + }); + + it("Should return skip actionType for highlight for old clients", (done) => { client.get(`${endpoint}/c962`, { params: { category: "poi_highlight" } }) .then(res => { assert.strictEqual(res.status, 200); const data = res.data; assert.strictEqual(data.length, 1); assert.strictEqual(data[0].segments.length, 1); + assert.strictEqual(data[0].segments[0].category, "poi_highlight"); + assert.strictEqual(data[0].segments[0].actionType, "skip"); done(); }) .catch(err => done(err));