39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
"""Unzip service — extract files from ZIP archive."""
|
|
import zipfile, io, base64, json
|
|
|
|
|
|
def handle_unzip(rfile, content_length):
|
|
"""Parse ZIP upload, return list of extracted files."""
|
|
body = rfile.read(content_length)
|
|
|
|
# Find file data in raw multipart
|
|
# Simple approach: find ZIP bytes after header
|
|
idx = body.find(b"\r\n\r\n")
|
|
if idx < 0:
|
|
return {"ok": False, "error": "invalid multipart"}
|
|
|
|
# Find first boundary end
|
|
raw = body[idx + 4:]
|
|
# Find the actual ZIP data (after Content-Disposition etc)
|
|
zip_start = raw.find(b"PK\x03\x04")
|
|
if zip_start < 0:
|
|
return {"ok": False, "error": "not a ZIP file"}
|
|
|
|
zip_data = raw[zip_start:]
|
|
|
|
files = []
|
|
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
for name in zf.namelist():
|
|
if name.endswith("/"):
|
|
continue
|
|
data = zf.read(name)
|
|
ext = name.rsplit(".", 1)[-1].lower() if "." in name else ""
|
|
files.append({
|
|
"filename": name,
|
|
"data_b64": base64.b64encode(data).decode(),
|
|
"ext": ext,
|
|
"size": len(data),
|
|
})
|
|
|
|
return {"ok": True, "files": files}
|