fix(validation): prevent overwriting files with same artist and title by generating unique filenames

- Implement generateUniqueFilename to ensure each file is saved with a unique name

These changes address the issue when two or more different songs by the same artist and with the same title overwrite each other
This commit is contained in:
xtrullor73
2024-05-27 16:06:51 -07:00
parent f63bab30f0
commit 91a56e0ff7
2 changed files with 34 additions and 3 deletions

View File

@@ -0,0 +1,28 @@
import fs from 'fs/promises';
import path from 'path';
/**
* Generates a unique filename based on the original filename, ensuring it doesn't overwrite existing files.
* @param {string} directory - The directory to save the downloaded image.
* @param {string} filename - The original filename.
* @returns {Promise<string>} - A promise that resolves to a unique filename.
*/
const generateUniqueFilename = async (directory, filename) => {
const extension = path.extname(filename);
const basename = path.basename(filename, extension);
let counter = 1;
let uniqueFilename = filename;
let filePath = path.join(directory, uniqueFilename);
// Check if the file exists and append a counter to make it unique
while (await fs.stat(filePath).catch(() => false)) {
uniqueFilename = `${basename} (${counter})${extension}`;
filePath = path.join(directory, uniqueFilename);
counter += 1;
}
return filePath;
};
export default generateUniqueFilename;

View File

@@ -1,5 +1,6 @@
import path from 'path';
import fs from 'fs/promises';
import generateUniqueFilename from '../utils/generateUniqueFilename.js';
/**
* Renames an audio file by its metadata properties: artist and title.
@@ -13,13 +14,15 @@ import fs from 'fs/promises';
export default async function renameFile(artist, title, filePath) {
// Ensure file path, artist, and title are provided
if (!filePath || !artist || !title) {
throw new Error('File path, artist, and title must be provided.');
throw new Error('File path, artist, and title must be provided when renaming file.');
}
const ext = path.extname(filePath);
const dir = path.dirname(filePath);
const newFileName = `${artist} - ${title}${ext}`;
const newFilePath = path.join(dir, newFileName);
const proposedFileName = `${artist} - ${title}${ext}`;
// Generate a unique filename to avoid overwriting
const newFilePath = await generateUniqueFilename(dir, proposedFileName);
try {
await fs.rename(filePath, newFilePath);