server/services/tag_excluder.js

263 lines
7.0 KiB
JavaScript

var path = require("path");
var notifier = require("./notifier");
var meta_data = require("music-metadata");
var db_manager = require("./database");
var server = require("../server");
var config = server.config;
var music_files_data = [];
var music_files_cover = [];
var parsing_music_data = 0;
var parsing_cover = 0;
var video_files_data = [];
var parsing_video_data = 0;
var exclude_meta_cover_is_running = false;
var exclude_meta_data_is_running = false;
var exclude_path_data_is_running = false;
var sleep_dur = 10;
exports.parsing_music_data = function() {
return parsing_music_data;
};
exports.parsing_video_data = function() {
return parsing_video_data;
};
exports.parsing_cover = function() {
return parsing_cover;
};
var music_timeout_handler_data;
var music_timeout_handler_cover;
var video_timeout_handler_data;
exports.get_buffer_size = () => {
return music_files_data.length;
};
notifier.on("music_file_found", file => {
music_files_data.push(file);
if (music_timeout_handler_data) {
clearTimeout(music_timeout_handler_data);
}
music_timeout_handler_data = setTimeout(exclude_meta_data, 1000);
});
notifier.on("album_cover_request", track => {
music_files_cover.push(track);
if (music_timeout_handler_cover) {
clearTimeout(music_timeout_handler_cover);
}
music_timeout_handler_cover = setTimeout(exclude_meta_cover, 1000);
});
async function exclude_meta_data() {
if (exclude_meta_data_is_running) {
return;
}
process.stdout.write("Start excluding meta data...\n");
exclude_meta_data_is_running = true;
while (music_files_data && music_files_data.length > 0) {
while (parsing_music_data >= 1) {
await sleep(sleep_dur);
}
parsing_music_data++;
let file = music_files_data.shift();
if (!file) {
parsing_music_data--;
continue;
}
db_manager.tracks.exists(file.path, exists => {
if (exists) {
parsing_music_data--;
} else {
let options = {
skipCovers: true,
skipPostHeaders: true,
duration: true
};
meta_data
.parseFile(file.path, options)
.then(meta => {
let title = (meta.common.title || "").trim();
let album = (meta.common.album || "").trim();
let artist = (
meta.common.albumartist ||
meta.common.artist ||
""
).trim();
if (title == "") {
let ext = path.extname(file.path);
title = path.basename(file.path, ext);
}
if (album == "") {
let dir = path.dirname(file.path);
album = path.basename(dir);
}
let item = {
path: file.path,
artist: artist,
album: album,
title: title,
duration: meta.format.duration,
bitrate: meta.format.bitrate,
mime: file.mime,
year: meta.common.year,
track: meta.common.track,
disk: meta.common.disk,
genre: meta.common.genre
};
notifier.emit("metadata_excluded", item);
parsing_music_data--;
})
.catch(err => {
process.stdout.write(file.path);
console.log(err);
parsing_music_data--;
});
}
});
}
process.stdout.write("End excluding meta data...\n");
exclude_meta_data_is_running = false;
notifier.emit("exclude_metadata_finished");
}
async function exclude_meta_cover() {
if (exclude_meta_cover_is_running) {
return;
}
process.stdout.write("Start excluding meta COVER...\n");
exclude_meta_cover_is_running = true;
while (music_files_cover && music_files_cover.length > 0) {
while (parsing_cover >= server.config.cpu_cores) {
await sleep(50);
}
parsing_cover++;
let track = music_files_cover.shift();
if (!track) {
parsing_cover--;
process.stdout.write("file is null");
continue;
}
let path = config.music_folder + track.path;
meta_data
.parseFile(path)
.then(meta => {
parsing_cover--;
if (meta.common.picture) {
track.parent.picture = meta.common.picture;
notifier.emit("metadata_picture_excluded", track.parent);
} else {
notifier.emit("no_metadata_picture_excluded", track.parent);
}
})
.catch(err => {
music_files_cover.splice(0, 1);
parsing_cover--;
notifier.emit("no_metadata_picture_excluded", track.parent);
console.log(err);
});
}
exclude_meta_cover_is_running = false;
process.stdout.write("End excluding meta COVER...\n");
notifier.emit("exclude_metacover_finished");
}
notifier.on("video_file_found", file => {
video_files_data.push(file);
if (video_timeout_handler_data) {
clearTimeout(video_timeout_handler_data);
}
video_timeout_handler_data = setTimeout(exclude_path_data, 1000);
});
async function exclude_path_data() {
if (exclude_path_data_is_running) {
return;
}
process.stdout.write("Start excluding path data...\n");
exclude_path_data_is_running = true;
while (video_files_data && video_files_data.length > 0) {
while (parsing_video_data >= 1) {
await sleep(sleep_dur);
}
parsing_video_data++;
let video = video_files_data.shift();
if (!video) {
parsing_video_data--;
continue;
}
let file_path = video.path;
db_manager.videos.exists(file_path, exists => {
if (exists) {
parsing_video_data--;
if (!exists.thumbnail || !exists.tracks) {
notifier.emit("check_video_details", exists);
}
} else {
let dir = path.dirname(file_path);
let box = path.basename(dir).trim();
let year = 0;
let regex_year = /\s?\([12]\d\d\d\)$/g;
let regex_season = /^seasons?\s*\d+$/gi;
let result = regex_season.exec(box);
if (result) {
let season_dir = path.dirname(dir);
let parent = path.basename(season_dir);
box = parent + " - " + box;
} else {
process.stdout.write("check box title: " + box + "\n");
result = regex_year.exec(box);
if (result) {
box = box.replace(result[0], "");
year = result[0]
.replace("(", "")
.replace(")", "")
.trim();
}
}
let ext = path.extname(file_path);
let title = path.basename(file_path, ext);
let item = {
path: file_path,
box: box,
box_path: dir,
title: title,
mime: video.mime,
year: year
};
notifier.emit("pathdata_excluded", item);
parsing_video_data--;
}
});
}
process.stdout.write("End excluding path data...\n");
exclude_path_data_is_running = false;
notifier.emit("exclude_pathdata_finished");
}
function sleep(milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}