index.js aktualisiert
This commit is contained in:
parent
160b56634c
commit
e3d0ad5dfa
471
index.js
471
index.js
@ -1,20 +1,42 @@
|
||||
/*
|
||||
* Projekt: File Renamer CLI
|
||||
* Beschreibung: Ein rekursives CLI-Tool zum Umbenennen von Dateien mit Suffix.
|
||||
* Autor: M_Viper
|
||||
* Lizenz: MIT
|
||||
* GitHub: https://git.viper.ipv64.net/M_Viper/file-renamer-cli
|
||||
* Webseite: https://m-viper.de
|
||||
*/
|
||||
* Projekt: File Renamer CLI
|
||||
* Version: 1.2
|
||||
* Beschreibung: Ein rekursives CLI-Tool zum Umbenennen von Dateien mit Suffix und TMDb-Titelerkennung.
|
||||
* Autor: M_Viper
|
||||
* Lizenz: MIT
|
||||
* Gitea: https://git.viper.ipv64.net/M_Viper/file-renamer-cli
|
||||
* Webseite: https://m-viper.de
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const readline = require('readline');
|
||||
const https = require('https');
|
||||
|
||||
const configPath = path.join(os.homedir(), 'Documents', 'config.json');
|
||||
// Optional: dotenv für Umgebungsvariablen
|
||||
let dotenv;
|
||||
try {
|
||||
dotenv = require('dotenv');
|
||||
dotenv.config();
|
||||
} catch {
|
||||
console.warn('dotenv nicht gefunden, verwende Standardwerte oder direkte Eingabe.');
|
||||
}
|
||||
|
||||
// ================== Banner ==================
|
||||
const localVersion = '1.2';
|
||||
|
||||
// TMDb API Bearer Token (aus .env oder direkt hier einfügen)
|
||||
const TMDB_API_BEARER_TOKEN = process.env.TMDB_API_BEARER_TOKEN || 'YOUR_TOKEN_HERE';
|
||||
|
||||
// Konfigurationspfad relativ zur EXE oder im Benutzerverzeichnis
|
||||
const configPath = process.env.NODE_ENV === 'production'
|
||||
? path.join(path.dirname(process.execPath), 'config.json')
|
||||
: path.join(os.homedir(), 'Documents', 'config.json');
|
||||
|
||||
const tmdbCache = new Map(); // Cache für TMDb-Abfragen
|
||||
let processedFiles = 0;
|
||||
|
||||
// ================== Hilfsfunktionen ==================
|
||||
function greenMessage(text) {
|
||||
console.log('\x1b[32m%s\x1b[0m', text);
|
||||
}
|
||||
@ -27,8 +49,7 @@ function centerText(text, width) {
|
||||
}
|
||||
|
||||
function showAsciiLogo() {
|
||||
const width = process.stdout.columns || 80; // Terminalbreite, fallback 80
|
||||
|
||||
const width = process.stdout.columns || 80;
|
||||
const logoLines = [
|
||||
'███████╗██╗██╗ ███████╗███╗ ██╗ █████╗ ███╗ ███╗███████╗ ██████╗██╗ ██╗',
|
||||
'██╔════╝██║██║ ██╔════╝████╗ ██║██╔══██╗████╗ ████║██╔════╝ ██╔════╝██║ ██║',
|
||||
@ -38,57 +59,93 @@ function showAsciiLogo() {
|
||||
'╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚══════╝╚═╝',
|
||||
];
|
||||
|
||||
console.log('\x1b[32m'); // grün starten
|
||||
console.log('\x1b[32m');
|
||||
for (const line of logoLines) {
|
||||
console.log(centerText(line, width));
|
||||
}
|
||||
console.log('\x1b[0m'); // Farbe zurücksetzen
|
||||
console.log('\x1b[0m');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
function showBanner() {
|
||||
console.clear();
|
||||
showAsciiLogo();
|
||||
|
||||
const width = process.stdout.columns || 60; // Breite des Terminals, fallback 60
|
||||
|
||||
const width = process.stdout.columns || 60;
|
||||
const bannerLines = [
|
||||
'Version 1.0',
|
||||
'Version 1.2',
|
||||
'Script by',
|
||||
'@M_Viper',
|
||||
'__________________________',
|
||||
'',
|
||||
'Git: https://git.viper.ipv64.net/M_Viper/file-renamer-cli',
|
||||
'Gitea: https://git.viper.ipv64.net/M_Viper/file-renamer-cli',
|
||||
];
|
||||
|
||||
// Obere Rahmenlinie
|
||||
greenMessage('╔' + '═'.repeat(width - 2) + '╗');
|
||||
|
||||
// Bannerzeilen mit Rahmen und Zentrierung
|
||||
for (const line of bannerLines) {
|
||||
const centered = centerText(line, width - 4); // 4 wegen Rahmen links und rechts + Leerzeichen
|
||||
const centered = centerText(line, width - 4);
|
||||
greenMessage('║ ' + centered + ' ║');
|
||||
}
|
||||
|
||||
// Untere Rahmenlinie
|
||||
greenMessage('╚' + '═'.repeat(width - 2) + '╝');
|
||||
greenMessage('');
|
||||
}
|
||||
// ============================================
|
||||
|
||||
function saveConfig(config) {
|
||||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
||||
// ================== Versionsprüfung (Gitea) ==================
|
||||
async function checkForUpdates() {
|
||||
return new Promise((resolve) => {
|
||||
const options = {
|
||||
hostname: 'git.viper.ipv64.net',
|
||||
path: '/api/v1/repos/M_Viper/file-renamer-cli/releases',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'User-Agent': 'File-Renamer-CLI',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
const req = https.request(options, (res) => {
|
||||
let data = '';
|
||||
res.on('data', (chunk) => (data += chunk));
|
||||
res.on('end', () => {
|
||||
try {
|
||||
const releases = JSON.parse(data);
|
||||
if (!Array.isArray(releases) || releases.length === 0) {
|
||||
return resolve(null);
|
||||
}
|
||||
const latestVersion = releases[0].tag_name.replace(/^v/i, '');
|
||||
const cleanLocal = localVersion.replace(/^v/i, '');
|
||||
if (latestVersion > cleanLocal) {
|
||||
resolve(latestVersion);
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
} catch {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', () => resolve(null));
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
function loadConfig() {
|
||||
if (fs.existsSync(configPath)) {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
// ================== Konfiguration ==================
|
||||
async function saveConfig(config) {
|
||||
try {
|
||||
await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
||||
console.log(`Konfiguration gespeichert unter: ${configPath}`);
|
||||
} catch (err) {
|
||||
console.error('Fehler beim Speichern der Konfiguration:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadConfig() {
|
||||
try {
|
||||
const data = await fs.readFile(configPath, 'utf-8');
|
||||
return JSON.parse(data);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function askQuestion(query) {
|
||||
@ -96,61 +153,202 @@ function askQuestion(query) {
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
return new Promise(resolve => rl.question(query, ans => {
|
||||
return new Promise((resolve) => rl.question(query, (ans) => {
|
||||
rl.close();
|
||||
resolve(ans.trim());
|
||||
}));
|
||||
}
|
||||
|
||||
async function getConfig() {
|
||||
const existingConfig = loadConfig();
|
||||
if (existingConfig?.folderPath && existingConfig?.suffix) {
|
||||
console.log(`Verwende gespeicherte Konfiguration:`);
|
||||
console.log(`Ordner: ${existingConfig.folderPath}`);
|
||||
console.log(`Suffix: ${existingConfig.suffix}`);
|
||||
return existingConfig;
|
||||
// Prüfe auf --setup Kommandozeilenoption
|
||||
const forceSetup = process.argv.includes('--setup');
|
||||
if (forceSetup) {
|
||||
console.log('Erzwinge Ersteinrichtung (--setup angegeben)...');
|
||||
return await setupConfig();
|
||||
}
|
||||
|
||||
const existingConfig = await loadConfig();
|
||||
|
||||
// Prüfe, ob die Konfiguration vollständig und gültig ist
|
||||
if (
|
||||
existingConfig?.folderPath &&
|
||||
existingConfig?.suffix &&
|
||||
['preview', 'preview-confirm', 'direct'].includes(existingConfig?.renameMode)
|
||||
) {
|
||||
try {
|
||||
await fs.access(existingConfig.folderPath); // Prüfe, ob der Ordner existiert
|
||||
if (/[<>"|?*]/.test(existingConfig.suffix)) {
|
||||
console.log('Ungültiger Suffix in Konfiguration gefunden. Starte Ersteinrichtung...');
|
||||
return await setupConfig();
|
||||
}
|
||||
return existingConfig;
|
||||
} catch {
|
||||
console.log('Konfigurationsordner existiert nicht mehr. Starte Ersteinrichtung...');
|
||||
return await setupConfig();
|
||||
}
|
||||
}
|
||||
|
||||
// Ersteinrichtung, wenn keine oder ungültige Konfiguration
|
||||
return await setupConfig();
|
||||
}
|
||||
|
||||
async function setupConfig() {
|
||||
console.log('\n--- Ersteinrichtung ---');
|
||||
|
||||
// Ordnerauswahl
|
||||
console.log('Möchtest du den automatischen Ordner nutzen?');
|
||||
console.log('1 = Ja (Desktop\\Filme)');
|
||||
console.log('2 = Benutzerdefinierter Ordner');
|
||||
|
||||
const antwort = await askQuestion('Deine Wahl (1 oder 2): ');
|
||||
|
||||
let folderPath;
|
||||
|
||||
if (antwort === '1') {
|
||||
folderPath = path.join(os.homedir(), 'Desktop', 'Filme');
|
||||
console.log(`Automatischer Ordner gewählt: ${folderPath}`);
|
||||
} else if (antwort === '2') {
|
||||
folderPath = await askQuestion('Bitte gib den vollständigen Pfad zum Ordner ein:\n');
|
||||
try {
|
||||
await fs.access(folderPath);
|
||||
} catch {
|
||||
console.log('Ordner existiert nicht, bitte überprüfe den Pfad.');
|
||||
return setupConfig();
|
||||
}
|
||||
} else {
|
||||
console.log('Ungültige Eingabe, bitte versuche es nochmal.');
|
||||
return getConfig();
|
||||
return setupConfig();
|
||||
}
|
||||
|
||||
const suffix = await askQuestion('Welcher Text soll am Ende der Dateinamen hinzugefügt werden? (z. B. @Name)\n');
|
||||
// Suffix
|
||||
const suffix = await askQuestion(
|
||||
'Welcher Text soll am Ende der Dateinamen hinzugefügt werden? (z. B. @Name)\n'
|
||||
);
|
||||
if (!suffix || /[<>"|?*]/.test(suffix)) {
|
||||
console.log('Ungültiger Suffix. Vermeide Sonderzeichen wie <, >, ?, * usw.');
|
||||
return setupConfig();
|
||||
}
|
||||
|
||||
const config = { folderPath, suffix };
|
||||
saveConfig(config);
|
||||
// Umbenennungsmodus
|
||||
console.log('Wie soll die Umbenennung durchgeführt werden?');
|
||||
console.log('1 = Nur Vorschau der Änderungen');
|
||||
console.log('2 = Vorschau mit Bestätigung');
|
||||
console.log('3 = Direkte Umbenennung ohne Vorschau');
|
||||
const modeChoice = await askQuestion('Deine Wahl (1, 2 oder 3): ');
|
||||
let renameMode;
|
||||
if (modeChoice === '1') {
|
||||
renameMode = 'preview';
|
||||
console.log('[DEBUG] Modus: Nur Vorschau');
|
||||
} else if (modeChoice === '2') {
|
||||
renameMode = 'preview-confirm';
|
||||
console.log('[DEBUG] Modus: Vorschau mit Bestätigung');
|
||||
} else if (modeChoice === '3') {
|
||||
renameMode = 'direct';
|
||||
console.log('[DEBUG] Modus: Direkte Umbenennung');
|
||||
} else {
|
||||
console.log('Ungültige Eingabe. Bitte gib "1", "2" oder "3" ein.');
|
||||
return setupConfig();
|
||||
}
|
||||
|
||||
const config = { folderPath, suffix, renameMode };
|
||||
await saveConfig(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
function umbenennenSync(pfad, suffix) {
|
||||
console.log('Prüfe Ordner:', pfad);
|
||||
|
||||
if (!fs.existsSync(pfad)) {
|
||||
console.log('Ordner existiert nicht, erstelle:', pfad);
|
||||
fs.mkdirSync(pfad, { recursive: true });
|
||||
return;
|
||||
// ================== TMDb API ==================
|
||||
async function fetchMovieDataFromTMDb(title, year) {
|
||||
if (!title) return null;
|
||||
const cacheKey = `${title}|${year || ''}`;
|
||||
if (tmdbCache.has(cacheKey)) {
|
||||
console.log(`Verwende gecachte TMDb-Daten für: ${title} (${year || 'ohne Jahr'})`);
|
||||
return tmdbCache.get(cacheKey);
|
||||
}
|
||||
|
||||
const eintraege = fs.readdirSync(pfad, { withFileTypes: true });
|
||||
try {
|
||||
const query = encodeURIComponent(title);
|
||||
let url = `https://api.themoviedb.org/3/search/movie?query=${query}&include_adult=false`;
|
||||
if (year) url += `&year=${year}`;
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${TMDB_API_BEARER_TOKEN}`,
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
},
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
https
|
||||
.get(url, options, (res) => {
|
||||
if (res.statusCode === 429) {
|
||||
console.warn('TMDb Rate-Limit erreicht, warte kurz...');
|
||||
setTimeout(() => fetchMovieDataFromTMDb(title, year).then(resolve).catch(reject), 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = '';
|
||||
res.on('data', (chunk) => (data += chunk));
|
||||
res.on('end', () => {
|
||||
try {
|
||||
const json = JSON.parse(data);
|
||||
const result = json.results && json.results.length > 0 ? json.results[0] : null;
|
||||
tmdbCache.set(cacheKey, result);
|
||||
resolve(result);
|
||||
} catch (err) {
|
||||
console.error(`Fehler beim Parsen der TMDb-Antwort für ${title}:`, err.message);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
})
|
||||
.on('error', (err) => {
|
||||
console.error(`Fehler bei TMDb-Abfrage für ${title}:`, err.message);
|
||||
resolve(null); // Fallback: Keine Daten
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`Unerwarteter Fehler bei TMDb-Abfrage für ${title}:`, err.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ================== Umbenennung ==================
|
||||
async function umbenennenSync(pfad, suffix, mode = 'preview') {
|
||||
console.log('Prüfe Ordner:', pfad);
|
||||
console.log(`[DEBUG] Umbenennungsmodus: ${mode}`);
|
||||
|
||||
try {
|
||||
await fs.access(pfad);
|
||||
} catch (err) {
|
||||
console.log('Ordner existiert nicht, erstelle:', pfad);
|
||||
try {
|
||||
await fs.mkdir(pfad, { recursive: true });
|
||||
} catch (mkdirErr) {
|
||||
console.error('Fehler beim Erstellen des Ordners:', mkdirErr.message);
|
||||
}
|
||||
return { shouldChangeConfig: false };
|
||||
}
|
||||
|
||||
let eintraege;
|
||||
try {
|
||||
eintraege = await fs.readdir(pfad, { withFileTypes: true });
|
||||
} catch (err) {
|
||||
console.error('Fehler beim Lesen des Ordners:', err.message);
|
||||
return { shouldChangeConfig: false };
|
||||
}
|
||||
|
||||
if (eintraege.length === 0) {
|
||||
console.log('Ordner ist leer:', pfad);
|
||||
if (mode === 'preview') {
|
||||
const changeConfig = await askQuestion('Möchten Sie die Konfiguration ändern? (ja/nein): ');
|
||||
if (changeConfig.toLowerCase() === 'ja') {
|
||||
return { shouldChangeConfig: true };
|
||||
}
|
||||
await askQuestion('Drücken Sie Enter zum Beenden...');
|
||||
}
|
||||
return { shouldChangeConfig: false };
|
||||
}
|
||||
|
||||
const jahrRegex = /(\d{4})/;
|
||||
const serieRegex = /(S\d{1,2}E\d{1,2})/i;
|
||||
const changes = [];
|
||||
|
||||
for (const eintrag of eintraege) {
|
||||
const vollerPfad = path.join(pfad, eintrag.name);
|
||||
|
||||
@ -164,7 +362,10 @@ function umbenennenSync(pfad, suffix) {
|
||||
continue;
|
||||
}
|
||||
console.log('Betrete Unterordner:', vollerPfad);
|
||||
umbenennenSync(vollerPfad, suffix);
|
||||
const result = await umbenennenSync(vollerPfad, suffix, mode);
|
||||
if (result.shouldChangeConfig) {
|
||||
return { shouldChangeConfig: true };
|
||||
}
|
||||
} else if (eintrag.isFile()) {
|
||||
const ext = path.extname(eintrag.name);
|
||||
const name = path.basename(eintrag.name, ext);
|
||||
@ -174,30 +375,148 @@ function umbenennenSync(pfad, suffix) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const neuerName = `${name} ${suffix}${ext}`;
|
||||
const neuerPfad = path.join(pfad, neuerName);
|
||||
const serieMatch = name.match(serieRegex);
|
||||
let neuerNameTeil;
|
||||
|
||||
if (serieMatch) {
|
||||
const serienTeil = serieMatch[0];
|
||||
const titelVorSerie = name.substring(0, serieMatch.index).trim().replace(/[\.\-_]+/g, ' ');
|
||||
neuerNameTeil = `${titelVorSerie} ${serienTeil} ${suffix}`.trim();
|
||||
} else {
|
||||
const jahrMatch = name.match(jahrRegex);
|
||||
const jahr = jahrMatch ? jahrMatch[1] : null;
|
||||
const titelRaw = name.replace(jahrRegex, '').replace(/[\.\-_]+/g, ' ').trim();
|
||||
|
||||
const filmDaten = await fetchMovieDataFromTMDb(titelRaw, jahr);
|
||||
let filmTitel = titelRaw;
|
||||
let filmJahr = jahr;
|
||||
|
||||
if (filmDaten) {
|
||||
filmTitel = filmDaten.title || filmTitel;
|
||||
filmJahr = filmDaten.release_date ? filmDaten.release_date.substring(0, 4) : filmJahr;
|
||||
}
|
||||
|
||||
neuerNameTeil = filmJahr ? `${filmTitel} (${filmJahr}) ${suffix}` : `${filmTitel} ${suffix}`;
|
||||
}
|
||||
|
||||
const neuerDateiname = neuerNameTeil + ext;
|
||||
const neuerPfad = path.join(pfad, neuerDateiname);
|
||||
|
||||
if (neuerDateiname === eintrag.name) {
|
||||
console.log('Dateiname ist bereits korrekt:', neuerDateiname);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.renameSync(vollerPfad, neuerPfad);
|
||||
console.log(`Umbenannt: ${eintrag.name} → ${neuerName}`);
|
||||
} catch (e) {
|
||||
console.error(`Fehler bei ${eintrag.name}:`, e.message);
|
||||
if (e.code === 'EPERM' || e.code === 'EACCES') {
|
||||
console.error('Keine Zugriffsrechte oder Datei geschützt. Übersprungen.');
|
||||
}
|
||||
await fs.access(neuerPfad);
|
||||
console.log(`Datei existiert bereits: ${neuerDateiname}, überspringe`);
|
||||
continue;
|
||||
} catch {
|
||||
// Datei existiert nicht, kann umbenannt werden
|
||||
}
|
||||
} else {
|
||||
console.log('Kein Datei- oder Ordner-Eintrag, überspringe:', eintrag.name);
|
||||
|
||||
changes.push({ alt: eintrag.name, neu: neuerDateiname, vollerPfad, neuerPfad });
|
||||
processedFiles++;
|
||||
}
|
||||
}
|
||||
|
||||
if (changes.length > 0) {
|
||||
if (mode === 'preview' || mode === 'preview-confirm') {
|
||||
console.log(`\nVorschau der Änderungen (${changes.length}):`);
|
||||
changes.forEach(({ alt, neu }) => {
|
||||
console.log(`${alt} → ${neu}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (mode === 'preview') {
|
||||
console.log('\nNur Vorschau: Keine Änderungen wurden vorgenommen.');
|
||||
const changeConfig = await askQuestion('Möchten Sie die Konfiguration ändern? (ja/nein): ');
|
||||
if (changeConfig.toLowerCase() === 'ja') {
|
||||
return { shouldChangeConfig: true };
|
||||
}
|
||||
await askQuestion('Drücken Sie Enter zum Beenden...');
|
||||
return { shouldChangeConfig: false };
|
||||
}
|
||||
|
||||
if (mode === 'preview-confirm') {
|
||||
console.log('\nAusführungs-Modus: Änderungen werden nach Bestätigung durchgeführt.');
|
||||
const confirm = await askQuestion('Sollen diese Änderungen durchgeführt werden? (ja/nein): ');
|
||||
if (confirm.toLowerCase() !== 'ja') {
|
||||
console.log('Umbenennung abgebrochen.');
|
||||
return { shouldChangeConfig: false };
|
||||
}
|
||||
}
|
||||
|
||||
// Für 'preview-confirm' (nach Bestätigung) oder 'direct'
|
||||
if (mode === 'preview-confirm' || mode === 'direct') {
|
||||
if (mode === 'direct') {
|
||||
console.log('\nDirekter Umbenennungs-Modus: Änderungen werden sofort durchgeführt.');
|
||||
}
|
||||
for (const { vollerPfad, neuerPfad } of changes) {
|
||||
try {
|
||||
await fs.rename(vollerPfad, neuerPfad);
|
||||
console.log(`Umbenannt: ${path.basename(vollerPfad)} → ${path.basename(neuerPfad)}`);
|
||||
} catch (err) {
|
||||
console.error(`Fehler beim Umbenennen von ${path.basename(vollerPfad)}:`, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(`\n${mode === 'preview' ? 'Vorschau-Modus' : mode === 'preview-confirm' ? 'Ausführungs-Modus' : 'Direkter Modus'}: Keine Änderungen erforderlich.`);
|
||||
if (mode === 'preview') {
|
||||
const changeConfig = await askQuestion('Möchten Sie die Konfiguration ändern? (ja/nein): ');
|
||||
if (changeConfig.toLowerCase() === 'ja') {
|
||||
return { shouldChangeConfig: true };
|
||||
}
|
||||
await askQuestion('Drücken Sie Enter zum Beenden...');
|
||||
}
|
||||
}
|
||||
|
||||
return { shouldChangeConfig: false };
|
||||
}
|
||||
|
||||
async function main() {
|
||||
showBanner(); // Banner anzeigen
|
||||
// ================== Hauptprogramm ==================
|
||||
(async () => {
|
||||
showBanner();
|
||||
|
||||
const config = await getConfig();
|
||||
umbenennenSync(config.folderPath, config.suffix);
|
||||
console.log('Fertig!');
|
||||
}
|
||||
if (!TMDB_API_BEARER_TOKEN || TMDB_API_BEARER_TOKEN === 'eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI4ZjlmNjk4MTk4ODE1ODFlZWUxNWI0NzU2NzkwYzU4ZCIsIm5iZiI6MTYwMTk3NzY4Ni45NTM5OTk4LCJzdWIiOiI1ZjdjM2Q1NjBlNTk3YjAwMzdiMjYxYzAiLCJzY29wZXMiOlsiYXBpX3JlYWQiXSwidmVyc2lvbiI6MX0.YxNqLdfqvV4bWOkUZIU1ObWrICh_8QILwRnf_I-2x5w') {
|
||||
console.error('Fehler: TMDb API-Token fehlt. Bitte in .env-Datei konfigurieren.');
|
||||
console.error('Hinweis: Verwende niemals einen echten Token direkt im Code!');
|
||||
console.error('Erstelle eine .env-Datei mit: TMDB_API_BEARER_TOKEN=dein_tmdb_token');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
main();
|
||||
try {
|
||||
const updateVerfuegbar = await checkForUpdates();
|
||||
if (updateVerfuegbar) {
|
||||
console.log(`Neue Version verfügbar: ${updateVerfuegbar} (Du hast: ${localVersion})`);
|
||||
console.log('Bitte aktualisiere das Tool über Gitea.\n');
|
||||
} else {
|
||||
console.log('Du hast die aktuellste Version.\n');
|
||||
}
|
||||
|
||||
let config = await getConfig();
|
||||
let shouldContinue = true;
|
||||
|
||||
while (shouldContinue) {
|
||||
console.log(`Starte Umbenennung im Ordner: ${config.folderPath}`);
|
||||
console.log(`Suffix: ${config.suffix}`);
|
||||
console.log(`Umbenennungsmodus: ${config.renameMode}\n`);
|
||||
|
||||
processedFiles = 0; // Zurücksetzen für neue Umbenennung
|
||||
const result = await umbenennenSync(config.folderPath, config.suffix, config.renameMode);
|
||||
|
||||
if (result.shouldChangeConfig) {
|
||||
console.log('\nStarte Konfigurationsänderung...');
|
||||
config = await setupConfig();
|
||||
} else {
|
||||
shouldContinue = false;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\nFertig! Verarbeitete Dateien: ${processedFiles}`);
|
||||
} catch (err) {
|
||||
console.error('Unerwarteter Fehler im Hauptprogramm:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
Loading…
x
Reference in New Issue
Block a user