mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-07 03:57:06 +03:00
add custom pagination in getSearchSegments
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import { db } from "../databases/databases";
|
import { db } from "../databases/databases";
|
||||||
import { ActionType, Category, DBSegment, Service, VideoID } from "../types/segments.model";
|
import { ActionType, Category, DBSegment, Service, VideoID, SortableFields } from "../types/segments.model";
|
||||||
import { getService } from "../utils/getService";
|
import { getService } from "../utils/getService";
|
||||||
const segmentsPerPage = 10;
|
const maxSegmentsPerPage = 100;
|
||||||
|
|
||||||
type searchSegmentResponse = {
|
type searchSegmentResponse = {
|
||||||
segmentCount: number,
|
segmentCount: number,
|
||||||
@@ -19,6 +19,22 @@ function getSegmentsFromDBByVideoID(videoID: VideoID, service: Service): Promise
|
|||||||
) as Promise<DBSegment[]>;
|
) as Promise<DBSegment[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSortField<T extends string>(...value: T[]): SortableFields {
|
||||||
|
const fieldByName = Object.values(SortableFields).reduce((acc, fieldName) => {
|
||||||
|
acc[fieldName.toLowerCase()] = fieldName;
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<string, SortableFields>);
|
||||||
|
|
||||||
|
for (const name of value) {
|
||||||
|
if (name?.trim().toLowerCase() in fieldByName) {
|
||||||
|
return fieldByName[name.trim().toLowerCase()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SortableFields.timeSubmitted;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns what would be sent to the client.
|
* Returns what would be sent to the client.
|
||||||
@@ -64,6 +80,10 @@ async function handleGetSegments(req: Request, res: Response): Promise<searchSeg
|
|||||||
|
|
||||||
let page: number = req.query.page ?? req.body.page ?? 0;
|
let page: number = req.query.page ?? req.body.page ?? 0;
|
||||||
page = Number(page);
|
page = Number(page);
|
||||||
|
let limit: number = req.query.limit ?? req.body.limit ?? 10;
|
||||||
|
limit = Number(limit) > maxSegmentsPerPage ? maxSegmentsPerPage : Number(limit);
|
||||||
|
const sortBy: SortableFields = getSortField(req.query.sortBy, req.body.sortBy);
|
||||||
|
const sortDir: string = req.query.sortDir ?? req.body.sortDir ?? "asc";
|
||||||
|
|
||||||
const minVotes: number = req.query.minVotes ?? req.body.minVotes ?? -3;
|
const minVotes: number = req.query.minVotes ?? req.body.minVotes ?? -3;
|
||||||
const maxVotes: number = req.query.maxVotes ?? req.body.maxVotes ?? Infinity;
|
const maxVotes: number = req.query.maxVotes ?? req.body.maxVotes ?? Infinity;
|
||||||
@@ -99,11 +119,11 @@ async function handleGetSegments(req: Request, res: Response): Promise<searchSeg
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return filterSegments(segments, page, filters);
|
return filterSegments(segments, filters, page, limit, sortBy, sortDir);
|
||||||
}
|
}
|
||||||
function filterSegments(segments: DBSegment[], page: number, filters: Record<string, any>) {
|
function filterSegments(segments: DBSegment[], filters: Record<string, any>, page: number, limit: number, sortBy: SortableFields, sortDir: string) {
|
||||||
const startIndex = 0+(page*segmentsPerPage);
|
const startIndex = 0+(page*limit);
|
||||||
const endIndex = segmentsPerPage+(page*segmentsPerPage);
|
const endIndex = limit+(page*limit);
|
||||||
const filteredSegments = segments.filter((segment) =>
|
const filteredSegments = segments.filter((segment) =>
|
||||||
!((segment.votes < filters.minVotes || segment.votes > filters.maxVotes)
|
!((segment.votes < filters.minVotes || segment.votes > filters.maxVotes)
|
||||||
|| (segment.views < filters.minViews || segment.views > filters.maxViews)
|
|| (segment.views < filters.minViews || segment.views > filters.maxViews)
|
||||||
@@ -114,10 +134,27 @@ function filterSegments(segments: DBSegment[], page: number, filters: Record<str
|
|||||||
// return false if any of the conditions are met
|
// return false if any of the conditions are met
|
||||||
// return true if none of the conditions are met
|
// return true if none of the conditions are met
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (sortBy !== SortableFields.timeSubmitted) {
|
||||||
|
filteredSegments.sort((a,b) => {
|
||||||
|
const key = sortDir === "desc" ? 1 : -1;
|
||||||
|
if (a[sortBy] < b[sortBy]) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a[sortBy] > b[sortBy]) {
|
||||||
|
return -key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
segmentCount: filteredSegments.length,
|
segmentCount: filteredSegments.length,
|
||||||
page,
|
page,
|
||||||
segments: filteredSegments.slice(startIndex, endIndex)
|
segments: filteredSegments.slice(startIndex, endIndex)
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,4 +107,12 @@ export interface LockCategory {
|
|||||||
reason: string,
|
reason: string,
|
||||||
videoID: VideoID,
|
videoID: VideoID,
|
||||||
userID: UserID
|
userID: UserID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SortableFields {
|
||||||
|
timeSubmitted = "timeSubmitted",
|
||||||
|
startTime = "startTime",
|
||||||
|
endTime = "endTime",
|
||||||
|
votes = "votes",
|
||||||
|
views = "views",
|
||||||
|
}
|
||||||
|
|||||||
@@ -282,4 +282,70 @@ describe("getSearchSegments", () => {
|
|||||||
})
|
})
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should be able to get with custom limit", (done) => {
|
||||||
|
client.get(endpoint, { params: { videoID: "searchTest4", limit: 2 } })
|
||||||
|
.then(res => {
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const data = res.data;
|
||||||
|
const segments = data.segments;
|
||||||
|
assert.strictEqual(data.segmentCount, 12);
|
||||||
|
assert.strictEqual(data.page, 0);
|
||||||
|
assert.strictEqual(segments.length, 2);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to get with custom limit(2) and page(2)", (done) => {
|
||||||
|
client.get(endpoint, { params: { videoID: "searchTest4", limit: 2, page: 2 } })
|
||||||
|
.then(res => {
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const data = res.data;
|
||||||
|
const segments = data.segments;
|
||||||
|
assert.strictEqual(data.segmentCount, 12);
|
||||||
|
assert.strictEqual(data.page, 2);
|
||||||
|
assert.strictEqual(segments.length, 2);
|
||||||
|
assert.strictEqual(segments[0].UUID, "search-page1-5");
|
||||||
|
assert.strictEqual(segments[1].UUID, "search-page1-6");
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to get sorted result (desc)", (done) => {
|
||||||
|
client.get(endpoint, { params: { videoID: "searchTest4", sortBy: "endTime", sortDir: "desc" } })
|
||||||
|
.then(res => {
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const data = res.data;
|
||||||
|
const segments = data.segments;
|
||||||
|
assert.strictEqual(data.segmentCount, 12);
|
||||||
|
assert.strictEqual(data.page, 0);
|
||||||
|
assert.strictEqual(segments[0].UUID, "search-page2-2");
|
||||||
|
assert.strictEqual(segments[1].UUID, "search-page2-1");
|
||||||
|
assert.strictEqual(segments[2].UUID, "search-page1-10");
|
||||||
|
assert.strictEqual(segments[3].UUID, "search-page1-9");
|
||||||
|
assert.strictEqual(segments[4].UUID, "search-page1-8");
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to get sorted result (asc)", (done) => {
|
||||||
|
client.get(endpoint, { params: { videoID: "searchTest4", sortBy: "endTime" } })
|
||||||
|
.then(res => {
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const data = res.data;
|
||||||
|
const segments = data.segments;
|
||||||
|
assert.strictEqual(data.segmentCount, 12);
|
||||||
|
assert.strictEqual(data.page, 0);
|
||||||
|
assert.strictEqual(segments[0].UUID, "search-page1-1");
|
||||||
|
assert.strictEqual(segments[1].UUID, "search-page1-2");
|
||||||
|
assert.strictEqual(segments[2].UUID, "search-page1-3");
|
||||||
|
assert.strictEqual(segments[3].UUID, "search-page1-4");
|
||||||
|
assert.strictEqual(segments[4].UUID, "search-page1-5");
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user