mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-06 11:36:58 +03:00
Merge remote-tracking branch 'origin/master' into master
This commit is contained in:
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:12
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
COPY package.json .
|
||||||
|
RUN npm install
|
||||||
|
COPY index.js .
|
||||||
|
COPY src src
|
||||||
|
COPY entrypoint.sh .
|
||||||
|
EXPOSE 8080
|
||||||
|
CMD ./entrypoint.sh
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
"discordReportChannelWebhookURL": null, //URL from discord if you would like notifications when someone makes a report [optional]
|
"discordReportChannelWebhookURL": null, //URL from discord if you would like notifications when someone makes a report [optional]
|
||||||
"discordFirstTimeSubmissionsWebhookURL": null, //URL from discord if you would like notifications when someone makes a first time submission [optional]
|
"discordFirstTimeSubmissionsWebhookURL": null, //URL from discord if you would like notifications when someone makes a first time submission [optional]
|
||||||
"discordCompletelyIncorrectReportWebhookURL": null, //URL from discord if you would like notifications when someone reports a submission as completely incorrect [optional]
|
"discordCompletelyIncorrectReportWebhookURL": null, //URL from discord if you would like notifications when someone reports a submission as completely incorrect [optional]
|
||||||
|
"proxySubmission": null, // Base url to proxy submissions to persist // e.g. https://sponsor.ajay.app (no trailing slash)
|
||||||
"behindProxy": "X-Forwarded-For", //Options: "X-Forwarded-For", "Cloudflare", "X-Real-IP", anything else will mean it is not behind a proxy. True defaults to "X-Forwarded-For"
|
"behindProxy": "X-Forwarded-For", //Options: "X-Forwarded-For", "Cloudflare", "X-Real-IP", anything else will mean it is not behind a proxy. True defaults to "X-Forwarded-For"
|
||||||
"db": "./databases/sponsorTimes.db",
|
"db": "./databases/sponsorTimes.db",
|
||||||
"privateDB": "./databases/private.db",
|
"privateDB": "./databases/private.db",
|
||||||
|
|||||||
26
entrypoint.sh
Executable file
26
entrypoint.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
echo 'Entrypoint script'
|
||||||
|
cd /usr/src/app
|
||||||
|
cp /etc/sponsorblock/config.json . || cat <<EOF > config.json
|
||||||
|
{
|
||||||
|
"port": 8080,
|
||||||
|
"globalSalt": "[CHANGE THIS]",
|
||||||
|
"adminUserID": "[CHANGE THIS]",
|
||||||
|
"youtubeAPIKey": null,
|
||||||
|
"discordReportChannelWebhookURL": null,
|
||||||
|
"discordFirstTimeSubmissionsWebhookURL": null,
|
||||||
|
"discordAutoModWebhookURL": null,
|
||||||
|
"proxySubmission": null,
|
||||||
|
"behindProxy": "X-Forwarded-For",
|
||||||
|
"db": "./databases/sponsorTimes.db",
|
||||||
|
"privateDB": "./databases/private.db",
|
||||||
|
"createDatabaseIfNotExist": true,
|
||||||
|
"schemaFolder": "./databases",
|
||||||
|
"dbSchema": "./databases/_sponsorTimes.db.sql",
|
||||||
|
"privateDBSchema": "./databases/_private.db.sql",
|
||||||
|
"mode": "development",
|
||||||
|
"readOnly": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
node index.js
|
||||||
5
index.js
5
index.js
@@ -1,5 +1,6 @@
|
|||||||
var config = require('./src/config.js');
|
var config = require('./src/config.js');
|
||||||
var createServer = require('./src/app.js');
|
var createServer = require('./src/app.js');
|
||||||
|
const logger = require('./src/utils/logger.js');
|
||||||
var server = createServer(() => {
|
var server = createServer(() => {
|
||||||
console.log("Server started.");
|
logger.info("Server started on port " + config.port + ".");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
var MysqlInterface = require('sync-mysql');
|
var MysqlInterface = require('sync-mysql');
|
||||||
|
var config = require('../config.js');
|
||||||
|
const logger = require('../utils/logger.js');
|
||||||
|
|
||||||
class Mysql {
|
class Mysql {
|
||||||
constructor(config) {
|
constructor(msConfig) {
|
||||||
this.connection = new MysqlInterface(config);
|
this.connection = new MysqlInterface(msConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
exec(query) {
|
exec(query) {
|
||||||
@@ -10,7 +12,7 @@ class Mysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prepare (type, query, params) {
|
prepare (type, query, params) {
|
||||||
(config.mode === "development") && console.log("prepare (mysql): type: " + type + ", query: " + query + ", params: " + params);
|
logger.debug("prepare (mysql): type: " + type + ", query: " + query + ", params: " + params);
|
||||||
if (type === 'get') {
|
if (type === 'get') {
|
||||||
return this.connection.query(query, params)[0];
|
return this.connection.query(query, params)[0];
|
||||||
} else if (type === 'run') {
|
} else if (type === 'run') {
|
||||||
@@ -18,7 +20,7 @@ class Mysql {
|
|||||||
} else if (type === 'all') {
|
} else if (type === 'all') {
|
||||||
return this.connection.query(query, params);
|
return this.connection.query(query, params);
|
||||||
} else {
|
} else {
|
||||||
console.log('returning undefined...')
|
logger.warn('returning undefined...');
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
const { db } = require("./databases");
|
const { db } = require("./databases");
|
||||||
|
var config = require('../config.js');
|
||||||
|
const logger = require('../utils/logger.js');
|
||||||
|
|
||||||
class Sqlite {
|
class Sqlite {
|
||||||
constructor(connection) {
|
constructor(connection) {
|
||||||
@@ -17,8 +19,8 @@ class Sqlite {
|
|||||||
} else if (type === 'all') {
|
} else if (type === 'all') {
|
||||||
return this.connection.prepare(query).all(...params);
|
return this.connection.prepare(query).all(...params);
|
||||||
} else {
|
} else {
|
||||||
(config.mode === "development") && console.log('returning undefined...')
|
logger.debug('sqlite query: returning undefined')
|
||||||
(config.mode === "development") && console.log("prepare: type: " + type + ", query: " + query + ", params: " + params);
|
logger.debug("prepare: type: " + type + ", query: " + query + ", params: " + params);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
var fs = require('fs');
|
const log = require('../utils/logger.js'); // log not logger to not interfere with function name
|
||||||
var config = require('../config.js');
|
|
||||||
|
|
||||||
module.exports = function logger (req, res, next) {
|
module.exports = function logger (req, res, next) {
|
||||||
(config.mode === "development") && console.log('Request recieved: ' + req.url);
|
log.info("Request recieved: " + req.method + " " + req.url);
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ var databases = require('../databases/databases.js');
|
|||||||
var db = databases.db;
|
var db = databases.db;
|
||||||
var privateDB = databases.privateDB;
|
var privateDB = databases.privateDB;
|
||||||
|
|
||||||
|
var logger = require('../utils/logger.js');
|
||||||
var getHash = require('../utils/getHash.js');
|
var getHash = require('../utils/getHash.js');
|
||||||
var getIP = require('../utils/getIP.js');
|
var getIP = require('../utils/getIP.js');
|
||||||
|
|
||||||
@@ -166,7 +167,7 @@ function handleGetSegments(req, res) {
|
|||||||
|
|
||||||
return segments;
|
return segments;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var db = require('../databases/databases.js').db;
|
var db = require('../databases/databases.js').db;
|
||||||
|
|
||||||
var getHash = require('../utils/getHash.js');
|
var getHash = require('../utils/getHash.js');
|
||||||
|
const logger = require('../utils/logger.js');
|
||||||
|
|
||||||
module.exports = function getUsername (req, res) {
|
module.exports = function getUsername (req, res) {
|
||||||
let userID = req.query.userID;
|
let userID = req.query.userID;
|
||||||
@@ -28,7 +29,7 @@ module.exports = function getUsername (req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
logger.error(err);
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
var db = require('../databases/databases.js').db;
|
var db = require('../databases/databases.js').db;
|
||||||
var getHash = require('../utils/getHash.js');
|
var getHash = require('../utils/getHash.js');
|
||||||
|
var logger = require('../utils/logger.js');
|
||||||
module.exports = function getViewsForUser(req, res) {
|
module.exports = function getViewsForUser(req, res) {
|
||||||
let userID = req.query.userID;
|
let userID = req.query.userID;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ module.exports = function getViewsForUser(req, res) {
|
|||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
logger.error(err);
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
var config = require('../config.js');
|
|
||||||
|
|
||||||
var postSkipSegments = require('./postSkipSegments.js');
|
var postSkipSegments = require('./postSkipSegments.js');
|
||||||
|
|
||||||
module.exports = async function submitSponsorTimes(req, res) {
|
module.exports = async function submitSponsorTimes(req, res) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ var databases = require('../databases/databases.js');
|
|||||||
var db = databases.db;
|
var db = databases.db;
|
||||||
var privateDB = databases.privateDB;
|
var privateDB = databases.privateDB;
|
||||||
var YouTubeAPI = require('../utils/youtubeAPI.js');
|
var YouTubeAPI = require('../utils/youtubeAPI.js');
|
||||||
|
var logger = require('../utils/logger.js');
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
var isoDurations = require('iso8601-duration');
|
var isoDurations = require('iso8601-duration');
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ function sendDiscordNotification(userID, videoID, UUID, segmentInfo) {
|
|||||||
id: videoID
|
id: videoID
|
||||||
}, function (err, data) {
|
}, function (err, data) {
|
||||||
if (err || data.items.length === 0) {
|
if (err || data.items.length === 0) {
|
||||||
err && console.log(err);
|
err && logger.error(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,13 +53,13 @@ function sendDiscordNotification(userID, videoID, UUID, segmentInfo) {
|
|||||||
}
|
}
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log("Failed to send first time submission Discord hook.");
|
logger.error("Failed to send first time submission Discord hook.");
|
||||||
console.log(JSON.stringify(err));
|
logger.error(JSON.stringify(err));
|
||||||
console.log("\n");
|
logger.error("\n");
|
||||||
} else if (res && res.statusCode >= 400) {
|
} else if (res && res.statusCode >= 400) {
|
||||||
console.log("Error sending first time submission Discord hook");
|
logger.error("Error sending first time submission Discord hook");
|
||||||
console.log(JSON.stringify(res));
|
logger.error(JSON.stringify(res));
|
||||||
console.log("\n");
|
logger.error("\n");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -69,9 +70,13 @@ function sendDiscordNotification(userID, videoID, UUID, segmentInfo) {
|
|||||||
// submission: {videoID, startTime, endTime}
|
// submission: {videoID, startTime, endTime}
|
||||||
// callback: function(reject: "String containing reason the submission was rejected")
|
// callback: function(reject: "String containing reason the submission was rejected")
|
||||||
// returns: string when an error, false otherwise
|
// returns: string when an error, false otherwise
|
||||||
|
|
||||||
|
// Looks like this was broken for no defined youtube key - fixed but IMO we shouldn't return
|
||||||
|
// false for a pass - it was confusing and lead to this bug - any use of this function in
|
||||||
|
// the future could have the same problem.
|
||||||
async function autoModerateSubmission(submission, callback) {
|
async function autoModerateSubmission(submission, callback) {
|
||||||
// Get the video information from the youtube API
|
// Get the video information from the youtube API
|
||||||
if (config.youtubeAPI !== null) {
|
if (config.youtubeAPIKey !== null) {
|
||||||
let {err, data} = await new Promise((resolve, reject) => {
|
let {err, data} = await new Promise((resolve, reject) => {
|
||||||
YouTubeAPI.videos.list({
|
YouTubeAPI.videos.list({
|
||||||
part: "contentDetails",
|
part: "contentDetails",
|
||||||
@@ -101,15 +106,31 @@ async function autoModerateSubmission(submission, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Skipped YouTube API");
|
logger.debug("Skipped YouTube API");
|
||||||
|
|
||||||
// Can't moderate the submission without calling the youtube API
|
// Can't moderate the submission without calling the youtube API
|
||||||
// so allow by default.
|
// so allow by default.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function proxySubmission(req) {
|
||||||
|
request.post(config.proxySubmission + '/api/skipSegments?userID='+req.query.userID+'&videoID='+req.query.videoID, {json: req.body}, (err, result) => {
|
||||||
|
if (config.mode === 'development') {
|
||||||
|
if (!err) {
|
||||||
|
logger.error('Proxy Submission: ' + result.statusCode + ' ('+result.body+')');
|
||||||
|
} else {
|
||||||
|
logger.debug("Proxy Submission: Failed to make call");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = async function postSkipSegments(req, res) {
|
module.exports = async function postSkipSegments(req, res) {
|
||||||
|
if (config.proxySubmission) {
|
||||||
|
proxySubmission(req);
|
||||||
|
}
|
||||||
|
|
||||||
let videoID = req.query.videoID || req.body.videoID;
|
let videoID = req.query.videoID || req.body.videoID;
|
||||||
let userID = req.query.userID || req.body.userID;
|
let userID = req.query.userID || req.body.userID;
|
||||||
|
|
||||||
@@ -148,7 +169,7 @@ module.exports = async function postSkipSegments(req, res) {
|
|||||||
let endTime = parseFloat(segments[i].segment[1]);
|
let endTime = parseFloat(segments[i].segment[1]);
|
||||||
|
|
||||||
if (isNaN(startTime) || isNaN(endTime)
|
if (isNaN(startTime) || isNaN(endTime)
|
||||||
|| startTime === Infinity || endTime === Infinity || startTime > endTime) {
|
|| startTime === Infinity || endTime === Infinity || startTime < 0 || startTime >= endTime) {
|
||||||
//invalid request
|
//invalid request
|
||||||
res.sendStatus(400);
|
res.sendStatus(400);
|
||||||
return;
|
return;
|
||||||
@@ -244,7 +265,7 @@ module.exports = async function postSkipSegments(req, res) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
//a DB change probably occurred
|
//a DB change probably occurred
|
||||||
res.sendStatus(502);
|
res.sendStatus(502);
|
||||||
console.log("Error when putting sponsorTime in the DB: " + videoID + ", " + segmentInfo.segment[0] + ", " +
|
logger.error("Error when putting sponsorTime in the DB: " + videoID + ", " + segmentInfo.segment[0] + ", " +
|
||||||
segmentInfo.segment[1] + ", " + userID + ", " + segmentInfo.category + ". " + err);
|
segmentInfo.segment[1] + ", " + userID + ", " + segmentInfo.category + ". " + err);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -254,7 +275,7 @@ module.exports = async function postSkipSegments(req, res) {
|
|||||||
sendDiscordNotification(userID, videoID, UUID, segmentInfo);
|
sendDiscordNotification(userID, videoID, UUID, segmentInfo);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
logger.error(err);
|
||||||
|
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ var config = require('../config.js');
|
|||||||
|
|
||||||
var db = require('../databases/databases.js').db;
|
var db = require('../databases/databases.js').db;
|
||||||
var getHash = require('../utils/getHash.js');
|
var getHash = require('../utils/getHash.js');
|
||||||
|
const logger = require('../utils/logger.js');
|
||||||
|
|
||||||
|
|
||||||
module.exports = function setUsername(req, res) {
|
module.exports = function setUsername(req, res) {
|
||||||
@@ -45,7 +46,7 @@ module.exports = function setUsername(req, res) {
|
|||||||
|
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
logger.error(err);
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -11,6 +11,19 @@ var db = databases.db;
|
|||||||
var privateDB = databases.privateDB;
|
var privateDB = databases.privateDB;
|
||||||
var YouTubeAPI = require('../utils/youtubeAPI.js');
|
var YouTubeAPI = require('../utils/youtubeAPI.js');
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
|
const logger = require('../utils/logger.js');
|
||||||
|
|
||||||
|
function getVoteAuthor(submissionCount, isVIP, isOwnSubmission) {
|
||||||
|
if (submissionCount === 0) {
|
||||||
|
return "Report by New User";
|
||||||
|
} else if (isVIP) {
|
||||||
|
return "Report by VIP User";
|
||||||
|
} else if (isOwnSubmission) {
|
||||||
|
return "Report by Submitter";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
function categoryVote(UUID, userID, isVIP, category, hashedIP, res) {
|
function categoryVote(UUID, userID, isVIP, category, hashedIP, res) {
|
||||||
// Check if they've already made a vote
|
// Check if they've already made a vote
|
||||||
@@ -96,6 +109,9 @@ async function voteOnSponsorTime(req, res) {
|
|||||||
//check if this user is on the vip list
|
//check if this user is on the vip list
|
||||||
let isVIP = db.prepare('get', "SELECT count(*) as userCount FROM vipUsers WHERE userID = ?", [nonAnonUserID]).userCount > 0;
|
let isVIP = db.prepare('get', "SELECT count(*) as userCount FROM vipUsers WHERE userID = ?", [nonAnonUserID]).userCount > 0;
|
||||||
|
|
||||||
|
//check if user voting on own submission
|
||||||
|
let isOwnSubmission = db.prepare("get", "SELECT UUID as submissionCount FROM sponsorTimes where userID = ? AND UUID = ?", [nonAnonUserID, UUID]) !== undefined;
|
||||||
|
|
||||||
if (type === undefined && category !== undefined) {
|
if (type === undefined && category !== undefined) {
|
||||||
return categoryVote(UUID, userID, isVIP, category, hashedIP, res);
|
return categoryVote(UUID, userID, isVIP, category, hashedIP, res);
|
||||||
}
|
}
|
||||||
@@ -165,19 +181,20 @@ async function voteOnSponsorTime(req, res) {
|
|||||||
let row = db.prepare('get', "SELECT votes, views FROM sponsorTimes WHERE UUID = ?", [UUID]);
|
let row = db.prepare('get', "SELECT votes, views FROM sponsorTimes WHERE UUID = ?", [UUID]);
|
||||||
|
|
||||||
if (voteTypeEnum === voteTypes.normal) {
|
if (voteTypeEnum === voteTypes.normal) {
|
||||||
if (isVIP && incrementAmount < 0) {
|
if ((isVIP || isOwnSubmission) && incrementAmount < 0) {
|
||||||
//this user is a vip and a downvote
|
//this user is a vip and a downvote
|
||||||
incrementAmount = - (row.votes + 2 - oldIncrementAmount);
|
incrementAmount = - (row.votes + 2 - oldIncrementAmount);
|
||||||
type = incrementAmount;
|
type = incrementAmount;
|
||||||
}
|
}
|
||||||
} else if (voteTypeEnum == voteTypes.incorrect) {
|
} else if (voteTypeEnum == voteTypes.incorrect) {
|
||||||
if (isVIP) {
|
if (isVIP || isOwnSubmission) {
|
||||||
//this user is a vip and a downvote
|
//this user is a vip and a downvote
|
||||||
incrementAmount = 500 * incrementAmount;
|
incrementAmount = 500 * incrementAmount;
|
||||||
type = incrementAmount < 0 ? 12 : 13;
|
type = incrementAmount < 0 ? 12 : 13;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// Get video ID
|
// Get video ID
|
||||||
let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " +
|
let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " +
|
||||||
"(select count(1) from sponsorTimes where userID = s.userID) count, " +
|
"(select count(1) from sponsorTimes where userID = s.userID) count, " +
|
||||||
@@ -255,6 +272,37 @@ async function voteOnSponsorTime(req, res) {
|
|||||||
}
|
}
|
||||||
// Send discord message
|
// Send discord message
|
||||||
if (webhookURL !== null && !isUpvote) {
|
if (webhookURL !== null && !isUpvote) {
|
||||||
|
=======
|
||||||
|
// Send discord message
|
||||||
|
if (incrementAmount < 0) {
|
||||||
|
// Get video ID
|
||||||
|
let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " +
|
||||||
|
"(select count(1) from sponsorTimes where userID = s.userID) count, " +
|
||||||
|
"(select count(1) from sponsorTimes where userID = s.userID and votes <= -2) disregarded " +
|
||||||
|
"FROM sponsorTimes s left join userNames u on s.userID = u.userID where s.UUID=?",
|
||||||
|
[UUID]);
|
||||||
|
|
||||||
|
let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [nonAnonUserID]);
|
||||||
|
|
||||||
|
if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) {
|
||||||
|
let webhookURL = null;
|
||||||
|
if (voteTypeEnum === voteTypes.normal) {
|
||||||
|
webhookURL = config.discordReportChannelWebhookURL;
|
||||||
|
} else if (voteTypeEnum === voteTypes.incorrect) {
|
||||||
|
webhookURL = config.discordCompletelyIncorrectReportWebhookURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.youtubeAPIKey !== null && webhookURL !== null) {
|
||||||
|
YouTubeAPI.videos.list({
|
||||||
|
part: "snippet",
|
||||||
|
id: submissionInfoRow.videoID
|
||||||
|
}, function (err, data) {
|
||||||
|
if (err || data.items.length === 0) {
|
||||||
|
err && logger.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
>>>>>>> origin/master
|
||||||
request.post(webhookURL, {
|
request.post(webhookURL, {
|
||||||
json: {
|
json: {
|
||||||
"embeds": [{
|
"embeds": [{
|
||||||
@@ -271,7 +319,7 @@ async function voteOnSponsorTime(req, res) {
|
|||||||
getFormattedTime(submissionInfoRow.startTime) + " to " + getFormattedTime(submissionInfoRow.endTime),
|
getFormattedTime(submissionInfoRow.startTime) + " to " + getFormattedTime(submissionInfoRow.endTime),
|
||||||
"color": 10813440,
|
"color": 10813440,
|
||||||
"author": {
|
"author": {
|
||||||
"name": userSubmissionCountRow.submissionCount === 0 ? "Report by New User" : (isVIP ? "Report by VIP User" : "")
|
"name": getVoteAuthor(userSubmissionCountRow.submissionCount, isVIP, isOwnSubmission)
|
||||||
},
|
},
|
||||||
"thumbnail": {
|
"thumbnail": {
|
||||||
"url": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "",
|
"url": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "",
|
||||||
@@ -280,13 +328,13 @@ async function voteOnSponsorTime(req, res) {
|
|||||||
}
|
}
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log("Failed to send reported submission Discord hook.");
|
logger.error("Failed to send reported submission Discord hook.");
|
||||||
console.log(JSON.stringify(err));
|
logger.error(JSON.stringify(err));
|
||||||
console.log("\n");
|
logger.error("\n");
|
||||||
} else if (res && res.statusCode >= 400) {
|
} else if (res && res.statusCode >= 400) {
|
||||||
console.log("Error sending reported submission Discord hook");
|
logger.error("Error sending reported submission Discord hook");
|
||||||
console.log(JSON.stringify(res));
|
logger.error(JSON.stringify(res));
|
||||||
console.log("\n");
|
logger.error("\n");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -348,7 +396,7 @@ async function voteOnSponsorTime(req, res) {
|
|||||||
|
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
logger.error(err);
|
||||||
|
|
||||||
res.status(500).json({error: 'Internal error creating segment vote'});
|
res.status(500).json({error: 'Internal error creating segment vote'});
|
||||||
}
|
}
|
||||||
@@ -359,4 +407,4 @@ module.exports = {
|
|||||||
endpoint: function (req, res) {
|
endpoint: function (req, res) {
|
||||||
voteOnSponsorTime(req, res);
|
voteOnSponsorTime(req, res);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
68
src/utils/logger.js
Normal file
68
src/utils/logger.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
const config = require('../config.js');
|
||||||
|
|
||||||
|
const levels = {
|
||||||
|
ERROR: "ERROR",
|
||||||
|
WARN: "WARN",
|
||||||
|
INFO: "INFO",
|
||||||
|
DEBUG: "DEBUG"
|
||||||
|
};
|
||||||
|
|
||||||
|
const colors = {
|
||||||
|
Reset: "\x1b[0m",
|
||||||
|
Bright: "\x1b[1m",
|
||||||
|
Dim: "\x1b[2m",
|
||||||
|
Underscore: "\x1b[4m",
|
||||||
|
Blink: "\x1b[5m",
|
||||||
|
Reverse: "\x1b[7m",
|
||||||
|
Hidden: "\x1b[8m",
|
||||||
|
|
||||||
|
FgBlack: "\x1b[30m",
|
||||||
|
FgRed: "\x1b[31m",
|
||||||
|
FgGreen: "\x1b[32m",
|
||||||
|
FgYellow: "\x1b[33m",
|
||||||
|
FgBlue: "\x1b[34m",
|
||||||
|
FgMagenta: "\x1b[35m",
|
||||||
|
FgCyan: "\x1b[36m",
|
||||||
|
FgWhite: "\x1b[37m",
|
||||||
|
|
||||||
|
BgBlack: "\x1b[40m",
|
||||||
|
BgRed: "\x1b[41m",
|
||||||
|
BgGreen: "\x1b[42m",
|
||||||
|
BgYellow: "\x1b[43m",
|
||||||
|
BgBlue: "\x1b[44m",
|
||||||
|
BgMagenta: "\x1b[45m",
|
||||||
|
BgCyan: "\x1b[46m",
|
||||||
|
BgWhite: "\x1b[47m",
|
||||||
|
}
|
||||||
|
|
||||||
|
const settings = {
|
||||||
|
ERROR: true,
|
||||||
|
WARN: true,
|
||||||
|
INFO: false,
|
||||||
|
DEBUG: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (config.mode === 'development') {
|
||||||
|
settings.INFO = true;
|
||||||
|
settings.DEBUG = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(level, string) {
|
||||||
|
if (!!settings[level]) {
|
||||||
|
let color = colors.Bright;
|
||||||
|
if (level === levels.ERROR) color = colors.FgRed;
|
||||||
|
if (level === levels.WARN) color = colors.FgYellow;
|
||||||
|
|
||||||
|
if (level.length === 4) {level = level + " "}; // ensure logs are aligned
|
||||||
|
console.log(colors.Dim, level + " " + new Date().toISOString() + ": ", color, string, colors.Reset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
levels,
|
||||||
|
log,
|
||||||
|
error: (string) => {log(levels.ERROR, string)},
|
||||||
|
warn: (string) => {log(levels.WARN, string)},
|
||||||
|
info: (string) => {log(levels.INFO, string)},
|
||||||
|
debug: (string) => {log(levels.DEBUG, string)},
|
||||||
|
};
|
||||||
@@ -20,6 +20,8 @@ describe('voteOnSponsorTime', () => {
|
|||||||
db.exec(startOfQuery + "('voter-submitter2', 1, 11, 2, 'vote-uuid-9', '" + getHash("randomID2") + "', 0, 50, 'sponsor', 0)");
|
db.exec(startOfQuery + "('voter-submitter2', 1, 11, 2, 'vote-uuid-9', '" + getHash("randomID2") + "', 0, 50, 'sponsor', 0)");
|
||||||
db.exec(startOfQuery + "('voter-submitter2', 1, 11, 2, 'vote-uuid-10', '" + getHash("randomID3") + "', 0, 50, 'sponsor', 0)");
|
db.exec(startOfQuery + "('voter-submitter2', 1, 11, 2, 'vote-uuid-10', '" + getHash("randomID3") + "', 0, 50, 'sponsor', 0)");
|
||||||
db.exec(startOfQuery + "('voter-submitter2', 1, 11, 2, 'vote-uuid-11', '" + getHash("randomID4") + "', 0, 50, 'sponsor', 0)");
|
db.exec(startOfQuery + "('voter-submitter2', 1, 11, 2, 'vote-uuid-11', '" + getHash("randomID4") + "', 0, 50, 'sponsor', 0)");
|
||||||
|
db.exec(startOfQuery + "('own-submission-video', 1, 11, 500, 'own-submission-uuid', '"+ getHash('own-submission-id') +"', 0, 50, 'sponsor', 0)");
|
||||||
|
db.exec(startOfQuery + "('not-own-submission-video', 1, 11, 500, 'not-own-submission-uuid', '"+ getHash('somebody-else-id') +"', 0, 50, 'sponsor', 0)");
|
||||||
|
|
||||||
db.exec("INSERT INTO vipUsers (userID) VALUES ('" + getHash("VIPUser") + "')");
|
db.exec("INSERT INTO vipUsers (userID) VALUES ('" + getHash("VIPUser") + "')");
|
||||||
privateDB.exec("INSERT INTO shadowBannedUsers (userID) VALUES ('" + getHash("randomID4") + "')");
|
privateDB.exec("INSERT INTO shadowBannedUsers (userID) VALUES ('" + getHash("randomID4") + "')");
|
||||||
@@ -151,6 +153,42 @@ describe('voteOnSponsorTime', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to completely downvote your own segment', (done) => {
|
||||||
|
request.get(utils.getbaseURL()
|
||||||
|
+ "/api/voteOnSponsorTime?userID=own-submission-id&UUID=own-submission-uuid&type=0", null,
|
||||||
|
(err, res, body) => {
|
||||||
|
if (err) done(err);
|
||||||
|
else if (res.statusCode === 200) {
|
||||||
|
let row = db.prepare('get', "SELECT votes FROM sponsorTimes WHERE UUID = ?", ["own-submission-uuid"]);
|
||||||
|
if (row.votes <= -2) {
|
||||||
|
done()
|
||||||
|
} else {
|
||||||
|
done("Vote did not succeed. Submission went from 500 votes to " + row.votes);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
done("Status code was " + res.statusCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be able to completely downvote somebody elses segment', (done) => {
|
||||||
|
request.get(utils.getbaseURL()
|
||||||
|
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=not-own-submission-uuid&type=0", null,
|
||||||
|
(err, res, body) => {
|
||||||
|
if (err) done(err);
|
||||||
|
else if (res.statusCode === 200) {
|
||||||
|
let row = db.prepare('get', "SELECT votes FROM sponsorTimes WHERE UUID = ?", ["not-own-submission-uuid"]);
|
||||||
|
if (row.votes === 499) {
|
||||||
|
done()
|
||||||
|
} else {
|
||||||
|
done("Vote did not succeed. Submission went from 500 votes to " + row.votes);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
done("Status code was " + res.statusCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Should be able to vote for a category and it should immediately change (for now)', (done) => {
|
it('Should be able to vote for a category and it should immediately change (for now)', (done) => {
|
||||||
request.get(utils.getbaseURL()
|
request.get(utils.getbaseURL()
|
||||||
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-4&category=intro", null,
|
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-4&category=intro", null,
|
||||||
|
|||||||
Reference in New Issue
Block a user