mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-09-29 05:15:12 +02:00
Unzip files + no double x (#3767)
* unzip files * quick nit * quick nit * nit
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
import zipfile
|
||||||
|
from io import BytesIO
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
@@ -386,10 +389,43 @@ def upload_files(
|
|||||||
for file in files:
|
for file in files:
|
||||||
if not file.filename:
|
if not file.filename:
|
||||||
raise HTTPException(status_code=400, detail="File name cannot be empty")
|
raise HTTPException(status_code=400, detail="File name cannot be empty")
|
||||||
|
|
||||||
|
# Skip directories and known macOS metadata entries
|
||||||
|
def should_process_file(file_path: str) -> bool:
|
||||||
|
normalized_path = os.path.normpath(file_path)
|
||||||
|
return not any(part.startswith(".") for part in normalized_path.split(os.sep))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
file_store = get_default_file_store(db_session)
|
file_store = get_default_file_store(db_session)
|
||||||
deduped_file_paths = []
|
deduped_file_paths = []
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
|
if file.content_type and file.content_type.startswith("application/zip"):
|
||||||
|
with zipfile.ZipFile(file.file, "r") as zf:
|
||||||
|
for file_info in zf.namelist():
|
||||||
|
if zf.getinfo(file_info).is_dir():
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not should_process_file(file_info):
|
||||||
|
continue
|
||||||
|
|
||||||
|
sub_file_bytes = zf.read(file_info)
|
||||||
|
sub_file_name = os.path.join(str(uuid.uuid4()), file_info)
|
||||||
|
deduped_file_paths.append(sub_file_name)
|
||||||
|
|
||||||
|
mime_type, __ = mimetypes.guess_type(file_info)
|
||||||
|
if mime_type is None:
|
||||||
|
mime_type = "application/octet-stream"
|
||||||
|
|
||||||
|
file_store.save_file(
|
||||||
|
file_name=sub_file_name,
|
||||||
|
content=BytesIO(sub_file_bytes),
|
||||||
|
display_name=os.path.basename(file_info),
|
||||||
|
file_origin=FileOrigin.CONNECTOR,
|
||||||
|
file_type=mime_type,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
file_path = os.path.join(str(uuid.uuid4()), cast(str, file.filename))
|
file_path = os.path.join(str(uuid.uuid4()), cast(str, file.filename))
|
||||||
deduped_file_paths.append(file_path)
|
deduped_file_paths.append(file_path)
|
||||||
file_store.save_file(
|
file_store.save_file(
|
||||||
|
@@ -36,6 +36,7 @@ export default function TextView({
|
|||||||
"text/plain",
|
"text/plain",
|
||||||
"text/x-rst",
|
"text/x-rst",
|
||||||
"text/x-org",
|
"text/x-org",
|
||||||
|
"txt",
|
||||||
];
|
];
|
||||||
return markdownFormats.some((format) => mimeType.startsWith(format));
|
return markdownFormats.some((format) => mimeType.startsWith(format));
|
||||||
};
|
};
|
||||||
@@ -117,7 +118,10 @@ export default function TextView({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open onOpenChange={onClose}>
|
<Dialog open onOpenChange={onClose}>
|
||||||
<DialogContent className="max-w-5xl w-[90vw] flex flex-col justify-between gap-y-0 h-full max-h-[80vh] p-0">
|
<DialogContent
|
||||||
|
hideCloseIcon
|
||||||
|
className="max-w-5xl w-[90vw] flex flex-col justify-between gap-y-0 h-full max-h-[80vh] p-0"
|
||||||
|
>
|
||||||
<DialogHeader className="px-4 mb-0 pt-2 pb-3 flex flex-row items-center justify-between border-b">
|
<DialogHeader className="px-4 mb-0 pt-2 pb-3 flex flex-row items-center justify-between border-b">
|
||||||
<DialogTitle className="text-lg font-medium truncate">
|
<DialogTitle className="text-lg font-medium truncate">
|
||||||
{fileName}
|
{fileName}
|
||||||
|
Reference in New Issue
Block a user