mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-13 23:17:02 +03:00
Unlock videos and hide segments if duration changed
This commit is contained in:
@@ -5,7 +5,7 @@ import {oldGetVideoSponsorTimes} from './routes/oldGetVideoSponsorTimes';
|
||||
import {postSegmentShift} from './routes/postSegmentShift';
|
||||
import {postWarning} from './routes/postWarning';
|
||||
import {getIsUserVIP} from './routes/getIsUserVIP';
|
||||
import {deleteNoSegments} from './routes/deleteNoSegments';
|
||||
import {deleteNoSegmentsEndpoint} from './routes/deleteNoSegments';
|
||||
import {postNoSegments} from './routes/postNoSegments';
|
||||
import {getUserInfo} from './routes/getUserInfo';
|
||||
import {getDaysSavedFormatted} from './routes/getDaysSavedFormatted';
|
||||
@@ -117,7 +117,7 @@ function setupRoutes(app: Express) {
|
||||
//submit video containing no segments
|
||||
app.post('/api/noSegments', postNoSegments);
|
||||
|
||||
app.delete('/api/noSegments', deleteNoSegments);
|
||||
app.delete('/api/noSegments', deleteNoSegmentsEndpoint);
|
||||
|
||||
//get if user is a vip
|
||||
app.get('/api/isUserVIP', getIsUserVIP);
|
||||
|
||||
@@ -2,12 +2,14 @@ import {Request, Response} from 'express';
|
||||
import {isUserVIP} from '../utils/isUserVIP';
|
||||
import {getHash} from '../utils/getHash';
|
||||
import {db} from '../databases/databases';
|
||||
import { Category, VideoID } from '../types/segments.model';
|
||||
import { UserID } from '../types/user.model';
|
||||
|
||||
export async function deleteNoSegments(req: Request, res: Response) {
|
||||
export async function deleteNoSegmentsEndpoint(req: Request, res: Response) {
|
||||
// Collect user input data
|
||||
const videoID = req.body.videoID;
|
||||
let userID = req.body.userID;
|
||||
const categories = req.body.categories;
|
||||
const videoID = req.body.videoID as VideoID;
|
||||
const userID = req.body.userID as UserID;
|
||||
const categories = req.body.categories as Category[];
|
||||
|
||||
// Check input data is valid
|
||||
if (!videoID
|
||||
@@ -23,8 +25,8 @@ export async function deleteNoSegments(req: Request, res: Response) {
|
||||
}
|
||||
|
||||
// Check if user is VIP
|
||||
userID = getHash(userID);
|
||||
const userIsVIP = await isUserVIP(userID);
|
||||
const hashedUserID = getHash(userID);
|
||||
const userIsVIP = await isUserVIP(hashedUserID);
|
||||
|
||||
if (!userIsVIP) {
|
||||
res.status(403).json({
|
||||
@@ -33,13 +35,22 @@ export async function deleteNoSegments(req: Request, res: Response) {
|
||||
return;
|
||||
}
|
||||
|
||||
deleteNoSegments(videoID, categories);
|
||||
|
||||
res.status(200).json({message: 'Removed no segments entrys for video ' + videoID});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param videoID
|
||||
* @param categories If null, will remove all
|
||||
*/
|
||||
export async function deleteNoSegments(videoID: VideoID, categories: Category[]): Promise<void> {
|
||||
const entries = (await db.prepare("all", 'SELECT * FROM "noSegments" WHERE "videoID" = ?', [videoID])).filter((entry: any) => {
|
||||
return (categories.indexOf(entry.category) !== -1);
|
||||
return categories === null || categories.indexOf(entry.category) !== -1;
|
||||
});
|
||||
|
||||
for (const entry of entries) {
|
||||
await db.prepare('run', 'DELETE FROM "noSegments" WHERE "videoID" = ? AND "category" = ?', [videoID, entry.category]);
|
||||
}
|
||||
|
||||
res.status(200).json({message: 'Removed no segments entrys for video ' + videoID});
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ async function getSegmentsByVideoID(req: Request, videoID: string, categories: C
|
||||
.prepare(
|
||||
'all',
|
||||
`SELECT "startTime", "endTime", "votes", "locked", "UUID", "category", "videoDuration", "shadowHidden" FROM "sponsorTimes"
|
||||
WHERE "videoID" = ? AND "category" IN (${categories.map((c) => "'" + c + "'")}) AND "service" = ? ORDER BY "startTime"`,
|
||||
WHERE "videoID" = ? AND "category" IN (${categories.map((c) => "'" + c + "'")}) AND "service" = ? AND "hidden" = 0 ORDER BY "startTime"`,
|
||||
[videoID, service]
|
||||
)).reduce((acc: SBRecord<Category, DBSegment[]>, segment: DBSegment) => {
|
||||
acc[segment.category] = acc[segment.category] || [];
|
||||
@@ -132,7 +132,7 @@ async function getSegmentsFromDB(hashedVideoIDPrefix: VideoIDHash, service: Serv
|
||||
.prepare(
|
||||
'all',
|
||||
`SELECT "videoID", "startTime", "endTime", "votes", "locked", "UUID", "category", "videoDuration", "shadowHidden", "hashedVideoID" FROM "sponsorTimes"
|
||||
WHERE "hashedVideoID" LIKE ? AND "service" = ? ORDER BY "startTime"`,
|
||||
WHERE "hashedVideoID" LIKE ? AND "service" = ? AND "hidden" = 0 ORDER BY "startTime"`,
|
||||
[hashedVideoIDPrefix + '%', service]
|
||||
);
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ import {dispatchEvent} from '../utils/webhookUtils';
|
||||
import {Request, Response} from 'express';
|
||||
import { skipSegmentsHashKey, skipSegmentsKey } from '../middleware/redisKeys';
|
||||
import redis from '../utils/redis';
|
||||
import { Category, IncomingSegment, Segment, Service, VideoDuration, VideoID } from '../types/segments.model';
|
||||
import { Category, IncomingSegment, Segment, SegmentUUID, Service, VideoDuration, VideoID } from '../types/segments.model';
|
||||
import { deleteNoSegments } from './deleteNoSegments';
|
||||
|
||||
interface APIVideoInfo {
|
||||
err: string | boolean,
|
||||
@@ -357,7 +358,7 @@ export async function postSkipSegments(req: Request, res: Response) {
|
||||
return res.status(403).send('Submission rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. Could you please send a message in Discord or Matrix so we can further help you?');
|
||||
}
|
||||
|
||||
const noSegmentList = (await db.prepare('all', 'SELECT category from "noSegments" where "videoID" = ?', [videoID])).map((list: any) => {
|
||||
let noSegmentList = (await db.prepare('all', 'SELECT category from "noSegments" where "videoID" = ?', [videoID])).map((list: any) => {
|
||||
return list.category;
|
||||
});
|
||||
|
||||
@@ -366,6 +367,31 @@ export async function postSkipSegments(req: Request, res: Response) {
|
||||
|
||||
const decreaseVotes = 0;
|
||||
|
||||
let apiVideoInfo: APIVideoInfo = null;
|
||||
if (service == Service.YouTube) {
|
||||
apiVideoInfo = await getYouTubeVideoInfo(videoID);
|
||||
}
|
||||
const apiVideoDuration = getYouTubeVideoDuration(apiVideoInfo);
|
||||
if (!videoDuration || (apiVideoDuration && Math.abs(videoDuration - apiVideoDuration) > 2)) {
|
||||
// If api duration is far off, take that one instead (it is only precise to seconds, not millis)
|
||||
videoDuration = apiVideoDuration || 0 as VideoDuration;
|
||||
}
|
||||
|
||||
const previousSubmissions = await db.prepare('all', `SELECT "videoDuration", "UUID" FROM "sponsorTimes" WHERE "videoID" = ? AND "service" = ? AND "hidden" = 0 AND "shadowHidden" = 0 AND "votes" >= 0`, [videoID, service]) as
|
||||
{videoDuration: VideoDuration, UUID: SegmentUUID}[];
|
||||
// If the video's duration is changed, then the video should be unlocked and old submissions should be hidden
|
||||
const videoDurationChanged = previousSubmissions.length > 0 && !previousSubmissions.some((e) => Math.abs(videoDuration - e.videoDuration) < 2);
|
||||
if (videoDurationChanged) {
|
||||
// Hide all previous submissions
|
||||
for (const submission of previousSubmissions) {
|
||||
await db.prepare('run', `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "UUID" = ?`, [submission.UUID]);
|
||||
}
|
||||
|
||||
// Reset no segments
|
||||
noSegmentList = [];
|
||||
deleteNoSegments(videoID, null);
|
||||
}
|
||||
|
||||
// Check if all submissions are correct
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
if (segments[i] === undefined || segments[i].segment === undefined || segments[i].category === undefined) {
|
||||
@@ -419,16 +445,6 @@ export async function postSkipSegments(req: Request, res: Response) {
|
||||
}
|
||||
}
|
||||
|
||||
let apiVideoInfo: APIVideoInfo = null;
|
||||
if (service == Service.YouTube) {
|
||||
apiVideoInfo = await getYouTubeVideoInfo(videoID);
|
||||
}
|
||||
const apiVideoDuration = getYouTubeVideoDuration(apiVideoInfo);
|
||||
if (!videoDuration || (apiVideoDuration && Math.abs(videoDuration - apiVideoDuration) > 2)) {
|
||||
// If api duration is far off, take that one instead (it is only precise to seconds, not millis)
|
||||
videoDuration = apiVideoDuration || 0 as VideoDuration;
|
||||
}
|
||||
|
||||
// Auto moderator check
|
||||
if (!isVIP && service == Service.YouTube) {
|
||||
const autoModerateResult = await autoModerateSubmission(apiVideoInfo, {userID, videoID, segments});//startTime, endTime, category: segments[i].category});
|
||||
|
||||
Reference in New Issue
Block a user