kannon/classes/Queue.js

195 lines
6 KiB
JavaScript
Raw Normal View History

2022-04-14 14:23:41 +02:00
const metadata = require('../libs/metadata.js');
2022-06-02 15:27:43 +02:00
const { extname } = require('path');
2022-04-14 14:23:41 +02:00
2022-06-03 17:04:44 +02:00
const Artist = require('../models/Artist.js');
2022-06-15 16:56:38 +02:00
const Album = require('../models/Album.js');
const Track = require('../models/Track.js');
const TrackToArtist = require('../models/TrackToArtist.js');
const TrackToAlbum = require('../models/TrackToAlbum.js');
2022-06-15 16:56:38 +02:00
const AlbumToArtist = require('../models/AlbumToArtist.js');
2022-06-03 17:04:44 +02:00
2022-04-14 14:23:41 +02:00
class Queue {
constructor() {
this.queue = [];
this.filter = this.getFilter();
this.handleQueue();
}
add(event, file, stats) {
2022-06-02 15:27:43 +02:00
if (file === undefined || !this.filter.includes(extname(file))) {
2022-04-14 14:23:41 +02:00
return;
}
const element = { file: file };
switch (event) {
2022-04-21 13:43:33 +02:00
case constants.FS_EVENT_ADD:
element.event = constants.FS_EVENT_ADD;
2022-04-14 14:23:41 +02:00
break;
2022-04-21 13:43:33 +02:00
case constants.FS_EVENT_UNLINK:
element.event = constants.FS_EVENT_UNLINK;
2022-04-14 14:23:41 +02:00
break;
2022-04-21 13:43:33 +02:00
case constants.FS_EVENT_CHANGE:
element.event = constants.FS_EVENT_CHANGE;
2022-04-14 14:23:41 +02:00
break;
default:
return;
}
this.queue.push(element);
}
async handleQueue() {
if (this.queue.length === 0) {
if (this.timeout === undefined) {
this.timeout = 10;
} else {
if (this.timeout > 60000) {
this.timeout = 60000;
} else {
this.timeout += 10;
}
}
logger.debug('queue is currently empty - sleeping for ' + this.timeout + 'ms...');
setTimeout(() => {
this.handleQueue()
}, this.timeout);
return;
}
if (this.timeout !== undefined) {
this.timeout = undefined;
}
const element = this.queue[0];
this.queue.shift();
const timestamp = new Date().getTime();
logger.debug('handling event \'' + element.event + '\' for queued file \'' + element.file + '\'...');
switch (element.event) {
2022-04-21 13:43:33 +02:00
case constants.FS_EVENT_ADD:
2022-04-14 14:23:41 +02:00
await this.eventAdd(element.file);
break;
2022-04-21 13:43:33 +02:00
case constants.FS_EVENT_UNLINK:
2022-04-14 14:23:41 +02:00
await this.eventUnlink(element.file);
break;
2022-04-21 13:43:33 +02:00
case constants.FS_EVENT_CHANGE:
2022-04-14 14:23:41 +02:00
await this.eventChange(element.file);
break;
}
logger.debug('event \'' + element.event + '\' for file \'' + element.file + '\' handled after ' + (new Date().getTime() - timestamp) + 'ms');
this.handleQueue();
}
async eventAdd(file) {
if (file === undefined) {
return;
}
const tags = await metadata.parseFile(file);
2022-06-15 16:56:38 +02:00
const artists = await this.addArtist(tags);
2022-04-14 14:23:41 +02:00
const album = await this.addAlbum(tags);
const track = await this.addTrack(tags, file);
this.linkTrackToArtists(track, artists);
this.linkTrackToAlbum(track, album);
2022-06-15 16:56:38 +02:00
this.linkAlbumToArtists(album, artists);
2022-04-14 14:23:41 +02:00
}
async eventUnlink(file) {
if (file === undefined) {
return;
}
try {
await database.models.Track.destroy({
where: { file: file }
});
} catch (err) {
logger.error(err);
}
}
async eventChange(file) {
if (file === undefined) {
return;
}
2022-06-15 16:56:38 +02:00
let artist = tags.common.artist;
const artists = tags.common.artists || [];
if (artist !== undefined && !artists.includes(artist)) {
artists.push(artist);
}
for (let index = 0; index < artists.length; index++) {
artist = new Artist(artists[index]);
await artist.save();
artists[index] = artist;
}
return artists;
2022-04-14 14:23:41 +02:00
}
async addArtist(tags) {
if (tags?.common?.artist === undefined && tags?.common?.artists === undefined) {
return;
}
let artist = tags.common.artist;
const artists = tags.common.artists || [];
if (artist !== undefined && !artists.includes(artist)) {
artists.push(artist);
}
for (let index = 0; index < artists.length; index++) {
2022-06-03 17:04:44 +02:00
artist = new Artist(artists[index]);
2022-06-15 16:56:38 +02:00
await artist.save();
artists[index] = artist;
2022-04-14 14:23:41 +02:00
}
2022-06-15 16:56:38 +02:00
return artists;
2022-04-14 14:23:41 +02:00
}
async addAlbum(tags) {
if (tags?.common?.album === undefined) {
return;
}
2022-06-15 16:56:38 +02:00
let album = new Album(tags.common.album);
await album.save();
return album;
2022-04-14 14:23:41 +02:00
}
async addTrack(tags, file) {
2022-04-14 14:23:41 +02:00
if (tags?.common?.title === undefined || file === undefined) {
return;
}
2022-06-15 16:56:38 +02:00
let track = new Track(tags, file);
await track.save();
return track;
2022-04-14 14:23:41 +02:00
}
async linkTrackToArtists(track, artists) {
if (track === undefined || artists === undefined || artists.length === 0) {
return;
}
for (let index = 0; index < artists.length; index++) {
await new TrackToArtist(track, artists[index]).save();
}
}
async linkTrackToAlbum(track, album) {
if (track === undefined || album === undefined) {
return;
}
await new TrackToAlbum(track, album).save();
}
2022-06-15 16:56:38 +02:00
async linkAlbumToArtists(album, artists) {
if (album === undefined || artists === undefined || artists.length === 0) {
return;
}
2022-06-15 16:56:38 +02:00
for (let index = 0; index < artists.length; index++) {
await new AlbumToArtist(album, artists[index]).save();
}
}
2022-04-14 14:23:41 +02:00
getFilter() {
let filter = config?.library?.formats || ['.mp3'];
for (let index = 0; index < filter.length; index++) {
if (filter[index].startsWith(".")) {
continue;
}
filter[index] = '.' + filter[index];
}
return filter;
}
}
module.exports = Queue;