Yeah, here's the app
This commit is contained in:
105
app/index.js
Normal file
105
app/index.js
Normal file
@@ -0,0 +1,105 @@
|
||||
require("dotenv").config();
|
||||
|
||||
const fs = require("fs").promises;
|
||||
const fss = require("fs"); // sync fs api
|
||||
const path = require("path");
|
||||
const mm = require("music-metadata");
|
||||
const os = require("os");
|
||||
|
||||
/**
|
||||
* Recursively list all files inside `rootDir`.
|
||||
* - returns an array of absolute file paths
|
||||
* - skips unreadable directories but logs a warning
|
||||
* - follows symlinks that point to files, but skips symlinked directories
|
||||
*/
|
||||
async function listAllFiles(rootDir) {
|
||||
const files = [];
|
||||
const directories = [];
|
||||
|
||||
async function scanDir(dir) {
|
||||
let entries;
|
||||
try {
|
||||
entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
} catch (err) {
|
||||
console.warn(`Warning: cannot read directory "${dir}": ${err.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
if (fullPath.includes("SpotiDownloader.com - ")) {
|
||||
directories.push(fullPath);
|
||||
fs.rename(fullPath, fullPath.replace("SpotiDownloader.com - ", ""));
|
||||
}
|
||||
|
||||
// recurse into subdirectory
|
||||
await scanDir(fullPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.isFile()) {
|
||||
if (fullPath.includes("SpotiDownloader.com - ")) {
|
||||
files.push(fullPath);
|
||||
fs.rename(fullPath, fullPath.replace("SpotiDownloader.com - ", ""));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.isSymbolicLink()) {
|
||||
// try to follow symlink if it points to a file; skip symlinked dirs
|
||||
try {
|
||||
const stat = await fs.stat(fullPath);
|
||||
if (stat.isFile()) files.push(fullPath);
|
||||
else if (stat.isDirectory()) {
|
||||
console.warn(`Skipping symlinked directory: ${fullPath}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
`Broken or inaccessible symlink "${fullPath}": ${e.message}`
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// other types (FIFO, socket, etc.) are ignored
|
||||
}
|
||||
}
|
||||
|
||||
await scanDir(rootDir);
|
||||
return {
|
||||
files,
|
||||
directories,
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const homeDir = os.homedir();
|
||||
const downloadsDir = path.join(homeDir, "Downloads");
|
||||
|
||||
console.log(`Scanning: ${downloadsDir}\n`);
|
||||
const allFiles = await listAllFiles(downloadsDir);
|
||||
|
||||
if (allFiles.files.length === 0) {
|
||||
console.log("No files found.");
|
||||
return;
|
||||
} else {
|
||||
console.log(`Found and cleaned ${allFiles.files.length} file(s)`);
|
||||
}
|
||||
|
||||
if (allFiles.directories.length === 0) {
|
||||
console.log("No directories found.");
|
||||
return;
|
||||
} else {
|
||||
console.log(
|
||||
`Found and cleaned ${allFiles.directories.length} directories.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Fatal error:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user