encoding problem war noch nicht für alle Varianten gelöst
This commit is contained in:
@@ -8,6 +8,8 @@ import zipfile
|
|||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
import shutil
|
import shutil
|
||||||
|
import struct
|
||||||
|
import zlib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
@@ -36,24 +38,80 @@ def filter_zip_no_stl(source_zip_path: str, replace: bool = False) -> str:
|
|||||||
copied_count = 0
|
copied_count = 0
|
||||||
skipped_count = 0
|
skipped_count = 0
|
||||||
|
|
||||||
# Öffne ZIP mit metadata_encoding für korrekte Behandlung von Umlauten
|
print("Filtere ZIP und erstelle neues Archiv mit UTF-8 Encoding...")
|
||||||
with zipfile.ZipFile(source_path, 'r', metadata_encoding='utf-8') as src_zip:
|
|
||||||
|
with zipfile.ZipFile(source_path, 'r') as src_zip:
|
||||||
with zipfile.ZipFile(temp_path, 'w', zipfile.ZIP_DEFLATED) as dst_zip:
|
with zipfile.ZipFile(temp_path, 'w', zipfile.ZIP_DEFLATED) as dst_zip:
|
||||||
|
# Iteriere über alle Dateien im Quell-ZIP
|
||||||
for info in src_zip.infolist():
|
for info in src_zip.infolist():
|
||||||
# Verzeichnisse überspringen
|
# Verzeichnisse überspringen
|
||||||
if info.is_dir():
|
if info.is_dir():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# .stl Dateien ausschließen (case-insensitive)
|
# .stl Dateien überspringen
|
||||||
if Path(info.filename).suffix.lower() == '.stl':
|
if info.filename.lower().endswith('.stl'):
|
||||||
skipped_count += 1
|
skipped_count += 1
|
||||||
print(f" ✗ {info.filename}")
|
print(f" - {info.filename}")
|
||||||
else:
|
continue
|
||||||
# Datei mit Original-Metadaten kopieren
|
|
||||||
data = src_zip.read(info.filename)
|
# Kopiere Datei ins neue ZIP
|
||||||
dst_zip.writestr(info, data)
|
try:
|
||||||
|
# Lese Dateiinhalt
|
||||||
|
with src_zip.open(info, 'r') as source:
|
||||||
|
file_data = source.read()
|
||||||
|
|
||||||
|
# Schreibe ins neue ZIP (mit UTF-8 Encoding)
|
||||||
|
dst_zip.writestr(info.filename, file_data, compress_type=zipfile.ZIP_DEFLATED)
|
||||||
copied_count += 1
|
copied_count += 1
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# Fallback: Low-Level Extraktion für problematische Dateien
|
||||||
|
try:
|
||||||
|
# Lese direkt aus der ZIP-Datei ohne Validierung
|
||||||
|
with open(source_path, 'rb') as f:
|
||||||
|
# Gehe zu Local File Header
|
||||||
|
f.seek(info.header_offset)
|
||||||
|
|
||||||
|
# Lese Local File Header (30 Bytes)
|
||||||
|
fheader = f.read(30)
|
||||||
|
if len(fheader) != 30:
|
||||||
|
raise Exception("Kann Local File Header nicht lesen")
|
||||||
|
|
||||||
|
# Parse Header (ZIP Local File Header format)
|
||||||
|
sig, ver, flags, comp_method, mod_time, mod_date, crc, comp_size, uncomp_size, fname_len, extra_len = struct.unpack('<4s5H3I2H', fheader)
|
||||||
|
if sig != b'PK\x03\x04':
|
||||||
|
raise Exception("Ungültiger Local File Header")
|
||||||
|
|
||||||
|
# Lese raw filename bytes aus Header
|
||||||
|
raw_filename_bytes = f.read(fname_len)
|
||||||
|
|
||||||
|
# Überspringe Extra Field
|
||||||
|
f.seek(info.header_offset + 30 + fname_len + extra_len)
|
||||||
|
|
||||||
|
# Lese komprimierte Daten
|
||||||
|
compressed_data = f.read(comp_size)
|
||||||
|
|
||||||
|
# Dekomprimiere
|
||||||
|
if comp_method == 8: # DEFLATE
|
||||||
|
file_data = zlib.decompress(compressed_data, -zlib.MAX_WBITS)
|
||||||
|
elif comp_method == 0: # STORED
|
||||||
|
file_data = compressed_data
|
||||||
|
else:
|
||||||
|
raise Exception(f"Unbekannte Kompression: {comp_method}")
|
||||||
|
|
||||||
|
# Dekodiere Dateinamen mit latin-1 (ISO-8859-1)
|
||||||
|
# latin-1 unterstützt deutsche Umlaute korrekt (\xf6 = ö)
|
||||||
|
correct_filename = raw_filename_bytes.decode('latin-1', errors='replace')
|
||||||
|
|
||||||
|
# Schreibe ins neue ZIP mit korrigiertem Namen
|
||||||
|
dst_zip.writestr(correct_filename, file_data, compress_type=zipfile.ZIP_DEFLATED)
|
||||||
|
copied_count += 1
|
||||||
|
print(f" + {correct_filename} (re-encoded)")
|
||||||
|
|
||||||
|
except Exception as e2:
|
||||||
|
print(f" ! Warnung: Konnte {info.filename} nicht kopieren: {e2}")
|
||||||
|
skipped_count += 1
|
||||||
|
|
||||||
print(f"\nErgebnis: {copied_count} Datei(en) kopiert, {skipped_count} STL-Datei(en) entfernt")
|
print(f"\nErgebnis: {copied_count} Datei(en) kopiert, {skipped_count} STL-Datei(en) entfernt")
|
||||||
|
|
||||||
if replace:
|
if replace:
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ pyinstaller --onefile filter_zip_no_stl.py
|
|||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo === Fertig! ===
|
echo === Fertig! ===
|
||||||
echo EXE liegt unter: dist\filter_zip_no_stl.exe
|
move dist\filter_zip_no_stl.exe ..\..\Sessions\removeStls.exe
|
||||||
pause
|
pause
|
||||||
|
|||||||
Reference in New Issue
Block a user