start support for songs

This commit is contained in:
Adolfo Reyna
2023-05-31 06:11:50 -04:00
parent 3d3dab58f9
commit 2f726a5331
9 changed files with 640 additions and 18 deletions

148
dbTools/songs.js Normal file
View File

@@ -0,0 +1,148 @@
const DBName = "EMI_SOCIAL";
const Song = require("./../def/songs.js")
postDB = (DB)=>{
DB.songsCol = DB.db.db(DBName).collection("songs");
DB.newSong = (songObj) => {
return DB.songsCol.insertOne(songObj.toObj()).catch((err)=>{
console.log(err);
return false;
});
}
DB.removeSong = (songId) => {
if(!DB.ObjectID.isValid(songId)) return false;
const _id = DB.ObjectID(songId);
return DB.songsCol.deleteOne({_id}).catch((err)=>{
console.log(err);
return false;
});
}
DB.updateSongContent = (songId, newContent, oldContent) => {
if(!DB.ObjectID.isValid(songId)) return false;
const id = DB.ObjectID(songId);
let update = {
$set:{
content: newContent,
// lastUpdated: new Date() // add back when finish updating videos.
},
$push: {
contentHistory: oldContent
}
}
return DB.songsCol.updateOne({_id: id}, update).catch((err)=>{
console.log(err);
return false;
});
}
DB.newReaction = (songId, profileid, reaction) => {
if(!DB.ObjectID.isValid(songId)) return false;
const id = DB.ObjectID(songId);
let update = {
$set:{
["reactions." + profileid]: reaction,
lastUpdated: new Date()
}
}
return DB.songsCol.updateOne({_id: id}, update).catch((err)=>{
console.log(err);
return false;
});
}
DB.removeReaction = (songId, profileid) => {
if(!DB.ObjectID.isValid(songId)) return false;
const id = DB.ObjectID(songId);
let update = {
$unset:{
["reactions." + profileid]: ""
},
//$set: { //Maybe is not relevant to pump post here
// lastUpdated: new Date()
//}
}
return DB.songsCol.updateOne({_id: id}, update).catch((err)=>{
console.log(err);
return false;
});
}
DB.newComment = (songId, comment) => {
if(!DB.ObjectID.isValid(songId)) return false;
const id = DB.ObjectID(songId);
return DB.songsCol.updateOne({_id: id}, {
$push: {
comments: comment
},
$set: {
lastUpdated: new Date()
}
}).catch((err)=>{
console.log(err);
return false;
});
}
DB.newCommentReaction = (songId, commentDate, profileid, reaction) => {
if(!DB.ObjectID.isValid(songId)) return false;
const id = DB.ObjectID(songId);
let update = {
$set:{
["comments.$.reactions." + profileid]: reaction,
"comments.$.lastUpdated": new Date(),
lastUpdated: new Date()
}
}
return DB.songsCol.updateOne({
_id: id,
"comments.createdAt": commentDate
}, update).catch((err)=>{
console.log(err);
return false;
});
}
DB.removeCommentReaction = (songId, commentDate, profileid) => {
if(!DB.ObjectID.isValid(songId)) return false;
const id = DB.ObjectID(songId);
let update = {
$unset:{
["comments.$.reactions." + profileid]: '',
"comments.$.lastUpdated": new Date(),
},
$set: {
lastUpdated: new Date()
}
}
return DB.songsCol.updateOne({
_id: id,
"comments.createdAt": commentDate
}, update).catch((err)=>{
console.log(err);
return false;
});
}
DB.getSongs = async (limit = 20) => {
let query = {};
return DB.songsCol.find(query).sort({_id: -1}).limit(limit).toArray().catch((err)=>{
console.log(err);
return false;
});
}
DB.getSong = (songId) => {
if(!DB.ObjectID.isValid(songId)) return [];
let _id = DB.ObjectID(songId);
return DB.songsCol.findOne({_id}).catch((err)=>{
console.log(err);
return false;
});
}
}
module.exports = postDB;

View File

@@ -28,24 +28,7 @@ class User {
} }
toObj(){ toObj(){
let r = {}; return { ...this };
r.userid = this.userid
r.username = this.username;
r.profile = this.profile;
r.data = this.data;
r.username = this.username;
r.following = this.following;
r.lastUpdate = this.lastUpdate;
r.newsFeedCache = this.newsFeedCache;
r.notifications = this.notifications;
r.isGroup = this.isGroup;
r.isCourse = this.isCourse;
r.isPrivate = this.isPrivate;
r.isChat = this.isChat;
r.subscribed = this.subscribed;
r.pending = this.pending;
return r;
} }
} }

24
def/songs.js Normal file
View File

@@ -0,0 +1,24 @@
class Songs {
constructor(info) {
if (!info || !info.userid) throw "Can not construct empty profile";
this.userid = info.userid;
this.data = info.data || {};
const allowedParams = ["title", 'author', "content", "contentHistory", "bpm", "lang", "reactions", "root", 'beatsPerTempo'];
for (const key in info) {
if (info.hasOwnProperty(key) && allowedParams.includes(key)) {
this[key] = info[key];
}
}
this.createdAt = info.createdAt || new Date();
this.lastUpdated = info.lastUpdated || this.createdAt;
this.comments = info.comments || [];
this.reactions = info.reactions || {};
}
toObj() {
return { ...this };
}
}
module.exports = Songs;

View File

@@ -47,6 +47,7 @@ const Post = require("./def/post.js")
const Profile = require("./def/profile.js"); const Profile = require("./def/profile.js");
const profileRoute = require('./routes/profile.js'); const profileRoute = require('./routes/profile.js');
const postRoute = require('./routes/post.js'); const postRoute = require('./routes/post.js');
const songsRoute = require('./routes/songs.js');
const paymentsRoute = require('./routes/payments.js'); const paymentsRoute = require('./routes/payments.js');
const subsplashRoute = require('./routes/subsplash.js'); const subsplashRoute = require('./routes/subsplash.js');
const bibleRoute = require('./routes/bible.js'); const bibleRoute = require('./routes/bible.js');
@@ -258,6 +259,7 @@ DB.getDB.then((DB) => {
app.use('/post', sessionChecker, postRoute); app.use('/post', sessionChecker, postRoute);
app.use('/payments', sessionChecker, paymentsRoute); app.use('/payments', sessionChecker, paymentsRoute);
app.use('/bible', sessionChecker, bibleRoute); app.use('/bible', sessionChecker, bibleRoute);
app.use('/songs', sessionChecker, songsRoute);
//Public Routes //Public Routes
app.use('/subsplash', subsplashRoute); app.use('/subsplash', subsplashRoute);

View File

@@ -7,6 +7,8 @@ const postDB = require("./dbTools/post.js");
const profileDB = require("./dbTools/profile.js"); const profileDB = require("./dbTools/profile.js");
const paymentDB = require("./dbTools/payments.js"); const paymentDB = require("./dbTools/payments.js");
const loggerDB = require("./dbTools/logger.js"); const loggerDB = require("./dbTools/logger.js");
const songsDB = require("./dbTools/songs.js");
const getDB = new Promise((resolve, reject) => { const getDB = new Promise((resolve, reject) => {
@@ -116,6 +118,7 @@ const getDB = new Promise((resolve, reject) => {
profileDB(DB); profileDB(DB);
paymentDB(DB); paymentDB(DB);
loggerDB(DB); loggerDB(DB);
songsDB(DB);
resolve(DB); resolve(DB);
}); });

313
package-lock.json generated
View File

@@ -21,6 +21,7 @@
"mongodb": "^3.6.3", "mongodb": "^3.6.3",
"nodemailer": "^6.6.3", "nodemailer": "^6.6.3",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
"socket.io": "^4.6.1",
"stripe": "^8.178.0", "stripe": "^8.178.0",
"web-push": "^3.4.5" "web-push": "^3.4.5"
} }
@@ -44,6 +45,24 @@
"node-pre-gyp": "bin/node-pre-gyp" "node-pre-gyp": "bin/node-pre-gyp"
} }
}, },
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"node_modules/@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
},
"node_modules/@types/cors": {
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "16.10.2", "version": "16.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz",
@@ -156,6 +175,14 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
}, },
"node_modules/base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
"engines": {
"node": "^4.5.0 || >= 5.9"
}
},
"node_modules/bcrypt": { "node_modules/bcrypt": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz",
@@ -531,6 +558,63 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/engine.io": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz",
"integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==",
"dependencies": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"ws": "~8.11.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/engine.io-parser": {
"version": "5.0.6",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz",
"integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/engine.io/node_modules/cookie": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/engine.io/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/engine.io/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/entities": { "node_modules/entities": {
"version": "4.4.0", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
@@ -1395,6 +1479,84 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
}, },
"node_modules/socket.io": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz",
"integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==",
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.2",
"engine.io": "~6.4.1",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-adapter": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
"integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
"dependencies": {
"ws": "~8.11.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz",
"integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io-parser/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/socket.io/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/sparse-bitfield": { "node_modules/sparse-bitfield": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
@@ -1558,6 +1720,26 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}, },
"node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/yallist": { "node_modules/yallist": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -1581,6 +1763,24 @@
"tar": "^6.1.0" "tar": "^6.1.0"
} }
}, },
"@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
},
"@types/cors": {
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
"requires": {
"@types/node": "*"
}
},
"@types/node": { "@types/node": {
"version": "16.10.2", "version": "16.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz",
@@ -1678,6 +1878,11 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
}, },
"base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
},
"bcrypt": { "bcrypt": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz",
@@ -1959,6 +2164,48 @@
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
}, },
"engine.io": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz",
"integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==",
"requires": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"ws": "~8.11.0"
},
"dependencies": {
"cookie": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"engine.io-parser": {
"version": "5.0.6",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz",
"integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw=="
},
"entities": { "entities": {
"version": "4.4.0", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
@@ -2601,6 +2848,66 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
}, },
"socket.io": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz",
"integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==",
"requires": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.2",
"engine.io": "~6.4.1",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.1"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"socket.io-adapter": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
"integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
"requires": {
"ws": "~8.11.0"
}
},
"socket.io-parser": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz",
"integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"sparse-bitfield": { "sparse-bitfield": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
@@ -2728,6 +3035,12 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}, },
"ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"requires": {}
},
"yallist": { "yallist": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",

View File

@@ -22,6 +22,7 @@
"mongodb": "^3.6.3", "mongodb": "^3.6.3",
"nodemailer": "^6.6.3", "nodemailer": "^6.6.3",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
"socket.io": "^4.6.1",
"stripe": "^8.178.0", "stripe": "^8.178.0",
"web-push": "^3.4.5" "web-push": "^3.4.5"
} }

87
routes/songs.js Normal file
View File

@@ -0,0 +1,87 @@
var express = require('express')
var router = express.Router()
const DB = require("../mongoDB.js");
const Song = require("../def/songs.js");
DB.getDB.then((DB)=>{
const getUserId = function(req){
const user_sid = req.cookies.user_sid || req.query.user_sid || req.body.user_sid;
return DB.ObjectID(user_sid);
}
const getProfileId = (req)=>{
return DB.ObjectID(req.cookies.profile_id || req.query.profile_id || req.body.profile_id);
}
router.get("/", async (req, res) => {
let profileId = req.params.id;
let songs = await DB.getSongs();
return res.json({
status: "ok",
songs
});
});
router.post("/", async (req, res) => {
let post = {
userid: getUserId(req),
...req.body
}
let postObj = new Song(post);
let dbr = await DB.newSong(postObj);
song = postObj.toObj();
song._id = dbr.insertedId;
return res.json({
status: "ok",
...song
})
});
router.get("/:id", async (req, res) => {
let profileId = req.params.id;
let profile = await DB.getProfile(profileId);
return res.json({
status: "ok",
... profile
});
});
async function songBelongsToUser(songId, userid){
// TODO: Verify ownserhip
return true;
}
router.delete("/:id", async (req, res) => {
const userid = getUserId(req);
const songId = req.params.id;
if(!await songBelongsToUser(songId, userid))
return res.json({
status: "This profile is not yours."
});
await DB.removeSong(songId);
return res.json({
status: "ok"
});
});
router.post("/:id", async (req, res) => {
const userid = getUserId(req);
const songId = req.params.id;
const song = await DB.getSong(songId);
const newContent = req.body.content;
console.log("Updating song", newContent)
if(!await songBelongsToUser(songId, userid))
return res.json({
status: "This post is not yours."
});
await DB.updateSongContent(songId, newContent, song.content);
return res.json({
status: "ok"
});
});
});
module.exports = router

61
socketio.js Normal file
View File

@@ -0,0 +1,61 @@
// Server-side code
const express = require('express');
const http = require('http');
const socketIO = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIO(server);
let interval;
let tempo = 120; // Initial tempo (beats per minute)
let startTime; // Start time of the metronome
io.on('connection', (socket) => {
console.log('A client connected');
socket.on('start', () => {
console.log('Metronome started');
startTime = Date.now(); // Set the start time
// Calculate the delay between each beat based on the tempo
const delay = (60 / tempo) * 1000;
// Send a beat event to all connected clients at the specified interval
interval = setInterval(() => {
const elapsedTime = Date.now() - startTime;
io.emit('beat', elapsedTime);
}, delay);
});
socket.on('stop', () => {
console.log('Metronome stopped');
clearInterval(interval);
});
socket.on('tempo', (newTempo) => {
console.log(`Tempo set to ${newTempo} BPM`);
tempo = newTempo;
// If the metronome is already running, restart it with the new tempo
if (interval) {
clearInterval(interval);
const delay = (60 / tempo) * 1000;
interval = setInterval(() => {
const elapsedTime = Date.now() - startTime;
io.emit('beat', elapsedTime);
}, delay);
}
});
socket.on('disconnect', () => {
console.log('A client disconnected');
clearInterval(interval);
});
});
server.listen(3000, () => {
console.log('Server is running on port 3000');
});
return io;