mirror of
https://github.com/IrosTheBeggar/mStream.git
synced 2025-10-27 07:31:02 +00:00
324 lines
9.4 KiB
JavaScript
324 lines
9.4 KiB
JavaScript
const sqlite3 = require('sqlite3').verbose();
|
|
const slash = require('slash');
|
|
const fe = require('path');
|
|
const crypto = require('crypto');
|
|
|
|
var db;
|
|
|
|
|
|
function getFileType(filename){
|
|
return filename.split(".").pop();
|
|
}
|
|
|
|
exports.getNumberOfFiles = function(username, callback){
|
|
db.get("SELECT Count(*) FROM items WHERE user = ?;", [username], function(err, row){
|
|
callback(row['Count(*)']);
|
|
});
|
|
}
|
|
|
|
exports.setup = function (mstream, dbSettings){
|
|
db = new sqlite3.Database(dbSettings.dbPath);
|
|
|
|
// Setup DB
|
|
// TODO: Add the following cols
|
|
// rating
|
|
var itemsSql = "CREATE TABLE IF NOT EXISTS items ( \
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT, \
|
|
title varchar DEFAULT NULL, \
|
|
artist varchar DEFAULT NULL, \
|
|
year int DEFAULT NULL, \
|
|
album varchar DEFAULT NULL, \
|
|
path TEXT NOT NULL, \
|
|
format VARCHAR, \
|
|
track INTEGER, \
|
|
disk INTEGER, \
|
|
user VARCHAR, \
|
|
filesize INTEGER, \
|
|
file_created_date INTEGER, \
|
|
file_modified_date INTEGER, \
|
|
hash VARCHAR, \
|
|
album_art_file TEXT, \
|
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP \
|
|
);";
|
|
|
|
var playlistSql = "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 \
|
|
);";
|
|
|
|
// Create tables
|
|
db.run(itemsSql, function() {});
|
|
db.run(playlistSql, function() {});
|
|
|
|
|
|
// Finish and test this
|
|
mstream.post('/db/metadata', function (req, res){
|
|
var relativePath = req.body.filepath;
|
|
var fullpath = fe.join(req.user.musicDir, relativePath);
|
|
|
|
// Find entry matching path
|
|
db.get("SELECT * FROM items WHERE path = ?", [fullpath], function(err, row){
|
|
if(err || !row){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
// Return metadata
|
|
res.json({
|
|
"filepath":relativePath,
|
|
"metadata":{
|
|
"artist":row.artist,
|
|
"album":row.album,
|
|
"track":row.track,
|
|
"title":row.title,
|
|
"year":row.year,
|
|
"album-art":row.album_art_file
|
|
}
|
|
});
|
|
|
|
});
|
|
});
|
|
|
|
|
|
// 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('/playlist/save', function (req, res){
|
|
var title = req.body.title;
|
|
var songs = req.body.songs;
|
|
|
|
// Check if this playlist already exists
|
|
db.all("SELECT id FROM mstream_playlists WHERE playlist_name = ? AND user = ?;", [title, req.user.username], 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 = ? AND user = ?;", [title, req.user.username]);
|
|
}
|
|
|
|
// Now we add the new entries
|
|
var sql2 = "insert into mstream_playlists (playlist_name, filepath, user) values ";
|
|
var sqlParser = [];
|
|
|
|
while(songs.length > 0) {
|
|
var song = songs.shift();
|
|
|
|
sql2 += "(?, ?, ?), ";
|
|
sqlParser.push(title);
|
|
sqlParser.push( fe.join(req.user.musicDir, song) );
|
|
sqlParser.push( req.user.username );
|
|
}
|
|
|
|
sql2 = sql2.slice(0, -2);
|
|
sql2 += ";";
|
|
|
|
db.run(sql2, sqlParser, function(){
|
|
res.json({success: true});
|
|
});
|
|
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
// Attach API calls to functions
|
|
mstream.get('/playlist/getall', 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 WHERE user = ?", [req.user.username], 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.json(playlists);
|
|
});
|
|
});
|
|
|
|
mstream.post('/playlist/load', function (req, res){
|
|
var playlist = req.body.playlistname;
|
|
|
|
db.all("SELECT * FROM mstream_playlists WHERE playlist_name = ? AND user = ? ORDER BY id COLLATE NOCASE ASC", [playlist, req.user.username], 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)); // TODO
|
|
returnThis.push({filepath: filepath, metadata:'' });
|
|
}
|
|
|
|
res.json(returnThis);
|
|
});
|
|
});
|
|
mstream.post('/playlist/delete', function(req, res){
|
|
var playlistname = req.body.playlistname;
|
|
|
|
// Handle a soft delete
|
|
if(req.body.hide && parseInt(req.body.hide) == true ){
|
|
db.run("UPDATE mstream_playlists SET hide = 1 WHERE playlist_name = ? AND user = ?;", [playlistname, req.user.username], function(){
|
|
res.json({success: true});
|
|
});
|
|
}else{
|
|
// Delete playlist from DB
|
|
db.run("DELETE FROM mstream_playlists WHERE playlist_name = ? AND user = ?;", [playlistname, req.user.username], function(){
|
|
res.json({success: true});
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
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 ? AND user = ? ORDER BY album COLLATE NOCASE ASC;";
|
|
db.all(sqlAlbum, [searchTerm, req.user.username], 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 ? AND user = ? ORDER BY artist COLLATE NOCASE ASC;";
|
|
db.all(sqlArtist, [searchTerm, req.user.username], 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.json(returnThis);
|
|
});
|
|
});
|
|
});
|
|
|
|
mstream.get('/db/artists', function (req, res) {
|
|
var artists = {"artists":[]};
|
|
|
|
var sql = "SELECT DISTINCT artist FROM items WHERE user = ? ORDER BY artist COLLATE NOCASE ASC;";
|
|
db.all(sql, [req.user.username], 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){
|
|
artists.artists.push(rows[i].artist);
|
|
}
|
|
}
|
|
|
|
res.json(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 = ? AND user = ? ORDER BY album COLLATE NOCASE ASC;";
|
|
var searchTerms = [];
|
|
searchTerms.push(req.body.artist);
|
|
searchTerms.push(req.user.username);
|
|
|
|
db.all(sql, searchTerms, 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.json(albums);
|
|
});
|
|
});
|
|
|
|
mstream.get('/db/albums', function (req, res) {
|
|
var albums = {"albums":[]};
|
|
|
|
var sql = "SELECT DISTINCT album FROM items WHERE user = ? ORDER BY album COLLATE NOCASE ASC;";
|
|
db.all(sql, req.user.username, 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(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 = ? AND user = ? ORDER BY track ASC;";
|
|
var searchTerms = [];
|
|
searchTerms.push(req.body.album);
|
|
searchTerms.push(req.user.username);
|
|
|
|
db.all(sql, searchTerms, function(err, rows) {
|
|
if(err){
|
|
res.status(500).json({ error: 'DB Error' });
|
|
return;
|
|
}
|
|
|
|
var songs = [];
|
|
// Format data for API
|
|
for(var i in rows ){
|
|
var path = String(rows[i]['cast(path as TEXT)']);
|
|
|
|
songs.push({
|
|
"filepath": slash(fe.relative(req.user.musicDir, path)),
|
|
"metadata": {
|
|
"artist": rows[i].artist,
|
|
"album": rows[i].album,
|
|
"track": rows[i].track,
|
|
"title": rows[i].title,
|
|
"year": rows[i].year,
|
|
"album-art": rows[i].album_art_file,
|
|
"filename": fe.basename( path )
|
|
}
|
|
})
|
|
}
|
|
|
|
res.json(songs);
|
|
});
|
|
});
|
|
|
|
}
|