mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-11 22:17:14 +03:00
Switch to null instead of undefined and fix indentation
This commit is contained in:
@@ -9,100 +9,100 @@ var getHash = require('../utils/getHash.js');
|
|||||||
var getIP = require('../utils/getIP.js');
|
var getIP = require('../utils/getIP.js');
|
||||||
|
|
||||||
function cleanGetSegments(videoID, categories) {
|
function cleanGetSegments(videoID, categories) {
|
||||||
let userHashedIP, shadowHiddenSegments;
|
let userHashedIP, shadowHiddenSegments;
|
||||||
|
|
||||||
let segments = [];
|
let segments = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const category of categories) {
|
for (const category of categories) {
|
||||||
const categorySegments = db
|
const categorySegments = db
|
||||||
.prepare(
|
.prepare(
|
||||||
'all',
|
'all',
|
||||||
'SELECT startTime, endTime, votes, UUID, shadowHidden FROM sponsorTimes WHERE videoID = ? and category = ? ORDER BY startTime',
|
'SELECT startTime, endTime, votes, UUID, shadowHidden FROM sponsorTimes WHERE videoID = ? and category = ? ORDER BY startTime',
|
||||||
[videoID, category]
|
[videoID, category]
|
||||||
)
|
)
|
||||||
.filter(segment => {
|
.filter(segment => {
|
||||||
if (segment.votes < -1) {
|
if (segment.votes < -1) {
|
||||||
return false; //too untrustworthy, just ignore it
|
return false; //too untrustworthy, just ignore it
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if shadowHidden
|
//check if shadowHidden
|
||||||
//this means it is hidden to everyone but the original ip that submitted it
|
//this means it is hidden to everyone but the original ip that submitted it
|
||||||
if (segment.shadowHidden != 1) {
|
if (segment.shadowHidden != 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shadowHiddenSegments === undefined) {
|
if (shadowHiddenSegments === undefined) {
|
||||||
shadowHiddenSegments = privateDB.prepare('all', 'SELECT hashedIP FROM sponsorTimes WHERE videoID = ?', [videoID]);
|
shadowHiddenSegments = privateDB.prepare('all', 'SELECT hashedIP FROM sponsorTimes WHERE videoID = ?', [videoID]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if this isn't their ip, don't send it to them
|
//if this isn't their ip, don't send it to them
|
||||||
return shadowHiddenSegments.some(shadowHiddenSegment => {
|
return shadowHiddenSegments.some(shadowHiddenSegment => {
|
||||||
if (userHashedIP === undefined) {
|
if (userHashedIP === undefined) {
|
||||||
//hash the IP only if it's strictly necessary
|
//hash the IP only if it's strictly necessary
|
||||||
userHashedIP = getHash(getIP(req) + config.globalSalt);
|
userHashedIP = getHash(getIP(req) + config.globalSalt);
|
||||||
}
|
}
|
||||||
return shadowHiddenSegment.hashedIP === userHashedIP;
|
return shadowHiddenSegment.hashedIP === userHashedIP;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
chooseSegments(categorySegments).forEach(chosenSegment => {
|
chooseSegments(categorySegments).forEach(chosenSegment => {
|
||||||
segments.push({
|
segments.push({
|
||||||
category,
|
category,
|
||||||
segment: [chosenSegment.startTime, chosenSegment.endTime],
|
segment: [chosenSegment.startTime, chosenSegment.endTime],
|
||||||
UUID: chosenSegment.UUID,
|
UUID: chosenSegment.UUID,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return segments;
|
||||||
|
} catch (err) {
|
||||||
|
if (err) {
|
||||||
|
logger.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return segments;
|
|
||||||
} catch (err) {
|
|
||||||
if (err) {
|
|
||||||
logger.error('j 2 Query failed');
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//gets a weighted random choice from the choices array based on their `votes` property.
|
//gets a weighted random choice from the choices array based on their `votes` property.
|
||||||
//amountOfChoices specifies the maximum amount of choices to return, 1 or more.
|
//amountOfChoices specifies the maximum amount of choices to return, 1 or more.
|
||||||
//choices are unique
|
//choices are unique
|
||||||
function getWeightedRandomChoice(choices, amountOfChoices) {
|
function getWeightedRandomChoice(choices, amountOfChoices) {
|
||||||
//trivial case: no need to go through the whole process
|
//trivial case: no need to go through the whole process
|
||||||
if (amountOfChoices >= choices.length) {
|
if (amountOfChoices >= choices.length) {
|
||||||
return choices;
|
return choices;
|
||||||
}
|
|
||||||
|
|
||||||
//assign a weight to each choice
|
|
||||||
let totalWeight = 0;
|
|
||||||
choices = choices.map(choice => {
|
|
||||||
//The 3 makes -2 the minimum votes before being ignored completely
|
|
||||||
//https://www.desmos.com/calculator/c1duhfrmts
|
|
||||||
//this can be changed if this system increases in popularity.
|
|
||||||
const weight = Math.exp((choice.votes + 3), 0.85);
|
|
||||||
totalWeight += weight;
|
|
||||||
|
|
||||||
return { ...choice, weight };
|
|
||||||
});
|
|
||||||
|
|
||||||
//iterate and find amountOfChoices choices
|
|
||||||
const chosen = [];
|
|
||||||
while (amountOfChoices-- > 0) {
|
|
||||||
//weighted random draw of one element of choices
|
|
||||||
const randomNumber = Math.random() * totalWeight;
|
|
||||||
let stackWeight = choices[0].weight;
|
|
||||||
let i = 0;
|
|
||||||
while (stackWeight < randomNumber) {
|
|
||||||
stackWeight += choices[++i].weight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add it to the chosen ones and remove it from the choices before the next iteration
|
//assign a weight to each choice
|
||||||
chosen.push(choices[i]);
|
let totalWeight = 0;
|
||||||
totalWeight -= choices[i].weight;
|
choices = choices.map(choice => {
|
||||||
choices.splice(i, 1);
|
//The 3 makes -2 the minimum votes before being ignored completely
|
||||||
}
|
//https://www.desmos.com/calculator/c1duhfrmts
|
||||||
|
//this can be changed if this system increases in popularity.
|
||||||
|
const weight = Math.exp((choice.votes + 3), 0.85);
|
||||||
|
totalWeight += weight;
|
||||||
|
|
||||||
return chosen;
|
return { ...choice, weight };
|
||||||
|
});
|
||||||
|
|
||||||
|
//iterate and find amountOfChoices choices
|
||||||
|
const chosen = [];
|
||||||
|
while (amountOfChoices-- > 0) {
|
||||||
|
//weighted random draw of one element of choices
|
||||||
|
const randomNumber = Math.random() * totalWeight;
|
||||||
|
let stackWeight = choices[0].weight;
|
||||||
|
let i = 0;
|
||||||
|
while (stackWeight < randomNumber) {
|
||||||
|
stackWeight += choices[++i].weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
//add it to the chosen ones and remove it from the choices before the next iteration
|
||||||
|
chosen.push(choices[i]);
|
||||||
|
totalWeight -= choices[i].weight;
|
||||||
|
choices.splice(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chosen;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function will find segments that are contained inside of eachother, called similar segments
|
//This function will find segments that are contained inside of eachother, called similar segments
|
||||||
@@ -110,34 +110,34 @@ function getWeightedRandomChoice(choices, amountOfChoices) {
|
|||||||
//This allows new less voted items to still sometimes appear to give them a chance at getting votes.
|
//This allows new less voted items to still sometimes appear to give them a chance at getting votes.
|
||||||
//Segments with less than -1 votes are already ignored before this function is called
|
//Segments with less than -1 votes are already ignored before this function is called
|
||||||
function chooseSegments(segments) {
|
function chooseSegments(segments) {
|
||||||
//Create groups of segments that are similar to eachother
|
//Create groups of segments that are similar to eachother
|
||||||
//Segments must be sorted by their startTime so that we can build groups chronologically:
|
//Segments must be sorted by their startTime so that we can build groups chronologically:
|
||||||
//1. As long as the segments' startTime fall inside the currentGroup, we keep adding them to that group
|
//1. As long as the segments' startTime fall inside the currentGroup, we keep adding them to that group
|
||||||
//2. If a segment starts after the end of the currentGroup (> cursor), no other segment will ever fall
|
//2. If a segment starts after the end of the currentGroup (> cursor), no other segment will ever fall
|
||||||
// inside that group (because they're sorted) so we can create a new one
|
// inside that group (because they're sorted) so we can create a new one
|
||||||
const similarSegmentsGroups = [];
|
const similarSegmentsGroups = [];
|
||||||
let currentGroup;
|
let currentGroup;
|
||||||
let cursor = -1; //-1 to make sure that, even if the 1st segment starts at 0, a new group is created
|
let cursor = -1; //-1 to make sure that, even if the 1st segment starts at 0, a new group is created
|
||||||
segments.forEach(segment => {
|
segments.forEach(segment => {
|
||||||
if (segment.startTime > cursor) {
|
if (segment.startTime > cursor) {
|
||||||
currentGroup = { segments: [], votes: 0 };
|
currentGroup = { segments: [], votes: 0 };
|
||||||
similarSegmentsGroups.push(currentGroup);
|
similarSegmentsGroups.push(currentGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentGroup.segments.push(segment);
|
currentGroup.segments.push(segment);
|
||||||
//only if it is a positive vote, otherwise it is probably just a sponsor time with slightly wrong time
|
//only if it is a positive vote, otherwise it is probably just a sponsor time with slightly wrong time
|
||||||
if (segment.votes > 0) {
|
if (segment.votes > 0) {
|
||||||
currentGroup.votes += segment.votes;
|
currentGroup.votes += segment.votes;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor = Math.max(cursor, segment.endTime);
|
cursor = Math.max(cursor, segment.endTime);
|
||||||
});
|
});
|
||||||
|
|
||||||
//if there are too many groups, find the best 8
|
//if there are too many groups, find the best 8
|
||||||
return getWeightedRandomChoice(similarSegmentsGroups, 8).map(
|
return getWeightedRandomChoice(similarSegmentsGroups, 8).map(
|
||||||
//randomly choose 1 good segment per group and return them
|
//randomly choose 1 good segment per group and return them
|
||||||
group => getWeightedRandomChoice(group.segments, 1)[0]
|
group => getWeightedRandomChoice(group.segments, 1)[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,39 +151,39 @@ function chooseSegments(segments) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function handleGetSegments(req, res) {
|
function handleGetSegments(req, res) {
|
||||||
const videoID = req.query.videoID;
|
const videoID = req.query.videoID;
|
||||||
// Default to sponsor
|
// Default to sponsor
|
||||||
// If using params instead of JSON, only one category can be pulled
|
// If using params instead of JSON, only one category can be pulled
|
||||||
const categories = req.query.categories
|
const categories = req.query.categories
|
||||||
? JSON.parse(req.query.categories)
|
? JSON.parse(req.query.categories)
|
||||||
: req.query.category
|
: req.query.category
|
||||||
? [req.query.category]
|
? [req.query.category]
|
||||||
: ['sponsor'];
|
: ['sponsor'];
|
||||||
|
|
||||||
let segments = cleanGetSegments(videoID, categories);
|
let segments = cleanGetSegments(videoID, categories);
|
||||||
|
|
||||||
if (segments === undefined) {
|
if (segments === null || segments === undefined) {
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segments.length == 0) {
|
if (segments.length == 0) {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return segments;
|
return segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
handleGetSegments,
|
handleGetSegments,
|
||||||
cleanGetSegments,
|
cleanGetSegments,
|
||||||
endpoint: function (req, res) {
|
endpoint: function (req, res) {
|
||||||
let segments = handleGetSegments(req, res);
|
let segments = handleGetSegments(req, res);
|
||||||
|
|
||||||
if (segments) {
|
if (segments) {
|
||||||
//send result
|
//send result
|
||||||
res.send(segments);
|
res.send(segments);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user