mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-25 00:48:22 +03:00
Merge branch 'master' into categoryLeaderboards
This commit is contained in:
71
src/routes/addUserAsTempVIP.ts
Normal file
71
src/routes/addUserAsTempVIP.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { VideoID } from "../types/segments.model";
|
||||
import { YouTubeAPI } from "../utils/youtubeApi";
|
||||
import { APIVideoInfo } from "../types/youtubeApi.model";
|
||||
import { config } from "../config";
|
||||
import { getHashCache } from "../utils/getHashCache";
|
||||
import { privateDB } from "../databases/databases";
|
||||
import { Request, Response } from "express";
|
||||
import { isUserVIP } from "../utils/isUserVIP";
|
||||
import { HashedUserID } from "../types/user.model";
|
||||
import redis from "../utils/redis";
|
||||
import { tempVIPKey } from "../utils/redisKeys";
|
||||
|
||||
interface AddUserAsTempVIPRequest extends Request {
|
||||
query: {
|
||||
userID: HashedUserID;
|
||||
adminUserID: string;
|
||||
enabled: string;
|
||||
channelVideoID: string;
|
||||
}
|
||||
}
|
||||
|
||||
function getYouTubeVideoInfo(videoID: VideoID, ignoreCache = false): Promise<APIVideoInfo> {
|
||||
return (config.newLeafURLs) ? YouTubeAPI.listVideos(videoID, ignoreCache) : null;
|
||||
}
|
||||
|
||||
const getChannelInfo = async (videoID: VideoID): Promise<{id: string | null, name: string | null }> => {
|
||||
const videoInfo = await getYouTubeVideoInfo(videoID);
|
||||
return {
|
||||
id: videoInfo?.data?.authorId,
|
||||
name: videoInfo?.data?.author
|
||||
};
|
||||
};
|
||||
|
||||
export async function addUserAsTempVIP(req: AddUserAsTempVIPRequest, res: Response): Promise<Response> {
|
||||
const { query: { userID, adminUserID } } = req;
|
||||
|
||||
const enabled = req.query?.enabled === "true";
|
||||
const channelVideoID = req.query?.channelVideoID as VideoID;
|
||||
|
||||
if (!userID || !adminUserID || !channelVideoID ) {
|
||||
// invalid request
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
// hash the issuer userID
|
||||
const issuerUserID = await getHashCache(adminUserID);
|
||||
// check if issuer is VIP
|
||||
const issuerIsVIP = await isUserVIP(issuerUserID as HashedUserID);
|
||||
if (!issuerIsVIP) {
|
||||
return res.sendStatus(403);
|
||||
}
|
||||
|
||||
// check to see if this user is already a vip
|
||||
const targetIsVIP = await isUserVIP(userID);
|
||||
if (targetIsVIP) {
|
||||
return res.sendStatus(409);
|
||||
}
|
||||
|
||||
const startTime = Date.now();
|
||||
const dayInSeconds = 86400;
|
||||
const channelInfo = await getChannelInfo(channelVideoID);
|
||||
|
||||
await privateDB.prepare("run", `INSERT INTO "tempVipLog" VALUES (?, ?, ?, ?)`, [adminUserID, userID, + enabled, startTime]);
|
||||
if (enabled) { // add to redis
|
||||
await redis.setAsyncEx(tempVIPKey(userID), channelInfo?.id, dayInSeconds);
|
||||
} else { // delete key
|
||||
await redis.delAsync(tempVIPKey(userID));
|
||||
}
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
@@ -307,7 +307,7 @@ function splitPercentOverlap(groups: OverlappingSegmentGroup[]): OverlappingSegm
|
||||
const overlapPercent = overlap / overallDuration;
|
||||
return (overlapPercent > 0 && segment.actionType === compareSegment.actionType && segment.category === compareSegment.category && segment.actionType !== ActionType.Chapter)
|
||||
|| (overlapPercent >= 0.6 && segment.actionType !== compareSegment.actionType && segment.category === compareSegment.category)
|
||||
|| (overlapPercent >= 0.8 && segment.actionType === compareSegment.actionType && segment.category !== compareSegment.category
|
||||
|| (overlapPercent >= 0.95 && segment.actionType === compareSegment.actionType && segment.category !== compareSegment.category
|
||||
&& segment.category !== "music_offtopic" && compareSegment.category !== "music_offtopic")
|
||||
|| (overlapPercent >= 0.8 && segment.actionType === ActionType.Chapter && compareSegment.actionType === ActionType.Chapter);
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import { db } from "../databases/databases";
|
||||
import { Logger } from "../utils/logger";
|
||||
import { Request, Response } from "express";
|
||||
import os from "os";
|
||||
import redis from "../utils/redis";
|
||||
|
||||
export async function getStatus(req: Request, res: Response): Promise<Response> {
|
||||
const startTime = Date.now();
|
||||
@@ -9,13 +10,16 @@ export async function getStatus(req: Request, res: Response): Promise<Response>
|
||||
value = Array.isArray(value) ? value[0] : value;
|
||||
try {
|
||||
const dbVersion = (await db.prepare("get", "SELECT key, value FROM config where key = ?", ["version"])).value;
|
||||
const numberRequests = await redis.increment("statusRequest");
|
||||
const statusRequests = numberRequests?.replies?.[0];
|
||||
const statusValues: Record<string, any> = {
|
||||
uptime: process.uptime(),
|
||||
commit: (global as any).HEADCOMMIT || "unknown",
|
||||
db: Number(dbVersion),
|
||||
startTime,
|
||||
processTime: Date.now() - startTime,
|
||||
loadavg: os.loadavg().slice(1) // only return 5 & 15 minute load average
|
||||
loadavg: os.loadavg().slice(1), // only return 5 & 15 minute load average
|
||||
statusRequests
|
||||
};
|
||||
return value ? res.send(JSON.stringify(statusValues[value])) : res.send(statusValues);
|
||||
} catch (err) {
|
||||
|
||||
@@ -9,11 +9,13 @@ import { getFormattedTime } from "../utils/getFormattedTime";
|
||||
import { getIP } from "../utils/getIP";
|
||||
import { getHashCache } from "../utils/getHashCache";
|
||||
import { config } from "../config";
|
||||
import { UserID } from "../types/user.model";
|
||||
import { HashedUserID, UserID } from "../types/user.model";
|
||||
import { Category, CategoryActionType, HashedIP, IPAddress, SegmentUUID, Service, VideoID, VideoIDHash, Visibility, VideoDuration } from "../types/segments.model";
|
||||
import { getCategoryActionType } from "../utils/categoryInfo";
|
||||
import { QueryCacher } from "../utils/queryCacher";
|
||||
import axios from "axios";
|
||||
import redis from "../utils/redis";
|
||||
import { tempVIPKey } from "../utils/redisKeys";
|
||||
|
||||
const voteTypes = {
|
||||
normal: 0,
|
||||
@@ -37,6 +39,7 @@ interface VoteData {
|
||||
UUID: string;
|
||||
nonAnonUserID: string;
|
||||
voteTypeEnum: number;
|
||||
isTempVIP: boolean;
|
||||
isVIP: boolean;
|
||||
isOwnSubmission: boolean;
|
||||
row: {
|
||||
@@ -57,6 +60,13 @@ function getYouTubeVideoInfo(videoID: VideoID, ignoreCache = false): Promise<API
|
||||
}
|
||||
}
|
||||
|
||||
const isUserTempVIP = async (nonAnonUserID: HashedUserID, videoID: VideoID): Promise<boolean> => {
|
||||
const apiVideoInfo = await getYouTubeVideoInfo(videoID);
|
||||
const channelID = apiVideoInfo?.data?.authorId;
|
||||
const { err, reply } = await redis.getAsync(tempVIPKey(nonAnonUserID));
|
||||
return err ? false : (reply == channelID);
|
||||
};
|
||||
|
||||
const videoDurationChanged = (segmentDuration: number, APIDuration: number) => (APIDuration > 0 && Math.abs(segmentDuration - APIDuration) > 2);
|
||||
|
||||
async function checkVideoDurationChange(UUID: SegmentUUID) {
|
||||
@@ -105,7 +115,7 @@ async function sendWebhooks(voteData: VoteData) {
|
||||
// Send custom webhooks
|
||||
dispatchEvent(isUpvote ? "vote.up" : "vote.down", {
|
||||
"user": {
|
||||
"status": getVoteAuthorRaw(userSubmissionCountRow.submissionCount, voteData.isVIP, voteData.isOwnSubmission),
|
||||
"status": getVoteAuthorRaw(userSubmissionCountRow.submissionCount, voteData.isTempVIP, voteData.isVIP, voteData.isOwnSubmission),
|
||||
},
|
||||
"video": {
|
||||
"id": submissionInfoRow.videoID,
|
||||
@@ -153,7 +163,7 @@ async function sendWebhooks(voteData: VoteData) {
|
||||
"author": {
|
||||
"name": voteData.finalResponse?.webhookMessage ??
|
||||
voteData.finalResponse?.finalMessage ??
|
||||
getVoteAuthor(userSubmissionCountRow.submissionCount, voteData.isVIP, voteData.isOwnSubmission),
|
||||
getVoteAuthor(userSubmissionCountRow.submissionCount, voteData.isTempVIP, voteData.isVIP, voteData.isOwnSubmission),
|
||||
},
|
||||
"thumbnail": {
|
||||
"url": getMaxResThumbnail(data) || "",
|
||||
@@ -311,7 +321,9 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<Re
|
||||
const hashedIP: HashedIP = await getHashCache((ip + config.globalSalt) as IPAddress);
|
||||
|
||||
//check if this user is on the vip list
|
||||
const isVIP = await isUserVIP(nonAnonUserID);
|
||||
const videoID = await db.prepare("get", `select "videoID" from "sponsorTimes" where "UUID" = ?`, [UUID]);
|
||||
const isTempVIP = await isUserTempVIP(nonAnonUserID, videoID?.videoID || null);
|
||||
const isVIP = await isUserVIP(nonAnonUserID) || isTempVIP;
|
||||
|
||||
//check if user voting on own submission
|
||||
const isOwnSubmission = (await db.prepare("get", `SELECT "UUID" as "submissionCount" FROM "sponsorTimes" where "userID" = ? AND "UUID" = ?`, [nonAnonUserID, UUID])) !== undefined;
|
||||
@@ -480,6 +492,7 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<Re
|
||||
UUID,
|
||||
nonAnonUserID,
|
||||
voteTypeEnum,
|
||||
isTempVIP,
|
||||
isVIP,
|
||||
isOwnSubmission,
|
||||
row: videoInfo,
|
||||
|
||||
Reference in New Issue
Block a user