mirror of
https://github.com/IrosTheBeggar/mStream.git
synced 2025-10-27 07:31:02 +00:00
271 lines
8.3 KiB
JavaScript
271 lines
8.3 KiB
JavaScript
const sqlite3 = require('sqlite3').verbose();
|
|
const slash = require('slash');
|
|
const fe = require('path');
|
|
const crypto = require('crypto');
|
|
|
|
var db;
|
|
|
|
// function that takes in a json array of songs and saves them to the sqlite db
|
|
// must contain the username and filepath for each song
|
|
|
|
// function that gets artist info and returns json array of albums
|
|
// function that searches db and returns json array of albums and artists
|
|
// function that takes ina playlist name and searchs db for that playlist and returns a json array of songs for that playlist
|
|
// BASICALLY, all the functions we have no but de-couple them from the Express API calls
|
|
|
|
|
|
// TODO: TODO: TODO: TODO: TODO: TODO: TODO: TODO: TODO: TODO: TODO: TODO:
|
|
// TODO: Pass in user music dir and compare it to the path using LIKE
|
|
// This way If the user is set to use a sub folder of the DB folder, we can ignore all folders above what the user has permission for
|
|
|
|
|
|
function getFileType(filename){
|
|
return filename.split(".").pop();
|
|
}
|
|
|
|
exports.getNumberOfFiles = function(username, callback){
|
|
db.get("SELECT Count(*) FROM items;", function(err, row){
|
|
callback(row['Count(*)']);
|
|
});
|
|
}
|
|
|
|
|
|
exports.setup = function(mstream, dbSettings){
|
|
db = new sqlite3.Database(dbSettings.dbPath);
|
|
|
|
|
|
// Create a playlist table
|
|
db.run("CREATE TABLE IF NOT EXISTS mstream_playlists ( id INTEGER PRIMARY KEY AUTOINCREMENT, playlist_name varchar, filepath varchar, hide int DEFAULT 0, user VARCHAR, created datetime default current_timestamp);", function() {
|
|
});
|
|
|
|
|
|
|
|
// TODO: This needs to be tested to see if it works on extra large playlists (think thousands of entries)
|
|
// TODO: Ban saving playlists that are > 10,000 items long
|
|
mstream.post('/saveplaylist', function (req, res){
|
|
var title = req.body.title;
|
|
var songs = req.body.stuff;
|
|
|
|
// Check if this playlist already exists
|
|
db.all("SELECT id FROM mstream_playlists WHERE playlist_name = ?", [title], function(err, rows) {
|
|
|
|
db.serialize(function() {
|
|
|
|
// We need to delete anys existing entries
|
|
if(rows && rows.length > 0){
|
|
db.run("DELETE FROM mstream_playlists WHERE playlist_name = ?;", [title]);
|
|
}
|
|
|
|
// Now we add the new entries
|
|
var sql2 = "insert into mstream_playlists (playlist_name, filepath) values ";
|
|
var sqlParser = [];
|
|
|
|
while(songs.length > 0) {
|
|
var song = songs.shift();
|
|
|
|
sql2 += "(?, ?), ";
|
|
sqlParser.push(title);
|
|
// TODO: We need to strip out the vPath
|
|
// We need to allow pre-set vPaths in the config file
|
|
// Then strip out the vPath here
|
|
sqlParser.push( fe.join(req.user.musicDir, song) );
|
|
|
|
}
|
|
|
|
sql2 = sql2.slice(0, -2);
|
|
sql2 += ";";
|
|
|
|
db.run(sql2, sqlParser, function(){
|
|
res.send('DONE');
|
|
});
|
|
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
// Attach API calls to functions
|
|
mstream.get('/getallplaylists', function (req, res){
|
|
// TODO: In V2 we need to change this to ignore hidden playlists
|
|
// TODO: db.all("SELECT DISTINCT playlist_name FROM mstream_playlists WHERE hide=0;", function(err, rows){
|
|
db.all("SELECT DISTINCT playlist_name FROM mstream_playlists", function(err, rows){
|
|
var playlists = [];
|
|
|
|
// loop through files
|
|
for (var i = 0; i < rows.length; i++) {
|
|
if(rows[i].playlist_name){
|
|
playlists.push({name: rows[i].playlist_name});
|
|
}
|
|
}
|
|
|
|
res.send(JSON.stringify(playlists));
|
|
});
|
|
});
|
|
mstream.get('/loadplaylist', function (req, res){
|
|
var playlist = req.query.playlistname;
|
|
|
|
db.all("SELECT * FROM mstream_playlists WHERE playlist_name = ? ORDER BY id COLLATE NOCASE ASC", [playlist], function(err, rows){
|
|
var returnThis = [];
|
|
|
|
for (var i = 0; i < rows.length; i++) {
|
|
|
|
// var tempName = rows[i].filepath.split('/').slice(-1)[0];
|
|
var tempName = fe.basename(rows[i].filepath);
|
|
var extension = getFileType(rows[i].filepath);
|
|
var filepath = slash(fe.relative(req.user.musicDir, rows[i].filepath));
|
|
console.log(filepath);
|
|
returnThis.push({name: tempName, file: filepath, filetype: extension });
|
|
}
|
|
|
|
res.send(JSON.stringify(returnThis));
|
|
});
|
|
});
|
|
mstream.get('/deleteplaylist', function(req, res){
|
|
var playlistname = req.query.playlistname;
|
|
|
|
// Handle a soft delete
|
|
if(req.query.hide && parseInt(req.query.hide) === 1 ){
|
|
db.run("UPDATE mstream_playlists SET hide = 1 WHERE playlist_name = ?;", [playlistname], function(){
|
|
res.send('DONE');
|
|
|
|
});
|
|
}else{ // Permentaly delete
|
|
|
|
// Delete playlist from DB
|
|
db.run("DELETE FROM mstream_playlists WHERE playlist_name = ?;", [playlistname], function(){
|
|
res.send('DONE');
|
|
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
mstream.post('/db/search', function(req, res){
|
|
var searchTerm = "%" + req.body.search + "%" ;
|
|
|
|
var returnThis = {"albums":[], "artists":[]};
|
|
|
|
// TODO: Combine SQL calls into one
|
|
db.serialize(function() {
|
|
|
|
var sqlAlbum = "SELECT DISTINCT album FROM items WHERE items.album LIKE ? ORDER BY album COLLATE NOCASE ASC;";
|
|
db.all(sqlAlbum, [searchTerm], function(err, rows) {
|
|
if(err){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < rows.length; i++) {
|
|
if(rows[i].album){
|
|
returnThis.albums.push(rows[i].album);
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
var sqlArtist = "SELECT DISTINCT artist FROM items WHERE items.artist LIKE ? ORDER BY artist COLLATE NOCASE ASC;";
|
|
db.all(sqlArtist, [searchTerm], function(err, rows) {
|
|
if(err){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < rows.length; i++) {
|
|
if(rows[i].artist){
|
|
returnThis.artists.push(rows[i].artist);
|
|
}
|
|
}
|
|
|
|
res.send(JSON.stringify(returnThis));
|
|
});
|
|
});
|
|
});
|
|
|
|
mstream.get('/db/artists', function (req, res) {
|
|
var artists = {"artists":[]};
|
|
|
|
var sql = "SELECT DISTINCT artist FROM items ORDER BY artist COLLATE NOCASE ASC;";
|
|
db.all(sql, function(err, rows) {
|
|
if(err){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
var returnArray = [];
|
|
for (var i = 0; i < rows.length; i++) {
|
|
if(rows[i].artist){
|
|
// rows.splice(i, 1);
|
|
artists.artists.push(rows[i].artist);
|
|
}
|
|
}
|
|
|
|
res.send(JSON.stringify(artists));
|
|
});
|
|
});
|
|
|
|
mstream.post('/db/artists-albums', function (req, res) {
|
|
var albums = {"albums":[]};
|
|
|
|
// TODO: Make a list of all songs without null albums and add them to the response
|
|
var sql = "SELECT DISTINCT album FROM items WHERE artist = ? ORDER BY album COLLATE NOCASE ASC;";
|
|
db.all(sql, [req.body.artist], function(err, rows) {
|
|
if(err){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
var returnArray = [];
|
|
for (var i = 0; i < rows.length; i++) {
|
|
if(rows[i].album){
|
|
albums.albums.push(rows[i].album);
|
|
}
|
|
}
|
|
|
|
res.send(JSON.stringify(albums));
|
|
});
|
|
});
|
|
|
|
mstream.get('/db/albums', function (req, res) {
|
|
var albums = {"albums":[]};
|
|
|
|
var sql = "SELECT DISTINCT album FROM items ORDER BY album COLLATE NOCASE ASC;";
|
|
db.all(sql, function(err, rows) {
|
|
if(err){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
var returnArray = [];
|
|
for (var i = 0; i < rows.length; i++) {
|
|
if(rows[i].album){
|
|
albums.albums.push(rows[i].album);
|
|
}
|
|
}
|
|
|
|
res.send(JSON.stringify(albums));
|
|
});
|
|
});
|
|
|
|
mstream.post('/db/album-songs', function (req, res) {
|
|
var sql = "SELECT title, artist, album, format, year, cast(path as TEXT), track FROM items WHERE album = ? ORDER BY track ASC;";
|
|
db.all(sql, [req.body.album], function(err, rows) {
|
|
if(err){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
// Format data for API
|
|
for(var i in rows ){
|
|
var path = String(rows[i]['cast(path as TEXT)']);
|
|
|
|
rows[i].format = rows[i].format.toLowerCase(); // make sure the format is lowecase
|
|
rows[i].file_location = slash(fe.relative(req.user.musicDir, path)); // Get the local file location
|
|
rows[i].filename = fe.basename( path ); // Ge the filname
|
|
}
|
|
|
|
res.send(JSON.stringify(rows));
|
|
});
|
|
});
|
|
|
|
}
|