Merge pull request #3 from cadtoolbox/copilot/fix-3mf-file-upload-error

This commit is contained in:
Thomas Rambach
2026-02-03 20:57:48 -05:00
committed by GitHub
4 changed files with 14 additions and 44 deletions
+3
View File
@@ -664,10 +664,12 @@ async def list_files(
print_name = None
print_time = None
filament_grams = None
sliced_for_model = None
if f.file_metadata:
print_name = f.file_metadata.get("print_name")
print_time = f.file_metadata.get("print_time_seconds")
filament_grams = f.file_metadata.get("filament_used_grams")
sliced_for_model = f.file_metadata.get("sliced_for_model")
file_list.append(
FileListResponse(
@@ -685,6 +687,7 @@ async def list_files(
print_name=print_name,
print_time_seconds=print_time,
filament_used_grams=filament_grams,
sliced_for_model=sliced_for_model,
)
)
+1
View File
@@ -154,6 +154,7 @@ class FileListResponse(BaseModel):
print_name: str | None = None
print_time_seconds: int | None = None
filament_used_grams: float | None = None
sliced_for_model: str | None = None
class Config:
from_attributes = True
+1
View File
@@ -3820,6 +3820,7 @@ export interface LibraryFileListItem {
print_name: string | null;
print_time_seconds: number | null;
filament_used_grams: number | null;
sliced_for_model: string | null;
}
export interface LibraryFileUpdate {
+9 -44
View File
@@ -431,7 +431,6 @@ interface UploadFile {
isZip?: boolean;
is3mf?: boolean;
extractedCount?: number;
archiveId?: number;
}
function UploadModal({ folderId, onClose, onUploadComplete, t }: UploadModalProps) {
@@ -489,49 +488,9 @@ function UploadModal({ folderId, onClose, onUploadComplete, t }: UploadModalProp
setIsUploading(true);
// Handle .3mf files with bulk upload API (advanced extraction)
const threemfFiles = files.filter((f) => f.is3mf && f.status === 'pending');
if (threemfFiles.length > 0) {
try {
// Mark files as uploading
setFiles((prev) =>
prev.map((f) => (f.is3mf && f.status === 'pending' ? { ...f, status: 'uploading' } : f))
);
// Use the archives bulk upload API for .3mf files (extracts printer model)
const result = await api.uploadArchivesBulk(threemfFiles.map((f) => f.file));
// Update file statuses based on result
setFiles((prev) =>
prev.map((f) => {
if (!f.is3mf || f.status !== 'uploading') return f;
const success = result.results.find((r) => r.filename === f.file.name);
const error = result.errors.find((e) => e.filename === f.file.name);
if (success) {
return { ...f, status: 'success', archiveId: success.id };
}
if (error) {
return { ...f, status: 'error', error: error.error };
}
return f;
})
);
} catch (err) {
setFiles((prev) =>
prev.map((f) =>
f.is3mf && f.status === 'uploading'
? { ...f, status: 'error', error: err instanceof Error ? err.message : 'Upload failed' }
: f
)
);
}
}
// Handle other files (ZIP and regular files) with library upload
// Handle all files with library upload (ZIP and regular files including .3mf)
for (let i = 0; i < files.length; i++) {
if (files[i].status !== 'pending' || files[i].is3mf) continue;
if (files[i].status !== 'pending') continue;
setFiles((prev) =>
prev.map((f, idx) => (idx === i ? { ...f, status: 'uploading' } : f))
@@ -554,7 +513,7 @@ function UploadModal({ folderId, onClose, onUploadComplete, t }: UploadModalProp
)
);
} else {
// Regular file upload (STL, etc.)
// Regular file upload (STL, .3mf, etc.) - .3mf files automatically get metadata extracted
await api.uploadLibraryFile(files[i].file, folderId, generateStlThumbnails);
setFiles((prev) =>
prev.map((f, idx) => (idx === i ? { ...f, status: 'success' } : f))
@@ -1003,6 +962,12 @@ function FileCard({ file, isSelected, isMobile, onSelect, onDelete, onDownload,
</span>
)}
</div>
{file.sliced_for_model && (
<div className="mt-1 text-xs text-purple-400 flex items-center gap-1">
<Printer className="w-3 h-3" />
{file.sliced_for_model}
</div>
)}
{file.print_count > 0 && (
<div className="mt-1 text-xs text-bambu-green">
{t('fileManager.printedCount', { count: file.print_count })}