editor.py aktualisiert

This commit is contained in:
2026-09-29 16:31:22 +02:00
parent f2585346e7
commit 09e7f79952
+82 -13
View File
@@ -165,7 +165,74 @@ def write_metadata(path, metadata):
raise ValueError("Speichern der ID3-Tags hat zu lange gedauert") raise ValueError("Speichern der ID3-Tags hat zu lange gedauert")
except OSError as exc: except OSError as exc:
temp.unlink(missing_ok=True) temp.unlink(missing_ok=True)
raise ValueError(f"ID3-Tags konnten nicht gespeichert werden: {exc}") raise ValueError(f"Speichern der ID3-Tags fehlgeschlagen: {exc}")
def update_finished_file(old_filename, new_filename, metadata):
"""Update metadata and optionally rename a finished file in one operation."""
old_path = finished_path(old_filename)
new_filename = clean_new_filename(new_filename)
if old_path is None or not old_path.is_file():
raise ValueError("Datei nicht gefunden")
if new_filename is None:
raise ValueError("Ungültiger Dateiname")
new_path = FINISHED_DIR / new_filename
if new_path != old_path and new_path.exists():
raise ValueError("Eine Datei mit diesem Namen existiert bereits")
date = str(metadata.get("date", "")).strip()
if not date:
raise ValueError("Zeitpunkt fehlt")
try:
dt = datetime.fromisoformat(date)
if dt.tzinfo is None:
dt = dt.replace(tzinfo=ZoneInfo("Europe/Berlin"))
date = dt.isoformat()
except ValueError:
raise ValueError("Ungültiger Zeitpunkt")
values = {
"date": date,
"artist": str(metadata.get("artist", "")).strip(),
"title": str(metadata.get("title", "")).strip(),
"album": str(metadata.get("album", "")).strip(),
}
# Build the complete new MP3 first. The original remains untouched until
# FFmpeg has successfully written the new file.
temp = FINISHED_DIR / f".{new_path.name}.update.tmp.mp3"
temp.unlink(missing_ok=True)
cmd = [
"ffmpeg", "-hide_banner", "-loglevel", "error", "-y",
"-i", str(old_path),
"-map", "0",
"-c", "copy",
"-map_metadata", "-1",
]
for key, value in values.items():
cmd += ["-metadata", f"{key}={value}"]
cmd.append(str(temp))
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
if result.returncode != 0 or not temp.is_file() or temp.stat().st_size == 0:
raise ValueError("ID3-Tags konnten nicht gespeichert werden")
temp.replace(new_path)
if new_path != old_path:
old_path.unlink()
return new_path
except subprocess.TimeoutExpired:
temp.unlink(missing_ok=True)
raise ValueError("Speichern der Datei hat zu lange gedauert")
except OSError as exc:
temp.unlink(missing_ok=True)
raise ValueError(f"Datei konnte nicht gespeichert werden: {exc}")
except ValueError:
temp.unlink(missing_ok=True)
raise
def delete_file(kind, filename): def delete_file(kind, filename):
@@ -1013,20 +1080,15 @@ async function saveFinishedMeta() {
album: document.getElementById('finishedAlbum').value.trim() album: document.getElementById('finishedAlbum').value.trim()
}; };
let targetFilename = filename;
if (newFilename.replace(/\.mp3$/i, '') !== filename.replace(/\.mp3$/i, '')) {
const renameResponse = await fetch('/api/file', {
method: 'POST', headers: {'Content-Type':'application/json'},
body: JSON.stringify({action:'rename', kind:'finished', filename, new_filename:newFilename})
});
const renameResult = await renameResponse.json();
if (!renameResponse.ok || !renameResult.success) throw new Error(renameResult.error || `HTTP ${renameResponse.status}`);
targetFilename = renameResult.filename;
}
const response = await fetch('/api/file', { const response = await fetch('/api/file', {
method: 'POST', headers: {'Content-Type':'application/json'}, method: 'POST', headers: {'Content-Type':'application/json'},
body: JSON.stringify({action:'update_metadata', kind:'finished', filename:targetFilename, metadata}) body: JSON.stringify({
action: 'update_finished',
kind: 'finished',
filename,
new_filename: newFilename,
metadata
})
}); });
const result = await response.json(); const result = await response.json();
if (!response.ok || !result.success) throw new Error(result.error || `HTTP ${response.status}`); if (!response.ok || !result.success) throw new Error(result.error || `HTTP ${response.status}`);
@@ -1204,6 +1266,13 @@ def api_file():
if action == "rename": if action == "rename":
path = rename_file(kind, filename, data.get("new_filename")) path = rename_file(kind, filename, data.get("new_filename"))
return jsonify({"success": True, "filename": path.name}) return jsonify({"success": True, "filename": path.name})
if action == "update_finished":
if kind != "finished":
return jsonify({"success": False, "error": "Metadaten können nur bei bearbeiteten Aufnahmen geändert werden"}), 400
metadata = data.get("metadata") or {}
path = update_finished_file(filename, data.get("new_filename"), metadata)
return jsonify({"success": True, "filename": path.name})
if action == "update_metadata": if action == "update_metadata":
if kind != "finished": if kind != "finished":
return jsonify({"success": False, "error": "Metadaten können nur bei bearbeiteten Aufnahmen geändert werden"}), 400 return jsonify({"success": False, "error": "Metadaten können nur bei bearbeiteten Aufnahmen geändert werden"}), 400