Files
MusicMetaFinder-xtrll/cli.js

106 lines
4.3 KiB
JavaScript

#!/usr/bin/env node
import checkEnv from './src/utils/checks/checkEnvVariables.js';
import checkPath from './src/utils/checks/checkInputPath.js';
import fetchFiles from './src/utils/fetchFiles.js';
import validateFiles from './src/services/fileService.js';
import recognizeFiles from './src/services/musicRecognitionService.js';
import retrieveMetadataService from './src/services/metadata/metadataRetrievalService.js';
import normalizeMetadataService from './src/services/metadata/normalizers/metadataNormalizerService.js';
import writeMetadataService from './src/services/metadata/metadataWritingService.js';
import deleteDirectoryRecursively from './src/utils/deleteDirectoryRecursively.js';
import path from 'path';
import { promises as fs } from 'fs';
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
process.exit(1);
});
// Check for required environment variables at the start
checkEnv();
/**
* The main function that serves as the entry point for the CLI tool.
* @param {string} inputPath - The file system path to the audio files to be processed.
* @param {string} [service] - Optional; name of the service to use for audio recognition.
*/
async function main(inputPath, service) {
try {
// Fetch the paths to audio files. This can handle a directory of files or a single file.
const files = await fetchFiles(inputPath);
// Validate the audio files at provided paths. This step checks their format,
// returning a filtered list of valid audio files.
const audioFiles = await validateFiles(files);
// Perform the audio file recognition. This step takes the valid audio files and
// uses an audio recognition service to identify each track, associating it with a unique ID.
const filesWithIds = await recognizeFiles(audioFiles, service);
// Retrieve the metadata for the recognized audio files. This involves fetching
// data such as titles, artists, albums, etc., based on the previously obtained track IDs.
const filesWithMetadata = await retrieveMetadataService(filesWithIds, service);
// Normalize the fetched metadata. Data normalization involves converting all the
// metadata to a standard format or schema, ensuring consistency across all data points.
const normalizedMetadata = await normalizeMetadataService(filesWithMetadata, service);
// Write the normalized metadata into the audio files. This step actually updates each
// audio file with the correct metadata, so it's correctly recognized by media players.
await writeMetadataService(normalizedMetadata);
} finally {
// Define the relative path to the images directory
const imagesDir = './images';
try {
// Check if the images directory exists before attempting to delete it
await fs.access(imagesDir);
await deleteDirectoryRecursively(imagesDir);
console.log('Temporary images directory deleted successfully.');
} catch (err) {
// Handle the error if the directory does not exist or deletion fails
if (err.code !== 'ENOENT') {
console.error('Failed to delete the images directory:', err);
}
}
}
}
/**
* Executes the main functionality of the command-line interface.
*
* This function parses command-line arguments to retrieve the input path and the
* optional service argument. It then passes those arguments to the main function for further processing.
*
* If an error occurs during the execution of the main function or the input path
* validation fails, it catches the error and exits the process with a status code of 1.
*/
function runCli() {
try {
const inputPath = process.argv[[2]];
checkPath(inputPath);
// Optionally selects a service (third CLI argument)
const service = process.argv[[3]] || undefined;
// Invoke the main function with the input path and service
main(inputPath, service).catch((error) => {
console.error('An error occurred:', error.message);
process.exit(1);
});
} catch (error) {
// Log the error message to the console
console.error('An error occurred:', error.message);
// Terminate the process with an error status code
process.exit(1);
}
}
runCli();