diff --git a/classes/Queue.js b/classes/Queue.js index b8eaad8..2ea4b04 100644 --- a/classes/Queue.js +++ b/classes/Queue.js @@ -1,5 +1,6 @@ const metadata = require('../libs/metadata.js'); -const ext = require('path').extname; +const { md5 } = require('../libs/util.js'); +const { extname } = require('path'); class Queue { @@ -10,7 +11,7 @@ class Queue { } add(event, file, stats) { - if (file === undefined || !this.filter.includes(ext(file))) { + if (file === undefined || !this.filter.includes(extname(file))) { return; } const element = { file: file }; @@ -73,10 +74,14 @@ class Queue { if (file === undefined) { return; } + const hash = await md5(file); + if (! await this.fileChanged(file, hash)) { + return; + } const tags = await metadata.parseFile(file); const artist = await this.addArtist(tags); const album = await this.addAlbum(tags); - const track = await this.addTrack(tags, file); + const track = await this.addTrack(tags, file, hash); this.linkTrackToArtist(track, artist); this.linkTrackToAlbum(track, album); this.linkAlbumToArtist(album, artist); @@ -101,6 +106,29 @@ class Queue { } } + async fileChanged(file, hash) { + if (file === undefined) { + return; + } + const where = { + file: file + }; + if (hash === undefined) { + hash = await md5(file); + } + if (hash !== undefined) { + where.hash = hash; + } + try { + const element = await database.models.Track.findOne({ + where: where + }); + return element?.id === undefined; + } catch (err) { + logger.error('error finding database entry for file \'' + file + '\' with md5 sum \'' + hash + '\' > ' + err); + } + } + async addArtist(tags) { if (tags?.common?.artist === undefined && tags?.common?.artists === undefined) { return; @@ -145,14 +173,23 @@ class Queue { } } - async addTrack(tags, file) { + async addTrack(tags, file, hash) { if (tags?.common?.title === undefined || file === undefined) { return; } + let timestamp = new Date(); const where = { - file: file, - title: tags.common.title + file: file }; + if (hash === undefined) { + hash = await md5(file); + } + if (hash !== undefined) { + where.hash = hash; + } + if (tags?.common?.title !== undefined) { + where.title = tags.common.title; + } if (tags?.common?.year !== undefined) { where.year = tags.common.year; } diff --git a/docker/.dockerignore b/docker/.dockerignore index 412c257..209b637 100644 --- a/docker/.dockerignore +++ b/docker/.dockerignore @@ -1 +1,2 @@ -docker-compose.yml \ No newline at end of file +docker-compose.yml +*.json \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e7bbda9..9715b10 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -18,4 +18,4 @@ services: - 3001:3001 - 3002:3002 volumes: - - /path/to/library:/mnt/library \ No newline at end of file + - /mnt/samsung/music:/mnt/library \ No newline at end of file diff --git a/docker/docker_config.json b/docker/docker_config.json index fffec33..9febbb4 100644 --- a/docker/docker_config.json +++ b/docker/docker_config.json @@ -17,7 +17,7 @@ "library": { "enabled": true, "sources": [ - "/mnt/library" + "/mnt/samsung/music" ], "formats": [ "mp3", @@ -38,4 +38,4 @@ "nodelay": false, "threshold": 10 } - } \ No newline at end of file + } diff --git a/libs/util.js b/libs/util.js index 7132429..385439e 100644 --- a/libs/util.js +++ b/libs/util.js @@ -1,3 +1,6 @@ +const crypto = require('crypto'); +const { open } = require('fs/promises'); + function isEnabled(parameter) { return isSet(parameter?.enabled) && parameter.enabled === true; } @@ -23,10 +26,34 @@ async function sleep(ms) { }); } +async function md5(file) { + if (file === undefined) { + return; + } + let buffer; + let filehandle; + try { + filehandle = await open(file); + buffer = await filehandle.readFile(); + } catch (error) { + logger.error('encountered an error generating the md5 hash sum for file \'' + file + '\' > ' + error); + } finally { + await filehandle?.close(); + } + if (buffer === undefined) { + return; + } + let md5 = crypto.createHash('md5'); + md5.update(buffer); + md5 = md5.digest('hex'); + return md5; +} + module.exports = { isEnabled, isDisabled, isSet, isUnset, - sleep + sleep, + md5 } \ No newline at end of file diff --git a/models/Track.js b/models/Track.js index 0865111..6d737ba 100644 --- a/models/Track.js +++ b/models/Track.js @@ -9,7 +9,8 @@ const Track = database.connection.define("track", { diskof: DataTypes.INTEGER, trackno: DataTypes.INTEGER, trackof: DataTypes.INTEGER, - file: DataTypes.TEXT + file: DataTypes.TEXT, + hash: DataTypes.TEXT }); module.exports = Track; \ No newline at end of file