const redis = require("../redis") const { ObjectId } = require('mongodb'); const connector = require("./CONNECTOR"); var dbo; connector.connect().then((ret) => { dbo = ret; dbo.collection("albums").createIndex({ artist_name: 1, year: 1, title: 1 }); // TEMPORARY dbo.collection("albums").updateMany({}, { $unset: { cover32: 1, cover64: 1, cover128: 1, cover256: 1, cover512: 1 } }); updateArtistName(); }); function updateArtistName() { dbo.collection("albums") .find({ artist_name: undefined }) .toArray((err, result) => { result.forEach(item => { dbo.collection("artists") .findOne({ _id: item.artist_id }) .then(artist => { if (artist) { dbo.collection("albums") .updateOne( { _id: item._id }, { $set: { artist_id: artist._id, artist_name: artist.name } }, { upsert: false }); } }); }) }); } exports.collection = function (page, filter, callback) { process.stdout.write("services/db_manager ALBUMS Collection: " + page + "\n"); let redis_key = "albumsCollection_" + (filter || '') + '_' + page; redis.get(redis_key, (value) => { if (value) { process.stdout.write("services/db_manager ALBUMS Collection REDIS: " + page + "\n"); callback(value); } else { let aggregate = [ { $project: { "covers.cover256": false, "covers.cover64": false, "covers.cover32": false } }, { $match: { visibility: { $not: { $eq: 'hidden' } } } }, { $sort: { artist_name: 1, year: 1, title: 1 } }, ]; if (filter) { aggregate.push({ $match: { visibility: { $in: filter } } }); } if (page > -1) { let pageSize = 12; let skip = (page - 1) * pageSize; aggregate.push( { $skip: skip }, { $limit: pageSize }); } dbo .collection("albums") .aggregate(aggregate, { allowDiskUse: true }) .toArray((err, result) => { if (err) throw err; if (result) { result.forEach(album => { album.type = "album"; album.tracks = []; album.share = {}; }); } process.stdout.write("services/db_manager ALBUMS Collection MONGO: " + page + "\n"); callback(result); redis.set(redis_key, result); }); } }); }; exports.favourites = function (id, callback) { dbo.collection("favourites") .find({ userId: id, type: "album" }) .toArray((err, favourites) => { if (err) throw err; let aggregate = [ { $match: { _id: { $in: favourites.map(m => m.itemId) } } }, { $project: { "covers.cover256": false, "covers.cover64": false, "covers.cover32": false } }, ] dbo.collection("albums") .aggregate(aggregate) .toArray((err, result) => { result.forEach(album => { album.type = "album"; album.tracks = []; }); callback(result); }); }) }; exports.newest = function (count, filter, callback) { let aggregate = [ { $project: { "covers.cover256": false, "covers.cover128": false, "covers.cover32": false } }, { $match: { visibility: { $not: { $eq: 'hidden' } } } }, { $sort: { _id: -1 } }, ]; if (filter) { aggregate.push({ $match: { visibility: { $in: filter } } }); } aggregate.push({ $limit: count }) dbo .collection("albums") .aggregate(aggregate, { allowDiskUse: true }) .toArray((err, result) => { if (err) throw err; if (result) { result.forEach(album => { album.type = "album"; album.tracks = []; }); } callback(result); }); }; exports.byId = function (id, filter, callback) { process.stdout.write("services/db_manager ALBUM by id: " + id + "\n"); let redis_key = "albumId_" + (filter || '') + '_' + id; redis.get(redis_key, (value) => { if (value) { process.stdout.write("services/db_manager ALBUM by id REDIS: " + id + "\n"); callback(value); } else { let aggregate = [ { $lookup: { from: "tracks", localField: "_id", foreignField: "album_id", as: "tracks" } }, { $lookup: { from: "shares", localField: "_id", foreignField: "object_id", as: "share" } }, { $match: { _id: ObjectId(id) } } ] if (filter) { aggregate.push({ $match: { visibility: { $in: filter } } }); } dbo .collection("albums") .aggregate(aggregate) .toArray((err, result) => { if (err) throw err; if (result) { result.forEach(album => { album.type = "album"; if (album.share.length > 0) { album.share = album.share[0]; } else { album.share = {}; } }); } process.stdout.write("services/db_manager ALBUM by id MONGO: " + id + "\n"); callback(result[0]); redis.set(redis_key, result[0]); }); } }); }; exports.filter = function (term, callback) { let aggregate = [ { $project: { 'parent.covers': false, 'covers.cover32': false, 'covers.cover256': false } }, { $match: { title: { $regex: term, $options: "i" } }, }, { $limit: 6 } ] dbo .collection("albums") .aggregate(aggregate) .toArray((err, result) => { if (err) throw err; callback(result); }); }; exports.tracks = function (id, callback) { process.stdout.write("services/db_manager TRACKS by id: " + id + "\n"); let request = [ { $lookup: { from: "tracks", localField: "_id", foreignField: "album_id", as: "tracks" } }, { $match: { _id: ObjectId(id) } } ]; dbo .collection("albums") .aggregate(request) .toArray((err, result) => { if (result) { callback(result[0]); } else { if (err) { process.stderr("services/db_manager ALBUM by id ERROR: " + err.message); } callback(null); } }); }; exports.delete = function (album, callback) { dbo.collection("albums") .deleteOne({ _id: ObjectId(album._id) }, err => { if (err) throw err; if (callback) { callback(); } }); }; exports.update = function (album, callback) { dbo.collection("albums") .updateOne( { _id: ObjectId(album._id) }, { $set: { visibility: album.visibility } }, { upsert: false }, err => { if (err) throw err; if (callback) { callback(); } } ); } exports.updateCovers = function (album, covers, callback) { dbo.collection("albums") .updateOne( { _id: ObjectId(album._id) }, { $set: { covers: covers } }, { upsert: false }, err => { if (err) throw err; if (callback) { callback(); } } ); }; exports.moveTo = function (album, callback) { process.stdout.write("services/db_manager ALBUM '" + album._id + "' move to '" + album.artist_id + "'\n"); dbo .collection("albums") .updateOne( { _id: ObjectId(album._id) }, { $set: { artist_id: ObjectId(album.artist_id), artist_name: album.artist_name } }, { upsert: false }, err => { if (err) throw err; if (callback) { callback(); } }); }; exports.empty = function (callback) { dbo .collection("albums") .aggregate([ { $lookup: { from: "tracks", localField: "_id", foreignField: "album_id", as: "tracks" } } ]) .toArray((err, result) => { 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); }