From d32fe82ebe2e192763bde26307ce81d0cee09a19 Mon Sep 17 00:00:00 2001 From: Borewit Date: Mon, 10 Jul 2017 16:10:02 +0200 Subject: [PATCH 1/5] Promise based storing and parsing of metadata. File based parsing instead of stream based which in in some cases more efficient. --- .../db-management/database-default-manager.js | 56 ++++++++++--------- modules/db-write/database-default-sqlite.js | 18 ++++-- package.json | 2 +- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/modules/db-management/database-default-manager.js b/modules/db-management/database-default-manager.js index 9502b85..4183c26 100644 --- a/modules/db-management/database-default-manager.js +++ b/modules/db-management/database-default-manager.js @@ -10,7 +10,7 @@ // "albumArtDir": "/album/art/dir" // } -const metadata = require('musicmetadata'); +const metadata = require('music-metadata'); const fs = require('fs'); const fe = require('path'); const crypto = require('crypto'); @@ -133,36 +133,41 @@ function parseFile(thisSong){ return; } - // Stores all data that needs to be added to DB - var songInfo; - - - - var readableStream = fs.createReadStream(thisSong); - var parser = metadata(readableStream, function (err, thisMetadata) { - readableStream.close(); - - if(err){ - // TODO: Do something - } - - songInfo = thisMetadata; - songInfo.filesize = filestat.size; - songInfo.created = filestat.birthtime.getTime(); - songInfo.modified = filestat.mtime.getTime(); - songInfo.filePath = thisSong; - songInfo.format = getFileType(thisSong); + // Parse the file for metadata and store it in the DB + return metadata.parseFile(thisSong).then(function (thisMetadata) { + var songInfo = thisMetadata.common; + songInfo.filesize = filestat.size; + songInfo.created = filestat.birthtime.getTime(); + songInfo.modified = filestat.mtime.getTime(); + songInfo.filePath = thisSong; + songInfo.format = getFileType(thisSong); + return songInfo; + }).catch(function (err) { + console.log("Warning: parsing file '%s': %s", thisSong, err.message); + }).then(function (songInfo) { + // Calculate unique DB ID + return calculateHash(thisSong, songInfo); + }).then(function (songInfo) { + // Stores metadata of song in the database + return dbRead.insertEntries([songInfo], loadJson.username) + }).then(function () { + // Continue with next file + parseFilesGenerator.next(); + }); +} +function calculateHash (thisSong, songInfo) { + return new Promise(function (resolve, reject) { // Handle album art - // TODO: handle cases where multiple images in metadata + // TODO: handle cases where multiple images in metadata var bufferString = false; var picFormat = false; - if(songInfo.picture[0]){ + if (songInfo.picture && songInfo.picture[0]) { bufferString = songInfo.picture[0].data.toString('utf8'); picFormat = songInfo.picture[0].format; // console.log(songInfo.picture); - }else if(false){ // TODO: Check if there is album art in base folder + } else if (false) { // TODO: Check if there is album art in base folder } @@ -189,10 +194,7 @@ function parseFile(thisSong){ } } - //console.log(songInfo); - dbRead.insertEntries([songInfo], loadJson.username, function(){ - parseFilesGenerator.next(); - }); + resolve(songInfo); }); readableStream2.pipe(hash); diff --git a/modules/db-write/database-default-sqlite.js b/modules/db-write/database-default-sqlite.js index ffd2e67..7f5d674 100644 --- a/modules/db-write/database-default-sqlite.js +++ b/modules/db-write/database-default-sqlite.js @@ -19,9 +19,12 @@ exports.getUserFiles = function(thisUser, callback){ }); } - - -exports.insertEntries = function(arrayOfSongs, username, callback){ +/** + * @param arrayOfSongs + * @param username + * @return Promise + */ +exports.insertEntries = function(arrayOfSongs, username){ var sql2 = "insert into items (title,artist,year,album,path,format, track, disk, user, filesize, file_modified_date, file_created_date, hash, album_art_file) values "; var sqlParser = []; @@ -70,8 +73,13 @@ exports.insertEntries = function(arrayOfSongs, username, callback){ sql2 = sql2.slice(0, -2); sql2 += ";"; - db.run(sql2, sqlParser, function() { - callback(); + return new Promise(function(resolve, reject) { + db.run(sql2, sqlParser, function(err) { + if(err) + reject(err); + else + resolve(); + }); }); } diff --git a/package.json b/package.json index 8352d75..db90d47 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "internal-ip": "^1.2.0", "jsonwebtoken": "^7.1.9", "lokijs": "^1.4.3", - "musicmetadata": "^2.0.3", + "music-metadata": "^0.7.4", "nat-upnp": "^1.1.0", "public-ip": "^2.0.1", "slash": "^1.0.0", From a981a87dacefed38523d8ccd14b6e26356d2cda8 Mon Sep 17 00:00:00 2001 From: Borewit Date: Tue, 11 Jul 2017 20:55:47 +0200 Subject: [PATCH 2/5] Avoid catch to cause another error, by passing an undefined result. --- modules/db-management/database-default-manager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/db-management/database-default-manager.js b/modules/db-management/database-default-manager.js index 4183c26..3bf219a 100644 --- a/modules/db-management/database-default-manager.js +++ b/modules/db-management/database-default-manager.js @@ -143,8 +143,6 @@ function parseFile(thisSong){ songInfo.filePath = thisSong; songInfo.format = getFileType(thisSong); return songInfo; - }).catch(function (err) { - console.log("Warning: parsing file '%s': %s", thisSong, err.message); }).then(function (songInfo) { // Calculate unique DB ID return calculateHash(thisSong, songInfo); @@ -154,6 +152,8 @@ function parseFile(thisSong){ }).then(function () { // Continue with next file parseFilesGenerator.next(); + }).catch(function (err) { + console.log("Warning: failed to parse file '%s': %s", thisSong, err.message); }); } From d4ba617f4822ec4ad017328ceb6f4933a3de8011 Mon Sep 17 00:00:00 2001 From: Borewit Date: Tue, 11 Jul 2017 21:00:45 +0200 Subject: [PATCH 3/5] Clarify default user authentication behaviour better. --- docs/cli_arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli_arguments.md b/docs/cli_arguments.md index 9ffb6ac..173a205 100644 --- a/docs/cli_arguments.md +++ b/docs/cli_arguments.md @@ -35,7 +35,7 @@ mstream -c /path/to/cert.pem -k /path/to/key.pem ``` ## User System -mStream can have a single user and guest. If the user is not set mStream will disable to the user system and anyone will be able to access the server +mStream can have a single user and guest. If the user is not set (default behaviour), mStream will permit unrestricted access to the system. ```shell # Set User From dc43c8534122d639d834185fb31a1ac4158f0898 Mon Sep 17 00:00:00 2001 From: Borewit Date: Tue, 8 Aug 2017 19:57:36 +0200 Subject: [PATCH 4/5] Update music-metadata version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db90d47..0102518 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "internal-ip": "^1.2.0", "jsonwebtoken": "^7.1.9", "lokijs": "^1.4.3", - "music-metadata": "^0.7.4", + "music-metadata": "^0.7.10", "nat-upnp": "^1.1.0", "public-ip": "^2.0.1", "slash": "^1.0.0", From 2a27ea91215e2ba4b899c85253588fda088e8cdf Mon Sep 17 00:00:00 2001 From: Borewit Date: Sat, 19 Aug 2017 14:23:15 +0200 Subject: [PATCH 5/5] Update music-metadata to 0.7.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3229d3a..a2fa3d8 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "internal-ip": "^1.2.0", "jsonwebtoken": "^7.1.9", "lokijs": "^1.4.3", - "music-metadata": "^0.7.10", + "music-metadata": "^0.7.14", "nat-upnp": "^1.1.0", "public-ip": "^2.0.1", "sqlite3": "^3.1.4",