A suite to track Project Diva score statistics and ratings / D4DJ event data.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
projectdivar/server/app.js

3016 lines
89 KiB

const express = require("express");
const axios = require("axios");
const twitchStreams = require("twitch-get-stream");
const app = express();
//add spaces here to force an update
const port = 4501;
const { json, urlencoded } = require("body-parser");
const Pool = require("pg").Pool;
app.use(json());
app.use(
urlencoded({
extended: true,
})
);
const nodemailer = require("nodemailer");
const fileUpload = require("express-fileupload");
const unzipper = require("unzipper");
const fs = require("fs");
const moment = require("moment");
const { exec, spawn } = require("child_process");
app.use(
fileUpload({
createParentPath: true,
limits: { fileSize: 15 * 1024 * 1024, files: 1 },
safeFileNames: true,
preserveExtension: true,
abortOnLimit: true,
uploadTimeout: 0,
})
);
const QuickChart = require("quickchart-js");
let allowCrossDomain = function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Allow-Methods", "*");
next();
};
app.use(allowCrossDomain);
const db = new Pool({
user: "postgres",
password: "",
host: "postgres",
database: "divar",
port: 5432,
});
const db2 = new Pool({
user: "postgres",
password: "",
host: "postgres",
database: "ngsplanner2",
port: 5432,
});
app.use((req, _, next) => {
req.db = db;
next()
})
exports.app = app;
require("./routes/d4dj-routes");
const ENDPOINTDATA = [
{
endpoint: "class",
requiredfields: ["name"],
optionalfields: ["icon"],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "class_level_data",
requiredfields: ["class_id", "level", "hp", "atk", "def", "name"],
optionalfields: [],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "class_weapon_type_data",
requiredfields: ["class_id", "weapon_type_id"],
optionalfields: [],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "weapon",
requiredfields: ["name", "rarity", "level_req", "atk"],
optionalfields: [
"potential_id",
"variance",
"base_affix_slots",
"drop_info",
"pb_gauge_build",
"icon",
],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "weapon_existence_data",
requiredfields: ["weapon_type_id", "weapon_id"],
optionalfields: ["popularity", "editors_choice"],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "weapon_type",
requiredfields: ["name", "dmg_type"],
optionalfields: ["icon"],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "armor",
requiredfields: ["name", "rarity", "level_req", "def"],
optionalfields: [
"hp",
"pp",
"mel_dmg",
"rng_dmg",
"tec_dmg",
"crit_rate",
"crit_dmg",
"pp_cost_reduction",
"active_pp_recovery",
"natural_pp_recovery",
"dmg_res",
"all_down_res",
"burn_res",
"freeze_res",
"blind_res",
"shock_res",
"panic_res",
"poison_res",
"battle_power_value",
"pb_gauge_build",
"icon",
"popularity",
"editors_choice",
],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "potential",
requiredfields: ["name"],
optionalfields: ["icon"],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "potential_data",
requiredfields: ["potential_id", "level", "name"],
optionalfields: [
"mel_dmg",
"rng_dmg",
"tec_dmg",
"crit_rate",
"crit_dmg",
"pp_cost_reduction",
"active_pp_recovery",
"natural_pp_recovery",
"dmg_res",
"all_down_res",
"burn_res",
"freeze_res",
"blind_res",
"shock_res",
"panic_res",
"poison_res",
"battle_power_value",
"pb_gauge_build",
],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "builds",
requiredfields: [
"users_id",
"creator",
"build_name",
"class1",
"created_on",
"last_modified",
"data",
],
optionalfields: ["class2", "likes", "editors_choice"],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "skill",
requiredfields: ["name", "skill_type_id"],
optionalfields: ["icon"],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "skill_type",
requiredfields: ["name"],
optionalfields: [],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "skill_data",
requiredfields: ["skill_id", "level", "name"],
optionalfields: [
"variance",
"mel_dmg",
"rng_dmg",
"tec_dmg",
"crit_rate",
"crit_dmg",
"pp_cost_reduction",
"active_pp_recovery",
"natural_pp_recovery",
"dmg_res",
"popularity",
"editors_choice",
],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "augment",
requiredfields: ["augment_type_id", "name"],
optionalfields: [
"variance",
"hp",
"pp",
"mel_dmg",
"rng_dmg",
"tec_dmg",
"crit_rate",
"crit_dmg",
"pp_cost_reduction",
"active_pp_recovery",
"natural_pp_recovery",
"dmg_res",
"affix_success_rate",
"all_down_res",
"burn_res",
"freeze_res",
"blind_res",
"shock_res",
"panic_res",
"poison_res",
"battle_power_value",
"pb_gauge_build",
"popularity",
"editors_choice",
],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "augment_type",
requiredfields: ["name"],
optionalfields: ["icon"],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "food",
requiredfields: ["name"],
optionalfields: [
"potency",
"pp",
"dmg_res",
"hp",
"pp_consumption",
"pp_recovery",
"weak_point_dmg",
"hp_recovery",
"popularity",
"editors_choice",
],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "food_mult",
requiredfields: ["amount"],
optionalfields: [
"potency",
"pp",
"dmg_res",
"hp",
"pp_consumption",
"pp_recovery",
"weak_point_dmg",
"hp_recovery",
],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "roles",
requiredfields: ["name"],
optionalfields: [],
excludedfields: [], //Fields to not output in GET.
},
{
endpoint: "users",
requiredfields: ["username", "email", "created_on", "roles_id"],
optionalfields: ["avatar", "editors_choice"],
excludedfields: ["password_hash"], //Fields to not output in GET.
},
{
endpoint: "database_audit",
requiredfields: [
"action",
"table_name",
"row_name",
"row_id",
"new_value",
"date",
"users_id",
],
optionalfields: ["old_value"],
excludedfields: [], //Fields to not output in GET.
},
];
function CreateDynamicEndpoints() {
ENDPOINTDATA.map((endpoint) => {
app.get("/ngsplanner/" + endpoint.endpoint, (req, res) => {
if (endpoint.requiredfields.includes("name")) {
db2
.query(
"select distinct on (name) name,* from " +
endpoint.endpoint +
" order by name,id desc"
)
.then((data) => {
res.status(200).json({ fields: data.fields, rows: data.rows });
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
db2
.query("select * from " + endpoint.endpoint + " order by id desc")
.then((data) => {
res.status(200).json({ fields: data.fields, rows: data.rows });
})
.catch((err) => {
res.status(500).send(err.message);
});
}
});
app.post("/ngsplanner/" + endpoint.endpoint, (req, res) => {
var allExist = true;
endpoint.requiredfields.forEach((field) => {
if (!(field in req.body)) {
allExist = false;
}
});
if (!allExist) {
res
.status(300)
.send(
"Required fields are: " +
endpoint.requiredfields
.filter((field) => !(field in req.body))
.join(",")
);
return;
}
var combinedfields = [
...endpoint.requiredfields,
...endpoint.optionalfields,
...endpoint.excludedfields,
];
//console.log(combinedfields)
var all_filled_fields = combinedfields.filter(
(field) => field in req.body
);
db2
.query(
"insert into " +
endpoint.endpoint +
"(" +
all_filled_fields.join(",") +
") values(" +
all_filled_fields.map((field, i) => "$" + (i + 1)).join(",") +
") returning *",
all_filled_fields.map((field) => req.body[field])
)
.then((data) => {
res.status(200).json(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.patch("/ngsplanner/" + endpoint.endpoint, (req, res) => {
if (req.body.id) {
var combinedfields = [
...endpoint.requiredfields,
...endpoint.optionalfields,
...endpoint.excludedfields,
];
//console.log(combinedfields)
var all_filled_fields = combinedfields.filter(
(field) => field in req.body
);
db2
.query(
"update " +
endpoint.endpoint +
" set " +
all_filled_fields
.map((field, i) => field + "=$" + (i + 1))
.join(",") +
" where id=$" +
(all_filled_fields.length + 1) +
" returning *",
[...all_filled_fields.map((field) => req.body[field]), req.body.id]
)
.then((data) => {
res.status(200).json(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(300).send("Invalid query!");
}
});
app.delete("/ngsplanner/" + endpoint.endpoint, (req, res) => {
if (req.body.id) {
db2
.query(
"delete from " + endpoint.endpoint + " where id=$1 returning *",
[req.body.id]
)
.then((data) => {
res.status(200).json(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(300).send("Invalid query!");
}
});
});
}
/*const db2 =
new Pool({
user: 'read_only_user',
password: 'divar1234',
host: 'postgres',
database: 'divar',
port: 5432,
})
app.get('/event/query',(req,res)=>{
if (req.query.query&&req.query.query.length>0) {
db2.query(req.query.query)
.then((data)=>{
res.status(200).json(data.rows)
})
.catch((err)=>{
res.status(500).json(err.message)
})
} else {
res.status(400).send("Empty query!")
}
})*/
app.get("/song/:songname", (req, res) => {
db.query(
"select * from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname],
(error, results) => {
if (error) {
res.status(500).json(error.message);
} else {
//console.log(req.params.songname+":"+JSON.stringify(results.rows));
res.status(200).json(results.rows);
}
}
);
});
app.get("/songs", (req, res) => {
db.query(
"select songs.*,songdata.rating as rating,songdata.difficulty,songdata.notecount from songs left join songdata on songs.id=songdata.songid",
(error, results) => {
if (error) {
res.status(500).json(error.message);
} else {
//console.log(req.params.songname+":"+JSON.stringify(results.rows));
//res.status(200).json(results.rows)
var data = {};
results.rows.forEach((song) => {
if (data[song.id]) {
if (typeof data[song.id].rating === "string") {
var oldRating = data[song.id].rating;
var oldNoteCount = data[song.id].notecount;
data[song.id].rating = {};
data[song.id].notecount = {};
data[song.id].rating[data[song.id].difficulty] = oldRating;
data[song.id].notecount[data[song.id].difficulty] = oldNoteCount;
}
data[song.id].rating[song.difficulty] = song.rating;
data[song.id].notecount[song.difficulty] = song.notecount;
} else {
data[song.id] = song;
if (data[song.id].rating === null) {
data[song.id].rating = {};
}
if (data[song.id].notecount === null) {
data[song.id].notecount = {};
}
}
});
res.status(200).json(data);
}
}
);
});
/*app.post('/register', (req, res) => {
if (req.body && req.body.username &&
req.body.username.length>2 && req.body.email) {
var duplicateFound=false;
db.query('select * from users where username=$1 limit 1',[req.body.username])
.then((data)=>{
if (data.rows.length>0) {
throw new Error("User "+data.rows[0].username+" already exists!");
} else {
return db.query('insert into users(username,email) values($1,$2) returning username,email',[req.body.username,req.body.email])
}
})
.then((data)=>{res.status(200).json(data.rows)})
.catch((err)=>{res.status(500).json(err.message)})
} else {
res.status(400).json("Invalid username!")
}
})*/
app.delete("/remove", (req, res) => {
if (
req.body &&
req.body.username !== undefined &&
req.body.authentication_token !== undefined &&
req.body.playid !== undefined
) {
var userObj = {},
songObj = {},
rating = 0,
isFirstClear = false;
db.query(
"select id,authentication_token,playcount,fccount,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear from users where username=$1 limit 1",
[req.body.username]
)
.then((data) => {
if (data && data.rows.length > 0) {
userObj = data.rows[0];
if (req.body.authentication_token === userObj.authentication_token) {
return db.query(
"delete from plays where id=$1 and userid=$2 returning *",
[req.body.playid, userObj.id]
);
} else {
throw new Error("Could not authenticate user!");
}
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
songObj = data.rows[0];
return CalculateRating(req.body.username);
} else {
throw new Error("Could not find play!");
}
})
.then((data) => {
rating = data;
return db.query(
"select * from plays where songid=$1 and userid=$2 and difficulty=$3 and score>0 limit 1",
[songObj.songid, userObj.id, songObj.difficulty]
);
})
.then((data) => {
if (data && data.rows.length === 0) {
isFirstClear = true;
}
/*console.log([data,userObj.playcount-1,(songObj.safe==0&&songObj.sad==0&&songObj.worst==0)?userObj.fccount-1:userObj.fccount,userObj.cool-songObj.cool,userObj.fine-songObj.fine,userObj.safe-songObj.safe,userObj.sad-songObj.sad,userObj.worst-songObj.worst,(songObj.difficulty=="E")?userObj.ecount-1:userObj.ecount,(songObj.difficulty=="N")?userObj.ncount-1:userObj.ncount,(songObj.difficulty=="H")?userObj.hcount-1:userObj.hcount,(songObj.difficulty=="EX")?userObj.excount-1:userObj.excount,(songObj.difficulty=="EXEX")?userObj.exexcount-1:userObj.exexcount]);*/ return db.query(
"update users set rating=$1,playcount=$2,fccount=$3,cool=$4,fine=$5,safe=$6,sad=$7,worst=$8,eclear=$9,nclear=$10,hclear=$11,exclear=$12,exexclear=$13 where id=$14 returning rating,playcount,fccount,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear",
[
rating,
userObj.playcount - 1,
songObj.safe == 0 && songObj.sad == 0 && songObj.worst == 0
? userObj.fccount - 1
: userObj.fccount,
userObj.cool - songObj.cool,
userObj.fine - songObj.fine,
userObj.safe - songObj.safe,
userObj.sad - songObj.sad,
userObj.worst - songObj.worst,
songObj.difficulty == "E" && isFirstClear
? userObj.eclear - 1
: userObj.eclear,
songObj.difficulty == "N" && isFirstClear
? userObj.nclear - 1
: userObj.nclear,
songObj.difficulty == "H" && isFirstClear
? userObj.hclear - 1
: userObj.hclear,
songObj.difficulty == "EX" && isFirstClear
? userObj.exclear - 1
: userObj.exclear,
songObj.difficulty == "EXEX" && isFirstClear
? userObj.exexclear - 1
: userObj.exexclear,
userObj.id,
]
);
})
.then((data) => {
if (data && data.rows.length > 0) {
res.status(200).json({ user: data.rows[0], song: songObj });
axios.post("http://projectdivar.com/updates/" + userObj.id, {
password: process.env.GMAIL,
type: "delete",
});
} else {
throw new Error(
"Could not update user information, but song is deleted!"
);
}
})
.catch((err) => {
res.status(500).json(err.message);
});
} else {
res.status(400).send("Missing required parameters!");
}
});
app.post("/upload", function (req, res) {
if (
!req.files ||
Object.keys(req.files).length === 0 ||
req.body.username === undefined ||
req.body.authentication_token === undefined
) {
res.status(400).send("No files were uploaded. Invalid parameters.");
return;
}
let file = req.files.file;
//console.log(file)
if (file.size > 15 * 1024 * 1024) {
res
.status(400)
.send(
"File is too large! Max is 15MB! Consider splitting your plays into chunks (Recommended 50 files per zip)."
);
return;
}
if (
file.mimetype !== "application/x-zip-compressed" &&
file.mimetype !== "image/jpeg" &&
file.mimetype !== "image/png" &&
file.mimetype !== "application/octet-stream"
) {
return;
}
var uploads = 0;
var userId = -1;
var fileLoc = "";
var count = 0;
db.query(
"select uploads,id from users where username=$1 and authentication_token=$2",
[req.body.username, req.body.authentication_token]
)
.then((data) => {
if (data.rows.length > 0) {
uploads = data.rows[0].uploads;
userId = data.rows[0].id;
fileLoc = "files/plays/" + userId + "/" + uploads;
return file.mv(fileLoc);
} else {
throw new Error(
"Could not find / authenticate user with name " +
req.body.username +
"!"
);
}
})
.then((data) => {
if (file.mimetype !== "application/x-zip-compressed") {
return db.query("update users set uploads=$1 where username=$2", [
Number(uploads) + 1,
req.body.username,
]);
} else {
//console.log(uploads)
uploads++;
//console.log(uploads)
return {};
}
})
.then((data) => {
if (file.mimetype !== "application/x-zip-compressed") {
if (req.body.playid !== undefined) {
//Add the url to that play.
return db.query("update plays set src=$1 where id=$2 and userid=$3", [
"http://projectdivar.com/" + fileLoc,
Number(req.body.playid),
userId,
]);
} else {
return axios.post("http://projectdivar.com/image", {
url: "http://projectdivar.com/" + fileLoc,
user: req.body.username,
auth: req.body.authentication_token,
});
}
} else {
//This is a zip file.
var promises = [];
promises.push(
new Promise((resolve) => {
var stream = fs.createReadStream(fileLoc);
stream
.pipe(unzipper.Parse())
.on("entry", function (entry) {
const fileName = entry.path;
const type = entry.type; // 'Directory' or 'File'
const size = entry.vars.uncompressedSize; // There is also compressedSize;
if (
type == "File" &&
(fileName.includes(".jpg") ||
fileName.includes(".jpeg") ||
fileName.includes(".png"))
) {
promises.push(
new Promise((resolve) => {
var file = "files/plays/" + userId + "/" + uploads++;
entry
.pipe(fs.createWriteStream(file))
.on("finish", () => {
/*console.log("Promise finished!");*/ count++;
resolve({ file: "http://projectdivar.com/" + file });
});
}).then((data) => {
return db.query(
"insert into uploadedplays values($1,$2,$3)",
[data.file, userId, new Date()]
);
})
);
} else {
entry.autodrain();
}
})
.on("finish", () => {
/*console.log("Read finished");*/ resolve();
});
})
);
setTimeout(() => console.dir(promises), 5000);
return Promise.all(promises);
}
})
.then((data) => {
if (file.mimetype !== "application/x-zip-compressed") {
res.status(200).send("Your play has been submitted! Thank you.");
} else {
//console.log(data)
//console.log(uploads))
fs.unlink(fileLoc, (err) => { });
return db.query("update users set uploads=$1 where username=$2", [
Number(uploads) + 1,
req.body.username,
]);
}
})
.then((data) => {
if (file.mimetype !== "application/x-zip-compressed") {
} else {
res
.status(200)
.send(
"Submitted " +
count +
" plays to the submission system. They will be processed shortly! Thank you."
);
}
})
.catch((err) => {
console.log(err.message);
res.status(500).send(err.message);
});
});
app.post("/submit", (req, res) => {
function addToQueue(src, userid, songid) {
if (src) {
db.query("select * from uploadedplays where filename=$1", [
req.body.src,
]).then((data) => {
if (data.rows.length > 0) {
if (data.rows[0].tries > -5) {
db.query(
"update uploadedplays set filename=$1,userid=$2,submissiondate=$3,id=$4,tries=$5 returning *",
[src, userid, moment(), songid, data.rows[0].tries * -1 + 1]
).then((data) => {
if (data.rows.length > 0) {
console.log(
"Added back to queue: " + JSON.stringify(data.rows[0])
);
}
});
}
}
});
}
}
if (
req.body &&
req.body.username !== undefined &&
req.body.authentication_token !== undefined &&
req.body.song !== undefined &&
req.body.difficulty !== undefined &&
req.body.cool !== undefined &&
req.body.fine !== undefined &&
req.body.safe !== undefined &&
req.body.sad !== undefined &&
req.body.worst !== undefined &&
req.body.fail !== undefined &&
req.body.percent !== undefined
) {
if (
req.body.cool == -1 ||
req.body.fine == -1 ||
req.body.safe == -1 ||
req.body.sad == -1 ||
req.body.worst == -1
) {
fs.writeFileSync("invalidSongs", JSON.stringify(req.body) + "\n", {
flag: "a",
});
res.status(400).json("Invalid note parameters!");
}
var fail = true;
if (req.body.fail !== undefined) {
fail = req.body.fail == "true";
//console.log("Fail is "+fail+" type:"+typeof(fail))
}
var submitDate = new Date();
if (req.body.submitDate !== undefined) {
submitDate = req.body.submitDate;
}
var playstyle = "",
songsubmitdata = {},
mod = "",
combo = -1,
gameScore = -1,
isFC = false,
songRating = -1,
userId = -1,
songId = -1,
playcount = -1,
fccount = -1,
cool = -1,
fine = -1,
safe = -1,
sad = -1,
worst = -1,
alreadyPassed = false,
eclear = -1,
nclear = -1,
hclear = -1,
exclear = -1,
exexclear = -1;
var songdata = {},
userObj = {};
if (req.body.mod !== undefined) {
mod = req.body.mod;
}
if (req.body.combo !== undefined) {
combo = req.body.combo;
}
if (req.body.gameScore !== undefined) {
gameScore = req.body.gameScore;
}
db.query(
"select id,authentication_token,playcount,fccount,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear,playstyle,megamix,futuretone from users where username=$1 limit 1",
[req.body.username]
)
.then((data) => {
if (data && data.rows.length > 0) {
if (
data.rows[0].authentication_token === req.body.authentication_token
) {
var obj = data.rows[0];
userObj = data.rows[0];
playstyle = data.rows[0].playstyle;
eclear = obj.eclear;
nclear = obj.nclear;
hclear = obj.hclear;
exclear = obj.exclear;
exexclear = obj.exexclear;
cool = data.rows[0].cool;
fine = data.rows[0].fine;
safe = data.rows[0].safe;
sad = data.rows[0].sad;
worst = data.rows[0].worst;
fccount = data.rows[0].fccount;
playcount = data.rows[0].playcount;
userId = data.rows[0].id;
return db.query(
"select id,mega39s,futuretone from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.body.song]
);
} else {
throw new Error("Could not authenticate!");
}
} else {
console.log(req.body);
throw new Error("Could not find user.");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
songId = data.rows[0].id;
songdata = data.rows[0];
if (
!(
req.body.difficulty === "H" ||
req.body.difficulty === "N" ||
req.body.difficulty === "E" ||
req.body.difficulty === "EX" ||
req.body.difficulty === "EXEX"
)
) {
throw new Error("Invalid difficulty!");
}
if (
req.body.cool == -1 ||
req.body.fine == -1 ||
req.body.safe == -1 ||
req.body.sad == -1 ||
req.body.worst == -1
) {
throw new Error("Invalid submission!");
}
return db.query(
"select rating from songdata where songid=$1 and difficulty=$2 limit 1",
[songId, req.body.difficulty]
);
} else {
throw new Error("Could not find song.");
}
})
.then((data) => {
songRating = data.rows[0].rating;
return db.query(
"select id from plays where userid=$1 and score>0 and difficulty=$2 and songid=$3 limit 1",
[userId, req.body.difficulty, songId]
);
})
.then((data) => {
if (data && data.rows.length > 0) {
alreadyPassed = true; /*console.log(data);*/
}
var score = CalculateSongScore({
rating: songRating,
cool: req.body.cool,
fine: req.body.fine,
safe: req.body.safe,
sad: req.body.sad,
worst: req.body.worst,
percent: req.body.percent,
difficulty: req.body.difficulty,
fail: fail,
});
return db.query(
"insert into plays(songId,userId,difficulty,cool,fine,safe,sad,worst,percent,date,score,fail,mod,combo,gamescore,src,playstyle) values($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17) returning *",
[
songId,
userId,
req.body.difficulty,
req.body.cool,
req.body.fine,
req.body.safe,
req.body.sad,
req.body.worst,
req.body.percent,
submitDate,
score,
fail,
mod,
combo,
gameScore,
req.body.src ? req.body.src : "",
playstyle ? playstyle : "",
]
);
})
.then((data) => {
if (data && data.rows.length > 0) {
songsubmitdata = data.rows[0];
//console.log(alreadyPassed+" / "+typeof(alreadyPassed))
if (alreadyPassed === false && songsubmitdata.score > 0) {
switch (req.body.difficulty) {
case "E":
{
eclear++;
}
break;
case "N":
{
nclear++;
}
break;
case "H":
{
hclear++;
}
break;
case "EX":
{
exclear++;
}
break;
case "EXEX":
{
exexclear++;
}
break;
}
}
isFC =
songsubmitdata.safe === 0 &&
songsubmitdata.sad === 0 &&
songsubmitdata.worst === 0;
return CalculateRating(req.body.username);
} else {
throw new Error("Could not submit song.");
}
})
.then((data) => {
return db.query(
"update users set rating=$1,last_played=$3,playcount=$4,fccount=$5,cool=$6,fine=$7,safe=$8,sad=$9,worst=$10,eclear=$11,nclear=$12,hclear=$13,exclear=$14,exexclear=$15,megamix=$16,futuretone=$17 where username=$2",
[
data,
req.body.username,
new Date(),
++playcount,
fccount + (isFC ? 1 : 0),
cool + Number(req.body.cool),
fine + Number(req.body.fine),
safe + Number(req.body.safe),
sad + Number(req.body.sad),
worst + Number(req.body.worst),
eclear,
nclear,
hclear,
exclear,
exexclear,
songdata.mega39s || userObj.megamix,
(songdata.futuretone && !songdata.mega39s) || userObj.futuretone,
]
);
})
.then((data) => {
return songsubmitdata;
})
.then((data) => {
//userId
//password, type
axios.post("http://projectdivar.com/updates/" + userId, {
password: process.env.GMAIL,
type: "submit",
});
if (req.body.src) {
db.query("delete from uploadedplays where filename=$1", [
req.body.src,
]);
}
res.status(200).json(data);
})
.catch((err) => {
//console.log(req.body);
console.log(err);
addToQueue(req.body.src, userId, songId);
res.status(500).send(err.message);
});
} else {
console.log(req.body);
res.status(400).send("Missing required parameters!");
}
});
CalculateSongScore = (song) => {
if (song.fail == true) {
return 0;
}
var noteCount =
Number(song.cool) +
Number(song.fine) +
Number(song.safe) +
Number(song.sad) +
Number(song.worst);
var comboBreaks = Number(song.safe) + Number(song.sad) + Number(song.worst);
/*console.log("Combo Breaks: "+comboBreaks)
console.log("Is FC? "+(comboBreaks===0))
console.log("Is PFC? "+(song.fine===0&&song.safe===0&&song.sad===0&&song.worst===0))*/
var scoreMult = 1;
var percentMult = 1;
if (song.percent > 110) {
song.percent = 100;
}
if (
song.fine === 0 &&
song.safe === 0 &&
song.sad === 0 &&
song.worst === 0
) {
scoreMult = 2.4;
} else if (comboBreaks === 0) {
scoreMult = 1.4;
} else {
scoreMult = 1;
}
switch (song.difficulty) {
case "E":
{
if (song.percent < 30) {
percentMult = 0;
} else {
percentMult = 1 + Math.pow(1.0 * ((song.percent - 30) / 70.0), 3);
}
}
break;
case "N":
{
if (song.percent < 50) {
percentMult = 0;
} else {
percentMult = 1 + Math.pow(1.0 * ((song.percent - 50) / 50.0), 3);
}
}
break;
case "H":
{
if (song.percent < 60) {
percentMult = 0;
} else {
percentMult = 1 + Math.pow(1.0 * ((song.percent - 60) / 40.0), 3);
}
}
break;
case "EX":
case "EXEX":
{
if (song.percent < 70) {
percentMult = 0;
} else {
percentMult = 1 + Math.pow(1.0 * ((song.percent - 70) / 30.0), 3);
}
}
break;
default: {
if (song.percent < 60) {
percentMult = 0;
} else {
percentMult = 1 + Math.pow(1.0 * ((song.percent - 60) / 40.0), 3);
}
}
}
/*console.log("Score mult: "+scoreMult)
console.log("Percent mult: "+percentMult)*/
var score =
((song.cool * 100 + song.fine * 50 + song.safe * 10 + song.sad * 5) /
1000.0) *
percentMult *
scoreMult;
if (scoreMult > 0 && percentMult > 0) {
score += Math.pow(song.rating, 3) / 5;
}
return Number(score);
};
CalculateAccuracy = (cool, fine, safe, sad, worst) => {
var noteCount = cool + fine + safe + sad + worst;
var sum = cool + fine * 0.5 + safe * 0.1 + sad * 0.05;
return sum / noteCount;
};
CalculateRating = (username) => {
var songs = [];
var debugScoreList = "";
var userId = -1;
/* //Old rating algorithm.
return db.query('select id from users where username=$1',[username])
.then((data)=>{if(data.rows.length>0){userId=data.rows[0].id;return db.query('select * from plays where userid=$1 order by score desc limit 100',[userId])}else{return 0}})
.then((data)=>{if(data.rows.length>0){return data.rows.reduce((sum,song,i)=>{
return sum+Number(CalculateSongScore(song)*(Math.pow(0.8,i)))},0)}else{return 0}})
.catch((err)=>{throw new Error(err.message)})*/
return db
.query("select id from users where username=$1 limit 1", [username])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query("select * from songs order by id asc");
} else {
return 0;
}
})
.then((data) => {
if (data.rows.length > 0) {
songs = data.rows;
return Promise.all(
data.rows.map((song) => {
return db
.query(
"select * from plays where userId=$1 and songId=$2 and score!=$3 order by score desc limit 100",
[userId, song.id, "NaN"]
)
.then((data) => {
if (data.rows.length > 0) {
debugScoreList += song.name + "\n";
songs[song.id - 1].score = data.rows.reduce(
(sum, play, i) => {
debugScoreList +=
" " +
play.score +
" -> " +
play.score * Math.pow(0.2, i) +
"";
if (
i === 0 &&
play.fine + play.safe + play.sad + play.worst === 0
) {
songs[play.songid - 1].pfc = true;
debugScoreList += "+";
} else if (
i === 0 &&
play.safe + play.sad + play.worst === 0
) {
songs[play.songid - 1].fc = true;
debugScoreList += "*";
}
debugScoreList += "\n";
/*console.log("Play score:"+play.score+". Sum:"+sum);*/ return (
sum + play.score * Math.pow(0.2, i)
);
},
0
);
debugScoreList += " " + songs[song.id - 1].score + "\n";
}
});
})
);
}
})
.then(() => {
return songs
.sort((a, b) => {
var scorea = a.score ? a.score : 0;
var scoreb = b.score ? b.score : 0;
return scorea > scoreb ? -1 : 1;
})
.reduce((sum, song, i) => {
if (song.score && !isNaN(song.score)) {
debugScoreList +=
song.name +
": " +
song.score +
" -> " +
song.score * Math.pow(0.9, i) +
(song.pfc ? "+" + 2 : song.fc ? "+" + 1 : 0) +
"\n";
return (
sum +
song.score * Math.pow(0.9, i) +
(song.pfc ? 2 : song.fc ? +1 : 0)
);
} else {
return sum;
}
}, 0);
})
.then((data) => {
/*console.log(debugScoreList);*/ return data;
});
};
app.get("/songdiffs", (req, res) => {
var diffObj = {};
db.query("select COUNT(*) from songdata where difficulty='E'")
.then((data) => {
diffObj.E = data.rows[0].count;
return db.query("select COUNT(*) from songdata where difficulty='N'");
})
.then((data) => {
diffObj.N = data.rows[0].count;
return db.query("select COUNT(*) from songdata where difficulty='H'");
})
.then((data) => {
diffObj.H = data.rows[0].count;
return db.query("select COUNT(*) from songdata where difficulty='EX'");
})
.then((data) => {
diffObj.EX = data.rows[0].count;
return db.query("select COUNT(*) from songdata where difficulty='EXEX'");
})
.then((data) => {
diffObj.EXEX = data.rows[0].count;
res.status(200).json(diffObj);
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/accuracy/:username", (req, res) => {
db.query("select cool,fine,safe,sad,worst from users where username=$1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
return CalculateAccuracy(
data.rows[0].cool,
data.rows[0].fine,
data.rows[0].safe,
data.rows[0].sad,
data.rows[0].worst
);
} else {
throw new Error("User does not exist!");
}
})
.then((data) => {
res.status(200).json({ accuracy: data });
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/updates/:userid", (req, res) => {
db.query("select * from userupdate where userid=$1", [req.params.userid])
.then((data) => {
if (data.rows.length > 0) {
res.status(200).json(data.rows[0]);
} else {
res.status(400).send("No user update found!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.post("/updates/:userid", (req, res) => {
if (req.body && req.body.password && req.body.type) {
if (req.body.password === process.env.GMAIL) {
db.query(
"insert into userupdate(userid,update_type,date) values($1,$2,$3) on conflict(userid) do update set update_type=$2,date=$3 where userupdate.userid=$1 returning *",
[req.params.userid, req.body.type, moment()]
)
.then((data) => {
if (data.rows.length >= 0) {
res.status(200).send(data.rows[0]);
} else {
throw new Error("Could not update user.");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(403).send("Could not authenticate");
}
} else {
res.status(400).send("Invalid credentials!");
}
});
app.get("/recalculatescore/:playid", (req, res) => {
var userId = -1;
var username = null;
var songRating = -1;
var song;
db.query("select * from plays where id=$1 limit 1", [req.params.playid])
.then((data) => {
if (data.rows.length > 0) {
song = data.rows[0];
userId = song.userid; /*console.log(song);*/
return db.query(
"select rating from songdata where songid=$1 and difficulty=$2 limit 1",
[song.songid, song.difficulty]
);
} else {
throw new Error("This play does not exist!");
}
})
.then((data) => {
if (data.rows.length > 0) {
songRating = data.rows[0].rating;
var score = CalculateSongScore({
rating: songRating,
cool: song.cool,
fine: song.fine,
safe: song.safe,
sad: song.sad,
worst: song.worst,
percent: song.percent,
difficulty: song.difficulty,
fail: song.fail,
});
return db.query("update plays set score=$1 where id=$2 returning *", [
score,
req.params.playid,
]);
} else {
throw new Error("Failed to retrieve song data!");
}
})
.then((data) => {
//console.log(data);
if (data.rows.length > 0) {
var scoreData = data.rows[0];
return db
.query("select username from users where id=$1", [userId])
.then((data) => {
username = data.rows[0].username;
return CalculateRating(username);
})
.then((data) => {
db.query("update users set rating=$1 where username=$2", [
data,
username,
]);
})
.then(() => {
return scoreData;
})
.catch((err) => {
throw new Error("Could not update score");
});
} else {
throw new Error("Failed to update score!");
}
})
.then((data) => {
res.status(200).json(data);
axios.post("http://projectdivar.com/updates/" + userId, {
password: process.env.GMAIL,
type: "recalculate",
});
})
.catch((err) => {
console.log(err);
res.status(500).send(err.message);
});
});
/*
app.get('/playdata',(req,res)=>{
db.query('select * from plays')
.then((data)=>{res.status(200).json(data.rows)})
.catch((err)=>res.status(500).json(err.message))
})*/
app.post("/recalculatePlayerData/:id", (req, res) => {
if (req.body && req.body.password) {
if (req.body.password === process.env.GMAIL) {
db.query(
" select COUNT(*) as plays,SUM(cool) as coolsum,SUM(fine) as finesum,SUM(safe) as safesum,SUM(sad) as sadsum,SUM(worst) as worstsum,COUNT(*) filter(where safe=0 and sad=0 and worst=0) as fc from plays where userid=$1",
[req.params.id]
)
.then((data) => {
var d = data.rows[0];
return db.query(
"update users set playcount=$1,fccount=$2,cool=$3,fine=$4,safe=$5,sad=$6,worst=$7 where id=$8 returning playcount,fccount,cool,fine,safe,sad,worst,id",
[
d.plays,
d.fc,
d.coolsum !== null ? d.coolsum : 0,
d.finesum !== null ? d.finesum : 0,
d.safesum !== null ? d.safesum : 0,
d.sadsum !== null ? d.sadsum : 0,
d.worstsum !== null ? d.worstsum : 0,
req.params.id,
]
);
})
.then((data) => {
res.status(200).json(data.rows[0]);
});
}
}
});
app.get("/completionreport/:username", (req, res) => {
//Number of passes,plays,fcs,pfcs, and the best play.
var userId = -1,
songs,
promises = [];
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query("select * from songs order by id asc");
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
songs = data.rows;
songs.forEach((song) => {
promises.push(
db
.query(
"select * from (select userid,count(*) filter(where difficulty='E' and mod='SD' and score>0) as ESDCount,count(*) filter(where difficulty='N' and mod='SD' and score>0) as NSDCount,count(*) filter(where difficulty='H' and mod='SD' and score>0) as HSDCount,count(*) filter(where difficulty='EX' and mod='SD' and score>0) as EXSDCount,count(*) filter(where difficulty='EXEX' and mod='SD' and score>0) as EXEXSDCount,count(*) filter(where difficulty='E' and mod='HD' and score>0) as EHDCount,count(*) filter(where difficulty='N' and mod='HD' and score>0) as NHDCount,count(*) filter(where difficulty='H' and mod='HD' and score>0) as HHDCount,count(*) filter(where difficulty='EX' and mod='HD' and score>0) as EXHDCount,count(*) filter(where difficulty='EXEX' and mod='HD' and score>0) as EXEXHDCount,count(*) filter(where difficulty='E' and mod='HS' and score>0) as EHSCount,count(*) filter(where difficulty='N' and mod='HS' and score>0) as NHSCount,count(*) filter(where difficulty='H' and mod='HS' and score>0) as HHSCount,count(*) filter(where difficulty='EX' and mod='HS' and score>0) as EXHSCount,count(*) filter(where difficulty='EXEX' and mod='HS' and score>0) as EXEXHSCount,Count(*) filter(where difficulty='E' and score>0) as EClearCount,Count(*) filter(where difficulty='N' and score>0) as NClearCount,Count(*) filter(where difficulty='H' and score>0) as HClearCount,Count(*) filter(where difficulty='EX' and score>0) as EXClearCount,Count(*) filter(where difficulty='EXEX' and score>0) as EXEXClearCount,count(*) filter(where difficulty='E') as ECount,count(*) filter(where difficulty='N') as NCount,count(*) filter(where difficulty='H') as HCount,count(*) filter(where difficulty='EX') as EXCount,count(*) filter(where difficulty='EXEX') as EXEXCount,Count(*) filter(where safe=0 and sad=0 and worst=0 and difficulty='E') as EFCCount,Count(*) filter(where safe=0 and sad=0 and worst=0 and difficulty='N') as NFCCount,Count(*) filter(where safe=0 and sad=0 and worst=0 and difficulty='H') as HFCCount,Count(*) filter(where safe=0 and sad=0 and worst=0 and difficulty='EX') as EXFCCount,Count(*) filter(where safe=0 and sad=0 and worst=0 and difficulty='EXEX') as EXEXFCCount,Count(*) filter(where fine=0 and safe=0 and sad=0 and worst=0 and difficulty='E') as EPFCCount,Count(*) filter(where fine=0 and safe=0 and sad=0 and worst=0 and difficulty='N') as NPFCCount,Count(*) filter(where fine=0 and safe=0 and sad=0 and worst=0 and difficulty='H') as HPFCCount,Count(*) filter(where fine=0 and safe=0 and sad=0 and worst=0 and difficulty='EX') as EXPFCCount,Count(*) filter(where fine=0 and safe=0 and sad=0 and worst=0 and difficulty='EXEX') as EXEXPFCCount from plays where userid=$1 and songid=$2 group by userid)t1 join (select rank,t.score,t.percent from (select row_number()over(order by score desc)rank,* from(select distinct on (userid) * from (select * from plays where songid=$2)t order by userid,score desc)t)t where userid=$1)t2 on t1.userid=t1.userid",
[userId, song.id]
)
.then((data) => {
if (data.rows.length > 0) {
song.report = data.rows[0];
} else {
song.report = {
ecount: 0,
ncount: 0,
hcount: 0,
excount: 0,
exexcount: 0,
efccount: 0,
nfccount: 0,
hfccount: 0,
exfccount: 0,
exexfccount: 0,
epfccount: 0,
npfccount: 0,
hpfccount: 0,
expfccount: 0,
exexpfccount: 0,
rank: 0,
};
}
})
);
});
return Promise.all(promises);
})
.then((data) => {
return res.status(200).json(songs);
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/ratings/:songname/:username", (req, res) => {
var songId = -1,
userId = -1;
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname]
);
} else {
throw new Error("Could not find user!");
}
})
.then((data) => {
if (data.rows.length > 0) {
songId = data.rows[0].id;
return db.query(
"select * from (select row_number()over(order by score desc)rank,* from(select distinct on (userid) * from (select * from plays where songid=$1)t order by userid,score desc)t)t where userid=$2",
[songId, userId]
);
} else {
throw new Error("Could not find song!");
}
})
.then((data) => {
res.status(200).json(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/bestplays/:username", (req, res) => {
var songId = -1,
userId = -1,
songPromises = [],
plays = [],
limit = 5,
offset = 0;
if (req.query.limit) {
limit = req.query.limit;
}
if (req.query.offset) {
offset = req.query.offset;
}
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query(
"select * from (select distinct on (songid) * from plays where userid=$1 " +
(req.query.fails === "false" ? "and score!=0" : "") +
" order by songid,score desc)t order by score desc limit $2 offset $3",
[userId, Number(limit), Number(offset)]
);
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
res.status(200).json(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/bestplay/:username/:songname/:difficulty", (req, res) => {
var songId = -1,
userId = -1;
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
if (req.params.songname) {
return db.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname]
);
} else {
return db.query(
"select * from plays where userid=$1 order by score desc",
[userId]
);
}
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
if (req.params.songname && data.rows.length > 0) {
songId = data.rows[0].id;
return db.query(
"select * from plays where userid=$1 and songid=$2 and difficulty=$3 order by score desc,percent desc limit 1",
[userId, songId, req.params.difficulty]
);
} else {
res.status(400).send("Could not find song!");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
res.status(200).json(data.rows[0]);
} else {
res.status(400).send("No data found!");
}
})
.catch((err) => {
res.status(500).send(err.message + JSON.stringify(req.body));
});
});
app.get("/userdata/:username", (req, res) => {
var songId = -1,
userId = -1,
finalData = {};
db.query(
"select id,megamix,futuretone,playstyle,playcount,fccount,rating,last_played,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear from users where username=$1 limit 1",
[req.params.username]
)
.then((data) => {
if (data && data.rows.length > 0) {
finalData = data.rows[0];
return db.query(
"select t.difficulty,COUNT(t.difficulty) from (select distinct on(songid) songid,*,users.id from plays join users on userid=users.id where users.username=$1 and plays.safe=0 and plays.worst=0 and plays.sad=0)t group by t.difficulty",
[req.params.username]
);
} else {
throw new Error("Could not retrieve user data!");
}
})
.then((data) => {
if (data) {
var fcData = {};
data.rows.forEach((fc) => {
fcData[fc.difficulty] = fc.count;
});
finalData = { ...{ fcdata: fcData }, ...finalData };
return db.query(
"select t.difficulty,COUNT(t.difficulty) from (select distinct on(songid) songid,*,users.id from plays join users on userid=users.id where users.username=$1 and plays.fine=0 and plays.safe=0 and plays.worst=0 and plays.sad=0)t group by t.difficulty",
[req.params.username]
);
} else {
throw new Error("Could not retrieve user data!");
}
})
.then((data) => {
if (data) {
var fcData = {};
data.rows.forEach((fc) => {
fcData[fc.difficulty] = fc.count;
});
finalData = { ...{ pfcdata: fcData }, ...finalData };
res.status(200).json(finalData);
} else {
throw new Error("Could not retrieve user data!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/plays/:username/:songid", (req, res) => {
var limit = 5,
offset = 0;
if (req.query.limit) {
limit = req.query.limit;
}
if (req.query.offset) {
offset = req.query.offset;
}
db.query(
"select plays.* from plays join users on users.id=plays.userid where users.username=$1 and plays.songid=$2 order by score desc,percent desc,date desc limit $3 offset $4",
[req.params.username, req.params.songid, Number(limit), Number(offset)]
)
.then((data) => {
res.status(200).json(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/playcount/:username/:songname/:difficulty", (req, res) => {
var songId = -1,
userId = -1;
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname]
);
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
if (req.params.songname && data.rows.length > 0) {
songId = data.rows[0].id;
return db.query(
"select * from plays where userid=$1 and songid=$2 and difficulty=$3 order by score desc",
[userId, songId, req.params.difficulty]
);
} else {
res.status(400).send("Could not find song!");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
res.status(200).json({ playcount: data.rows.length });
} else {
res.status(200).json({ playcount: 0 });
}
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/songpasscount/:username/:songname/:difficulty", (req, res) => {
var songId = -1,
userId = -1;
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname]
);
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
if (req.params.songname && data.rows.length > 0) {
songId = data.rows[0].id;
return db.query(
"select * from plays where userid=$1 and songid=$2 and difficulty=$3 and score>0",
[userId, songId, req.params.difficulty]
);
} else {
res.status(400).send("Could not find song!");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
res.status(200).json({ passcount: data.rows.length });
} else {
res.status(200).json({ passcount: 0 });
}
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/songfccount/:username/:songname/:difficulty", (req, res) => {
var songId = -1,
userId = -1;
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname]
);
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
if (req.params.songname && data.rows.length > 0) {
songId = data.rows[0].id;
return db.query(
"select * from plays where userid=$1 and songid=$2 and difficulty=$3 and safe=0 and sad=0 and worst=0",
[userId, songId, req.params.difficulty]
);
} else {
res.status(400).send("Could not find song!");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
res.status(200).json({ fccount: data.rows.length });
} else {
res.status(200).json({ fccount: 0 });
}
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/songpfccount/:username/:songname/:difficulty", (req, res) => {
var songId = -1,
userId = -1;
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname]
);
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
if (req.params.songname && data.rows.length > 0) {
songId = data.rows[0].id;
return db.query(
"select * from plays where userid=$1 and songid=$2 and difficulty=$3 and fine=0 and safe=0 and sad=0 and worst=0",
[userId, songId, req.params.difficulty]
);
} else {
res.status(400).send("Could not find song!");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
res.status(200).json({ fccount: data.rows.length });
} else {
res.status(200).json({ fccount: 0 });
}
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/songmods/:username/:songname/:difficulty", (req, res) => {
var songId = -1,
userId = -1,
hs = 0,
sd = 0,
hd = 0;
db.query("select id from users where username=$1 limit 1", [
req.params.username,
])
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
return db.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[req.params.songname]
);
} else {
throw new Error("Cannot find user!");
}
})
.then((data) => {
if (req.params.songname && data.rows.length > 0) {
songId = data.rows[0].id;
return db.query(
"select COUNT(mod) from (select * from plays where userid=$1 and songid=$2 and difficulty=$3 and mod=$4)t",
[userId, songId, req.params.difficulty, "HS"]
);
} else {
res.status(400).send("Could not find song!");
}
})
.then((data) => {
if (data && data.rows.length > 0) {
hs = data.rows[0].count;
}
return db.query(
"select COUNT(mod) from (select * from plays where userid=$1 and songid=$2 and difficulty=$3 and mod=$4)t",
[userId, songId, req.params.difficulty, "SD"]
);
})
.then((data) => {
if (data && data.rows.length > 0) {
sd = data.rows[0].count;
}
return db.query(
"select COUNT(mod) from (select * from plays where userid=$1 and songid=$2 and difficulty=$3 and mod=$4)t",
[userId, songId, req.params.difficulty, "HD"]
);
})
.then((data) => {
if (data && data.rows.length > 0) {
hd = data.rows[0].count;
}
res.status(200).json({ hs: hs, sd: sd, hd: hd });
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/rating/:username", (req, res) => {
if (req.params.username) {
db.query("select rating from users where username=$1 limit 1", [
req.params.username,
]).then((data) => {
if (data.rows.length > 0) {
res.status(200).json(data.rows[0]);
} else {
res.status(200).json({ rating: 0 });
}
});
} else {
res.status(400).send("Invalid username!");
}
});
app.get("/recentplays/:username", (req, res) => {
if (req.params.username) {
db.query(
"select plays.* from plays join users on users.id=plays.userid where users.username=$1 order by plays.id desc limit 5",
[req.params.username]
).then((data) => {
if (data.rows.length > 0) {
res.status(200).json(data.rows);
} else {
res.status(200).json([]);
}
});
} else {
res.status(400).send("Invalid username!");
}
});
app.get("/users/:orderby/:sortorder", (req, res) => {
if (
req.params.orderby &&
req.params.sortorder &&
req.query.limit &&
req.query.offset
) {
var valid = ["rating", "last_played", "playcount", "username", "fccount"];
var validsort = ["desc", "asc"];
if (
valid.includes(req.params.orderby) &&
validsort.includes(req.params.sortorder)
) {
db.query(
"select username,rating,last_played,playcount,fccount from users order by " +
req.params.orderby +
" " +
req.params.sortorder +
",rating desc limit $1 offset $2",
[req.query.limit, req.query.offset]
)
.then((data) => {
return res.status(200).json(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Not a valid sort option!");
}
} else {
res.status(400).send("Invalid query!");
}
});
function ValidateToken(username, token) {
return db
.query("select authentication_token from users where username=$1 limit 1", [
username,
])
.then((data) => {
if (data.rows.length > 0) {
return token === data.rows[0].authentication_token;
} else {
return false;
}
});
}
function GetSongId(songname) {
return db
.query(
"select id from songs where name=$1 or romanized_name=$1 or english_name=$1 limit 1",
[songname]
)
.then((data) => {
if (data.rows.length > 0) {
return data.rows[0].id;
} else {
throw new Error("Could not get song ID for song '" + songname + "'");
}
});
}
function GetNoteCount(songname, difficulty) {
var songID = -1;
return GetSongId(songname)
.then((id) => {
songID = id;
return db.query(
"select notecount from songdata where songid=$1 and difficulty=$2 limit 1",
[songID, difficulty]
);
})
.then((data) => {
if (data.rows.length > 0) {
return data.rows[0].notecount;
} else {
throw new Error(
"Could not get note count for song '" +
songname +
"' on difficulty '" +
difficulty +
"'"
);
}
});
}
app.post("/song/:songname/:difficulty", (req, res) => {
if (
req.body &&
req.params.songname &&
req.params.difficulty &&
req.body.username &&
req.body.percent &&
req.body.authentication_token
) {
var noteCount = 0,
songID = 0,
fail = false;
ValidateToken(req.body.username, req.body.authentication_token)
.then((allowed) => {
if (allowed) {
return GetSongId(req.params.songname);
} else {
throw new Error("Could not authenticate!");
}
})
.then((songId) => {
if (songId) {
songID = songId;
return GetNoteCount(req.params.songname, req.params.difficulty);
} else {
throw new Error("Could not find song ID!");
}
})
.then((noteCount) => {
var percentThreshold =
(req.params.difficulty === "E" ? 100 : 107) / 100.0;
var percent = (req.params.difficulty === "E" ? 100 : 107)
? Math.min(req.body.percent / 100.0, percentThreshold)
: Math.min(req.body.percent / 107.0, percentThreshold);
var cool = 0;
var fine = 0;
var safe = 0;
var sad = 0;
var worst = 0;
for (var i = 0; i < noteCount; i++) {
if (req.body.isFC) {
if (Math.random() < percent) {
cool++;
} else {
fine++;
}
} else {
if (Math.random() < percent) {
cool++;
continue;
} else if (Math.random() < percent) {
fine++;
continue;
} else if (Math.random() < percent) {
worst++;
continue;
} else if (Math.random() < percent) {
safe++;
continue;
} else if (Math.random() < percent) {
sad++;
continue;
} else {
worst++;
}
}
}
switch (req.params.difficulty) {
case "E":
{
if (req.body.percent < 30) {
fail = true;
}
}
break;
case "N":
{
if (req.body.percent < 50) {
fail = true;
}
}
break;
case "H":
{
if (req.body.percent < 60) {
fail = true;
}
}
break;
case "EX":
case "EXEX":
{
if (req.body.percent < 70) {
fail = true;
}
}
break;
default:
{
if (req.body.percent < 60) {
fail = true;
}
}
break;
}
if (req.body.fail) {
fail = req.body.fail;
}
//res.status(200).json({cool:cool,fine:fine,safe:safe,sad:sad,worst:worst,percent:req.body.percent})
return axios.post("http://projectdivar.com/submit", {
username: req.body.username,
authentication_token: req.body.authentication_token,
song: req.params.songname,
difficulty: req.params.difficulty,
cool: cool,
fine: fine,
safe: safe,
sad: sad,
worst: worst,
percent: req.body.percent,
fail: String(fail),
});
})
.then((data) => {
res.status(200).json(data.data);
})
.catch((err) => {
res.status(400).send(err.message);
});
} else {
res.status(400).send("Invalid query!");
}
});
function CheckUserExists(username, email) {
return db.query(
"select id,username,email,registered from users where username=$1 or email=$2 limit 1",
[username, email]
);
}
function SendLoginEmail(username, emailTo, authCode) {
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "admin@projectdivar.com",
pass: process.env.GMAIL, // naturally, replace both with your real credentials or an application-specific password
},
});
transporter.sendMail(
{
from: "admin@projectdivar.com",
to: emailTo,
subject: "Project DivaR Login Code",
html: `<b>${username}</b>,<br><br>Thank you for using Project DivaR!<br><br>Your authentication code is <b>${authCode}</b>!`,
},
(err, info) => {
if (err) {
console.log(err.message);
} else {
console.log(info.envelope);
console.log(info.messageId);
}
}
);
}
function SendRegistrationEmail(username, emailTo, authCode) {
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "admin@projectdivar.com",
pass: process.env.GMAIL, // naturally, replace both with your real credentials or an application-specific password
},
});
transporter.sendMail(
{
from: "admin@projectdivar.com",
to: emailTo,
subject: "Project DivaR Registration Code",
html: `<b>${username}</b>,<br><br>Thank you for signing up for Project DivaR!<br><br>Your authentication code is <b>${authCode}</b>!`,
},
(err, info) => {
if (err) {
console.log(err.message);
} else {
console.log(info.envelope);
console.log(info.messageId);
}
}
);
}
function GetUserInfo(username) {
return db.query(
"select id,username,email,code_time from users where username=$1 limit 1",
[username]
);
}
function GetUserLoginAllowed(username, authCode) {
return db.query(
"select id,username,email,code_time,playstyle,twitter_name,twitch_name from users where username=$1 and code=$2 limit 1",
[username, authCode]
);
}
app.post("/authenticate/authToken", (req, res) => {
if (req.body && req.body.username && req.body.authCode) {
GetUserLoginAllowed(req.body.username.trim(), req.body.authCode.trim())
.then((data) => {
if (data.rows.length > 0) {
return db.query(
"select authentication_token from users where id=$1",
[data.rows[0].id]
);
} else {
return new Error("Failed login!");
}
})
.then((data) => {
if (data.rows.length > 0) {
res.status(200).json(data.rows[0]);
} else {
return new Error("Failed to get authentication token!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid Credentials!");
}
});
app.post("/authenticate/login", (req, res) => {
if (req.body && req.body.username && req.body.authCode) {
GetUserLoginAllowed(
req.body.username.trim(),
req.body.authCode.trim()
).then((data) => {
if (data.rows.length > 0) {
res.status(200).json(data.rows[0]);
} else {
return new Error("Failed login!");
}
});
} else {
res.status(400).send("Invalid Credentials!");
}
});
app.post("/sendemail/login", function (req, res) {
if (req.body && req.body.username) {
GetUserInfo(req.body.username.trim())
.then((data) => {
if (data.rows.length > 0) {
res.status(200).send("Email sent.");
//console.log(data.rows[0].code_time)
if (data.rows[0].code_time) {
if (
moment(data.rows[0].code_time, "YYYY-MM-DD HH:mm:ss.SSSZ").diff(
moment(),
"minutes"
) <= -15
) {
var authCode = Math.floor(Math.random() * 90000) + 10000;
SendLoginEmail(req.body.username, data.rows[0].email, authCode);
db.query("update users set code=$1,code_time=$3 where id=$2", [
authCode,
data.rows[0].id,
moment(),
]);
}
//console.log(moment(data.rows[0].code_time,"YYYY-MM-DD HH:mm:ss.SSSZ").diff(moment(),'minutes'))
} else {
var authCode = Math.floor(Math.random() * 90000) + 10000;
SendLoginEmail(req.body.username, data.rows[0].email, authCode);
db.query("update users set code=$1,code_time=$3 where id=$2", [
authCode,
data.rows[0].id,
moment(),
]);
}
} else {
return new Error("User does not exist!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.patch("/updateRegisteredState", function (req, res) {
if (req.body && req.body.username && req.body.authCode) {
GetUserLoginAllowed(req.body.username, req.body.authCode)
.then((data) => {
if (data.rows.length > 0) {
return db.query("update users set registered=$1 where id=$2", [
true,
data.rows[0].id,
]);
} else {
throw new Error("Could not login!");
}
})
.then((data) => {
res.status(200).send("Registered!");
})
.catch((err) => {
res.status(500).send("Could not finish registration!");
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.post("/sendemail/register", function (req, res) {
if (req.body && req.body.username && req.body.email) {
//Generate a token for the user to login with.
CheckUserExists(req.body.username.trim(), req.body.email.trim())
.then((data) => {
var authCode = Math.floor(Math.random() * 90000) + 10000;
var authenticationToken =
String(Math.floor(Math.random() * 90000) + 10000) +
"-" +
String(Math.floor(Math.random() * 90000) + 10000) +
"-" +
String(Math.floor(Math.random() * 90000) + 10000);
if (data.rows.length > 0) {
//db.query("update users set code=$1 where id=$2",[authCode,data.rows[0].id])
if (data.rows[0].registered) {
throw new Error("User already exists!");
} else {
return db.query(
"update users set code=$1 where id=$2 returning code",
[authCode, data.rows[0].id]
);
}
} else {
return db.query(
"insert into users(username,email,authentication_token,code) values($1,$2,$3,$4) returning code",
[req.body.username, req.body.email, authenticationToken, authCode]
);
}
})
.then((data) => {
if (data.rows.length > 0) {
res.status(200).send("Email sent.");
SendRegistrationEmail(
req.body.username,
req.body.email,
data.rows[0].code
);
} else {
throw new Error("Something bad happened!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
function AuthenticateUser(username, auth) {
return db.query(
"select id,username,email from users where username=$1 and authentication_token=$2 limit 1",
[username, auth]
);
}
app.post("/authenticateuser", function (req, res) {
if (req.body && req.body.username && req.body.authenticationToken) {
AuthenticateUser(
req.body.username.trim(),
req.body.authenticationToken.trim()
)
.then((data) => {
if (data.rows.length > 0) {
res.status(200).send("Authentication Success!");
} else {
throw new Error("Authentication Failed!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.post("/updateuser", function (req, res) {
var userId = -1;
if (
req.body &&
req.body.playStyle &&
req.body.username &&
req.body.authCode
) {
GetUserLoginAllowed(req.body.username, req.body.authCode)
.then((data) => {
if (data.rows.length > 0) {
userId = data.rows[0].id;
if (req.body.twitchName) {
db.query("update users set twitch_name=$1 where id=$2", [
req.body.twitchName,
userId,
]);
}
if (req.body.twitterName) {
return axios.get(
"https://api.twitter.com/1.1/users/show.json?screen_name=" +
req.body.twitterName,
{
headers: {
/*BEARER*/ Authorization:
"Bearer " + process.env.TWITTER_BEARER, //the token is a variable which holds the token
},
}
);
} else {
return { data: {} };
}
} else {
throw new Error("Could not login!");
}
})
.then((data) => {
if (data.data.id) {
return db.query(
"update users set playstyle=$1,twitter=$2,twitter_name=$3 where id=$4",
[req.body.playStyle, data.data.id, req.body.twitterName, userId]
);
} else {
return db.query("update users set playstyle=$1 where id=$2", [
req.body.playStyle,
userId,
]);
}
})
.then((data) => {
res.status(200).send("Successfully updated user settings!");
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.post("/getUserAuthData", function (req, res) {
if (req.body && req.body.password && req.body.userId) {
if (req.body.password === process.env.GUARDIANPASSWORD) {
db.query(
"select uploads,username,authentication_token from users where id=$1",
[req.body.userId]
)
.then((data) => {
if (data.rows.length > 0) {
res.status(400).json(data.rows[0]);
db.query("update users set uploads=$1 where id=$2", [
data.rows[0].uploads + 1,
req.body.userId,
]);
} else {
res.status(400).send("No user found!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Authentication failed!");
}
} else {
res.status(400).send("Invalid credentials!");
}
});
app.post("/passImageData", function (req, res) {
if (req.body && req.body.user && req.body.auth && req.body.url) {
axios
.post("http://projectdivar.com/image", {
user: req.body.user,
auth: req.body.auth,
url: req.body.url,
})
.then((data) => {
res.status(200).json(data.data);
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.post("/streamstart/:id", function (req, res) {
if (req.body && req.body.username && req.body.authentication_token) {
GetUserLoginAllowed(
req.body.username.trim(),
req.body.authentication_token.trim()
)
.then((data) => {
if (data.rows.length > 0) {
spawn("../divabotguardian/stream_monitor.sh", [
Number(req.params.id),
]);
res.status(200).send("Monitor started");
} else {
res.status(400).send("Failed to authenticate");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.post("/streamtop/:id", function (req, res) {
exec("ps 43", (err, out, stderr) => {
if (err) {
res.status(500).send(`${err.message}`);
return;
}
if (stderr) {
res.status(500).send(`${stderr}`);
return;
}
res.status(200).send(`${out}`);
});
});
app.post("/streaminfo/:id", function (req, res) {
if (req.body && req.body.username && req.body.authentication_token) {
GetUserLoginAllowed(
req.body.username.trim(),
req.body.authentication_token.trim()
)
.then((data) => {
if (data.rows.length > 0) {
exec(
"ps $(cat ../divabotguardian/processes/" +
Number(req.params.id) +
".ffmpeg)|wc -l",
(err, out, stderr) => {
if (err) {
res.status(500).send(`${err.message}`);
return;
}
if (stderr) {
res.status(500).send(`${stderr}`);
return;
}
res.status(200).send(`${out}`);
}
);
} else {
res.status(400).send("Failed to authenticate");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.get("/cans", function (req, res) {
db.query(
"select (select count(*) from cans where can=true) as cans,(select count(*) from cans where can=false) as notcan;"
)
.then((data) => {
res.status(200).send(data.rows[0]);
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/ev", function (req, res) {
if (req.query.all) {
db.query(
"select * from " + (req.query.en ? "en_" : "") + "event order by id desc;"
)
.then((data) => {
res.status(200).send(data.rows);
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
db.query(
"select * from " +
(req.query.en ? "en_" : "") +
"event order by id desc limit 1;"
)
.then((data) => {
res.status(200).send(data.rows[0]);
})
.catch((err) => {
res.status(500).send(err.message);
});
}
});
app.post("/cans", function (req, res) {
if (req.body && req.body.cans !== undefined && req.body.cans !== null) {
db.query("insert into cans(date,can) values($1,$2)", [
moment(),
req.body.cans,
]).then((data) => {
res.status(200).send("Done!");
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.post("/streamkill/:id", function (req, res) {
if (req.body && req.body.username && req.body.authentication_token) {
GetUserLoginAllowed(
req.body.username.trim(),
req.body.authentication_token.trim()
)
.then((data) => {
if (data.rows.length > 0) {
exec(
"kill $(cat ../divabotguardian/processes/" +
Number(req.params.id) +
".ffmpeg)|wc -l",
(err, out, stderr) => {
if (err) {
res.status(500).send(`${err.message}`);
return;
}
if (stderr) {
res.status(500).send(`${stderr}`);
return;
}
res.status(200).send(`${out}`);
}
);
} else {
res.status(400).send("Failed to authenticate");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
} else {
res.status(400).send("Invalid credentials!");
}
});
app.get("/streamdata/:id", function (req, res) {
db.query("select twitch_name from users where id=$1", [req.params.id])
.then((data) => {
return twitchStreams.get(data.rows[0].twitch_name);
})
.then(function (streams) {
if (streams.length > 0) {
var streamchoice = undefined;
for (var i = 0; i < streams.length; i++) {
if (streams[i].quality.includes("720p")) {
streamchoice = streams[i];
break;
}
}
if (streamchoice === undefined) {
streamchoice = streams[0];
}
res.status(200).send(streamchoice.url);
} else {
res.status(400).send("Not online!");
}
})
.catch((err) => {
res.status(500).send(err.message);
});
});
app.get("/eventchart", function (req, res) {
const myChart = new QuickChart();
myChart
.setConfig({
type: "bar",
data: {
labels: ["Hello world", "Foo bar"],
datasets: [{ label: "Foo", data: [1, 2] }],
},
})
.setWidth(300)
.setHeight(150);
// You can send the URL to someone...
const chartImageUrl = myChart.getUrl();
res.status(200).send('<img src="' + chartImageUrl + '">');
});
var process_images = [];
var processPromises = [];
var largestId = 0;
var filterId = 0;
var MAX_INDEX = 12; //To prevent being rate-limited.
function Process(data, ind) {
for (var i in data.data.statuses) {
var tweet = data.data.statuses[i];
if (
(tweet.source && tweet.source.includes("Nintendo Switch Share")) ||
tweet.source.includes("PlayStation®Network")
) {
if (tweet.extended_entities) {
//console.log(tweet.extended_entities.media)
for (var j = 0; j < tweet.extended_entities.media.length; j++) {
var media = tweet.extended_entities.media[j];
process_images.push({
image: media.media_url,
user: tweet.user.id,
id: tweet.id,
});
}
}
}
}
//console.log(process_images)
if (data.data.search_metadata.next_results && ind < MAX_INDEX) {
return axios
.get(
"https://api.twitter.com/1.1/search/tweets.json" +
data.data.search_metadata.next_results,
{
headers: {
/*BEARER*/ Authorization: "Bearer " + process.env.TWITTER_BEARER, //the token is a variable which holds the token
},
}
)
.then((data) => {
//console.log("Going to next: "+(ind+1))
return Process(data, ind + 1);
});
}
return "Done!";
}
app.use(
"/files",
express.static("files", {
maxAge: 86400000 * 30,
})
);
/*
axios.get('https://api.twitter.com/1.1/search/tweets.json?q=@divarbot', {
headers: {
Authorization: 'Bearer '+process.env.TWITTER_BEARER //the token is a variable which holds the token
}
})
.then((data)=>{
//console.log(data.data.statuses)
//console.log(data.data)
return Process(data);
})
.then((data)=>{process_images.forEach((image)=>{console.log(image)})})*/
/*setInterval(
()=>{
twitchStreams.get('smallant')
.then(function(streams) {
//console.log(streams)
if (streams.length>0) {
db.query("update streams set stream=$1 where id=1",[streams[0].url]);
}
})
.catch((err)=>{
console.log(err.message)
})
},5000)*/
/*
setInterval(
()=>{
function addToQueue(uploadData) {
if (uploadData.tries===undefined||uploadData.tries===null) {
uploadData.tries=1;
} else {
uploadData.tries+=1;
}
if (uploadData.tries<5) {
console.log("Failed to upload. Added back to queue. Tries: "+uploadData.tries+" / "+JSON.stringify(uploadData))
db.query("insert into uploadedplays(filename,userid,submissiondate,id,playid,tries) values($1,$2,$3,$4,$5,$6);",
[uploadData.filename,uploadData.userid,uploadData.submissiondate,uploadData.id,uploadData.playid,uploadData.tries])
}
}
var uploadData=undefined,user=undefined,auth=undefined,playData;
db.query("select * from uploadedplays where tries is null or tries>=0 order by submissiondate asc limit 1")
.then((data)=>{
if (data.rows.length>0) {
uploadData=data.rows[0];
//console.log(uploadData)
return db.query("select username,authentication_token from users where id=$1",[uploadData.userid])
}
})
.then((data)=>{
if (uploadData && data.rows.length>0) {
user=data.rows[0].username
auth=data.rows[0].authentication_token
if (uploadData.tries!==undefined&&uploadData.tries!==null) {
return db.query("update uploadedplays set tries=$2 where id=$1",[uploadData.id,(uploadData.tries*-1)])
} else {
return db.query("update uploadedplays set tries=-1 where id=$1",[uploadData.id])
}
}
})
.then((data)=>{
if (uploadData) {
//console.log(data.data)
return axios.post("http://projectdivar.com/image",
{url:uploadData.filename,user:user,auth:auth})
}
})
.then((data)=>{
if (uploadData) {
if (data.data==="Invalid parameters!") {
throw new Error("Invalid parameters while trying to submit play!")
}
}
})
.catch((err)=>{
if (uploadData) {
addToQueue(uploadData)
}
})
}
,1000)
*/
//setInterval(()=>{db.query("select * from twitter_bot limit 1")
//.then((data)=>{
// largestId=filterId=data.rows[0].lastpost;
// //console.log("Filter Id: "+filterId);
// /*return axios.get('https://api.twitter.com/1.1/search/tweets.json?q=%23mega39s', {
// headers: {
// Authorization: 'Bearer '+process.env.TWITTER_BEARER //the token is a variable which holds the token
// }
// })*/
// return axios.get('https://api.twitter.com/1.1/search/tweets.json?q=%23divarbot', {
// headers: {
// Authorization: 'Bearer '+process.env.TWITTER_BEARER //the token is a variable which holds the token
// }
// })
//})
//.then((data)=>{
// //console.log(data.data.statuses)
// //console.log(data.data)
// //data.data.s
// //console.log("Reading Twitter Data...")
// return Process(data,0);
//})
//.then((data)=>{
// //console.log(process_images)
// var promisesDone=0;
// process_images.forEach((obj)=>{
// if (filterId<obj.id) {
// if (largestId<obj.id) {largestId=obj.id}
// processPromises.push(new Promise((resolve,reject)=>{
// console.log("Process Twitter Post: "+obj.id);
// return db.query("select id from users where twitter=$1",[obj.user])
// .then((data)=>{
// if (data.rows.length>0) {
// console.log("Process new play for User id "+data.rows[0].id+"...")
// return db.query("insert into uploadedplays values($1,$2,$3)",[obj.image,data.rows[0].id,new Date()])
// .then(()=>{resolve("Done!")})
// } else {
// reject("Not associated with an Id!")
// }
// })
// .catch((err)=>{console.log(err.message);reject("Failed!")})}))
// }
//})
////setTimeout(()=>{console.dir(processPromises, {'maxArrayLength': null})},2000)
//return Promise.allSettled(processPromises)
//})
//.then((data)=>{
// //console.log(largestId)
// return db.query("update twitter_bot set lastpost=$1 returning *",[largestId])
//})
//.catch((err)=>{console.log(err.message)})
//},60000)
// setInterval(() => {
// // axios.get("http://www.projectdivar.com/eventdata/t20?chart=true&force=true");
// }, 20000);
CreateDynamicEndpoints();
app.listen(port, () =>
console.log(`app listening at http://localhost:${port}`)
);