Compare commits

...

19 Commits

Author SHA1 Message Date
Artem Anufrij
9d0272351d wip
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-28 13:00:46 +02:00
Artem Anufrij
94a6893444 code style
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-09-27 21:44:58 +02:00
Artem Anufrij
cd0b9a7f55 code design
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-27 21:43:52 +02:00
Artem Anufrij
97fcdcce5d add get api for random album covers
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-27 16:52:37 +02:00
Artem Anufrij
e6614d0805 add get api for random album covers
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-27 16:52:28 +02:00
Artem Anufrij
988afab81c fix most listened tracks. fix #19
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-27 15:20:19 +02:00
94007dc7da Merge pull request 'set empty covers for radios in the db funktion' (#17) from dev into main
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #17
2023-09-22 14:46:08 +02:00
Artem Anufrij
7145a0b1cd set empty covers for radios in the db funktion
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-09-22 14:22:55 +02:00
77948e93b6 Merge pull request 'change cover structure in radio fix #15' (#16) from dev into main
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #16
2023-09-22 13:09:34 +02:00
Artem Anufrij
07cc31ede3 change cover structure in radio fix #15
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-09-21 11:13:47 +02:00
Artem Anufrij
1051f05cce fix settings
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-19 16:42:00 +02:00
159aac6a2e Merge pull request 'save-and-restore-progress-for-audio fix #12' (#14) from save-and-restore-progress-for-audio into main
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #14
2023-09-19 16:34:08 +02:00
Artem Anufrij
85367e844d api for deleting progress
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-09-19 15:00:25 +02:00
Artem Anufrij
d7879a654a start to work on new functions
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-19 01:58:22 +02:00
449accb003 README.md aktualisiert
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-15 00:56:45 +02:00
392b6c007a server.js aktualisiert
All checks were successful
continuous-integration/drone/push Build is passing
New video quality (240, 320)
2023-08-27 13:36:54 +02:00
Artem Anufrij
a2e01bdbb7 update package.json
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-20 13:25:50 +01:00
Artem Anufrij
831597f015 share: object id
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-17 22:52:54 +01:00
Artem Anufrij
e4c1f14300 add title to shared items
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-17 22:47:15 +01:00
15 changed files with 568 additions and 341 deletions

View File

@@ -4,7 +4,7 @@
WebPlay Server provides REST-API for your media files. In then next step, you can use [WebPlay Client](/WebPlay/client) to access your content. WebPlay Server provides REST-API for your media files. In then next step, you can use [WebPlay Client](/WebPlay/client) to access your content.
## How to install your own instance (Docker) ## How to install your own instance (Docker)
[Documentation](/WebPlay/docker#requirements) [Documentation](/WebPlay/docker#setup-your-own-webplay-instance)
## Support ## Support
Join our Matrix room: <a href="https://matrix.to/#/#WebPlay:matrix.anufrij.de">#WebPlay:matrix.anufrij.de</a> Join our Matrix room: <a href="https://matrix.to/#/#WebPlay:matrix.anufrij.de">#WebPlay:matrix.anufrij.de</a>

View File

@@ -10,12 +10,12 @@
"http://localhost" "http://localhost"
], ],
"database": { "database": {
"host": "database", "host": "localhost",
"port": 27017, "port": 27017,
"name": "webplay" "name": "webplay"
}, },
"redis": { "redis": {
"host": "redis", "host": "localhost",
"port": 6379 "port": 6379
}, },
"album_cover_files": [ "album_cover_files": [

717
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,31 +10,31 @@
}, },
"dependencies": { "dependencies": {
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"body-parser": "^1.19.1", "body-parser": "^1.20.1",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.17.2", "express": "^4.18.2",
"express-fileupload": "^1.3.1", "express-fileupload": "^1.4.0",
"express-session": "^1.17.2", "express-session": "^1.17.3",
"fluent-ffmpeg": "^2.1.2", "fluent-ffmpeg": "^2.1.2",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^9.0.0",
"mime-types": "^2.1.34", "mime-types": "^2.1.35",
"mongodb": "^4.3.1", "mongodb": "^6.1.0",
"music-metadata": "^7.11.8", "music-metadata": "^7.13.3",
"node-fdkaac": "^1.4.1", "node-fdkaac": "^1.4.1",
"node-id3": "^0.2.3", "node-id3": "^0.2.6",
"node-lame": "^1.3.2", "node-lame": "^1.3.2",
"passport": "^0.5.2", "passport": "^0.6.0",
"passport-jwt": "^4.0.0", "passport-jwt": "^4.0.1",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"redis": "^4.5.1", "redis": "^4.6.4",
"request": "^2.88.2", "request": "^2.88.2",
"sharp": "0.27.2", "sharp": "0.27.2",
"socket.io": "^4.4.1", "socket.io": "^4.6.0",
"systeminformation": "^5.11.2" "systeminformation": "^5.17.9"
}, },
"devDependencies": { "devDependencies": {
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"nodemon": "^2.0.15" "nodemon": "^2.0.20"
} }
} }

View File

@@ -51,6 +51,12 @@ router.route("/filter/:term")
res.json(result).status(200).end(); res.json(result).status(200).end();
}); });
}) })
router.route("/random/:count")
.get(passport.authenticate("jwt", { session: false }), (req, res) => {
database.albums.randomCovers(req.params.count, 64, (result) => {
res.json(result).status(200).end();
});
})
router.route("/:id") router.route("/:id")
.get(checkGuest, (req, res) => { .get(checkGuest, (req, res) => {
@@ -126,7 +132,8 @@ router.route("/:id/share")
if (result == null) { if (result == null) {
let item = { let item = {
user_id: req.user._id, user_id: req.user._id,
object_id: album._id, object_id: new ObjectId(album_id),
title: album.title,
type: "album", type: "album",
cover: album.covers.cover32 cover: album.covers.cover32
} }

View File

@@ -128,7 +128,8 @@ router.route("/:id/share")
if (result == null) { if (result == null) {
let item = { let item = {
user_id: req.user._id, user_id: req.user._id,
object_id: box._id, object_id: new ObjectId(box_id),
title: box.title,
type: "box", type: "box",
cover: box.covers.cover32 cover: box.covers.cover32
} }

View File

@@ -56,9 +56,9 @@ router
if (radio) { if (radio) {
if (req.files.file) { if (req.files.file) {
resize_image_for_radio(req.files.file.data, (result) => { resize_image_for_radio(req.files.file.data, (result) => {
radio.cover32 = result.cover32; radio.covers.cover32 = result.cover32;
radio.cover64 = result.cover64; radio.covers.cover64 = result.cover64;
radio.cover128 = result.cover128; radio.covers.cover128 = result.cover128;
database.radios.update(radio); database.radios.update(radio);
res.json(radio).end(); res.json(radio).end();
}); });

View File

@@ -138,11 +138,6 @@ router
router router
.route("/history") .route("/history")
.get(passport.authenticate("jwt", { session: false }), (req, res) => {
database.historyList(req.user._id, result => {
res.json(result).end();
});
})
.post(passport.authenticate("jwt", { session: false }), (req, res) => { .post(passport.authenticate("jwt", { session: false }), (req, res) => {
let item = req.body; let item = req.body;
item.userId = req.user._id; item.userId = req.user._id;
@@ -159,6 +154,31 @@ router
}); });
}); });
router
.route("/progress")
.post(passport.authenticate("jwt", { session: false }), (req, res) => {
let item = req.body;
item.userId = req.user._id;
database.progress.update(item);
res.status(200).end();
});
router
.route("/progress/:parent")
.get(passport.authenticate("jwt", { session: false }), (req, res) => {
database.progress.get(req.params.parent, result => {
res.json(result).end();
});
})
.delete(passport.authenticate("jwt", { session: false }), (req, res) => {
let item = {
parentId: req.params.parent,
userId: req.user._id
}
database.progress.delete(item);
res.status(200).end();
});
router router
.route("/settings") .route("/settings")
.put(passport.authenticate("jwt", { session: false }), (req, res) => { .put(passport.authenticate("jwt", { session: false }), (req, res) => {

View File

@@ -52,7 +52,7 @@ const status = {
process.stdout.write("server DEF arrays\n"); process.stdout.write("server DEF arrays\n");
const lists = { const lists = {
audio_quality: ["64", "96", "128", "192", "256", "320"], audio_quality: ["64", "96", "128", "192", "256", "320"],
video_quality: ["480", "720", "1080"], video_quality: ["240", "360", "480", "720", "1080"],
user_role: ["admin", "moderator", "user"], user_role: ["admin", "moderator", "user"],
lang: ["ENG", "GER", "RUS"], lang: ["ENG", "GER", "RUS"],
visibility: ["global", "instance", "owner", "hidden"] visibility: ["global", "instance", "owner", "hidden"]

View File

@@ -1,4 +1,4 @@
const { MongoClient } = require('mongodb'); const MongoClient = require('mongodb').MongoClient;
const server = require("../../server"); const server = require("../../server");
const config = server.config; const config = server.config;
@@ -14,7 +14,10 @@ exports.connect = async function () {
else { else {
try { try {
console.log("DB CONNECTING:" + config.database.host + ":" + config.database.port) console.log("DB CONNECTING:" + config.database.host + ":" + config.database.port)
const client = await MongoClient.connect(url); const client = await MongoClient.connect(url, (err, db)=> {
console.log("DB Connected")
}
);
dbo = client.db(database); dbo = client.db(database);
return dbo; return dbo;
} catch (error) { } catch (error) {

View File

@@ -311,3 +311,26 @@ exports.empty = function (callback) {
callback(result.filter(f => !f.tracks || f.tracks.length == 0)); callback(result.filter(f => !f.tracks || f.tracks.length == 0));
}); });
}; };
exports.randomCovers = function (count, size, callback) {
dbo
.collection("albums")
.find({ "covers.cover64": { $exists: true } })
.project({ "covers.cover64": true })
.toArray((err, result) => {
if (result.length > count) {
let res = [];
while (count-- > 0) {
let rnd = randomNumber(0, result.length);
res.push(result[rnd]);
}
callback(res);
} else {
callback(result);
}
})
}
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}

View File

@@ -62,6 +62,9 @@ exports.artists = artists;
const boxes = require("./boxes"); const boxes = require("./boxes");
exports.boxes = boxes; exports.boxes = boxes;
const progress = require("./progress");
exports.progress = progress;
const videos = require("./videos"); const videos = require("./videos");
exports.videos = videos; exports.videos = videos;

View File

@@ -0,0 +1,27 @@
const { ObjectId } = require('mongodb');
const connector = require("./CONNECTOR");
var dbo;
connector.connect().then((ret) => {
dbo = ret;
});
exports.get = function (parentId, callback) {
dbo.collection("progress")
.findOne({ parentId: parentId }, (err, result) => {
if (err) throw err;
callback(result);
});
}
exports.update = function (item) {
dbo.collection("progress").deleteMany({ userId: ObjectId(item.userId), parentId: item.parentId }, () => {
dbo.collection("progress").insertOne(item, (err) => {
if (err) throw err;
});
});
};
exports.delete = function (item) {
dbo.collection("progress").deleteMany({ userId: ObjectId(item.userId), parentId: item.parentId }, (err) => {
if (err) throw err;
});
}

View File

@@ -13,6 +13,9 @@ exports.collection = function (callback) {
.toArray((err, result) => { .toArray((err, result) => {
result.forEach(item => { result.forEach(item => {
item.type = "radio"; item.type = "radio";
if (!item.covers) {
item.covers = {};
}
}); });
callback(result); callback(result);
}); });
@@ -23,6 +26,9 @@ exports.byId = function (id, callback) {
.collection("radios") .collection("radios")
.findOne({ _id: ObjectId(id) }, (err, result) => { .findOne({ _id: ObjectId(id) }, (err, result) => {
if (err) throw err; if (err) throw err;
if (!result.covers) {
result.covers = {};
}
callback(result); callback(result);
}); });
}; };
@@ -63,9 +69,7 @@ exports.update = function (radio, callback) {
$set: { $set: {
name: radio.name, name: radio.name,
url: radio.url, url: radio.url,
cover32: radio.cover32, covers: radio.covers
cover64: radio.cover64,
cover128: radio.cover128
} }
}, },
{ upsert: false }, { upsert: false },

View File

@@ -97,17 +97,27 @@ exports.mostListened = function (filter, callback) {
} }
}, { $match: { "album.visibility": { $in: filter } } }); }, { $match: { "album.visibility": { $in: filter } } });
} else { } else {
aggregate.unshift({ $match: { type: 'track' } }); dbo.collection("history")
} .find()
aggregate.push({ $sort: { counter: -1, _id: -1 } }, { $limit: 6 }) .project({ _id: true })
.sort({ _id: -1 })
.limit(1000)
.toArray((err, ids) => {
let arr = ids.map(h => h._id);
aggregate.unshift({ $match: { type: 'track', _id: { $in: arr } } });
aggregate.push({ $sort: { counter: -1 } }, { $limit: 6 })
dbo
.collection("history")
.aggregate(aggregate, {
allowDiskUse: true
})
.toArray((err, result) => {
if (err) throw err;
callback(result);
});
});
}
dbo
.collection("history")
.aggregate(aggregate, {
allowDiskUse: true
})
.toArray((err, result) => {
if (err) throw err;
callback(result);
});
}; };