diff --git a/demo/model3D_demo/files/Bunny.obj b/demo/model3D/files/Bunny.obj similarity index 100% rename from demo/model3D_demo/files/Bunny.obj rename to demo/model3D/files/Bunny.obj diff --git a/demo/model3D_demo/files/Duck.glb b/demo/model3D/files/Duck.glb similarity index 100% rename from demo/model3D_demo/files/Duck.glb rename to demo/model3D/files/Duck.glb diff --git a/demo/model3D_demo/files/Fox.gltf b/demo/model3D/files/Fox.gltf similarity index 100% rename from demo/model3D_demo/files/Fox.gltf rename to demo/model3D/files/Fox.gltf diff --git a/demo/model3D_demo/files/face.obj b/demo/model3D/files/face.obj similarity index 100% rename from demo/model3D_demo/files/face.obj rename to demo/model3D/files/face.obj diff --git a/demo/model3D_demo/files/source.txt b/demo/model3D/files/source.txt similarity index 100% rename from demo/model3D_demo/files/source.txt rename to demo/model3D/files/source.txt diff --git a/demo/model3D_demo/run.py b/demo/model3D/run.py similarity index 69% rename from demo/model3D_demo/run.py rename to demo/model3D/run.py index e451d868015fb..40438e48d203a 100644 --- a/demo/model3D_demo/run.py +++ b/demo/model3D/run.py @@ -5,16 +5,17 @@ def load_mesh(mesh_file_name): time.sleep(2) - return mesh_file_name + return mesh_file_name, mesh_file_name -inputs = gr.Model3D() -outputs = gr.Model3D(clear_color=[0.8, 0.2, 0.2, 1.0]) - demo = gr.Interface( fn=load_mesh, - inputs=inputs, - outputs=outputs, + inputs=gr.Model3D(), + outputs=[ + gr.Model3D( + clear_color=[0.0, 0.0, 0.0, 0.0], label="3D Model"), + gr.File(label="Download 3D Model") + ], examples=[ [os.path.join(os.path.dirname(__file__), "files/Bunny.obj")], [os.path.join(os.path.dirname(__file__), "files/Duck.glb")], diff --git a/demo/model3D_demo.zip b/demo/model3D_demo.zip new file mode 100644 index 0000000000000..7b1847095a305 Binary files /dev/null and b/demo/model3D_demo.zip differ diff --git a/gradio/components.py b/gradio/components.py index b507b5a5be8c5..2454fafdedd3c 100644 --- a/gradio/components.py +++ b/gradio/components.py @@ -2149,7 +2149,23 @@ def update( } def preprocess_example(self, x): - return {"name": x, "data": None, "is_example": True} + if isinstance(x, list): + return [ + { + "name": file, + "data": None, + "size": os.path.getsize(file), + "is_example": True, + } + for file in x + ] + else: + return { + "name": x, + "data": None, + "size": os.path.getsize(x), + "is_example": True, + } def preprocess(self, x: List[Dict[str, str]] | None): """ @@ -2198,9 +2214,14 @@ def save_flagged(self, dir, label, data, encryption_key): """ Returns: (str) path to file """ - return self.save_flagged_file( - dir, label, None if data is None else data[0]["data"], encryption_key - ) + if isinstance(data, list): + return self.save_flagged_file( + dir, label, None if data is None else data[0]["data"], encryption_key + ) + else: + return self.save_flagged_file( + dir, label, data["data"], encryption_key, data["name"] + ) def generate_sample(self): return deepcopy(media_data.BASE64_FILE) @@ -2216,11 +2237,27 @@ def postprocess(self, y): """ if y is None: return None - return { - "name": os.path.basename(y), - "size": os.path.getsize(y), - "data": processing_utils.encode_file_to_base64(y), - } + if isinstance(y, list): + return [ + { + "name": os.path.basename(file), + "size": os.path.getsize(file), + "data": processing_utils.encode_file_to_base64(file), + } + for file in y + ] + else: + return { + "name": os.path.basename(y), + "size": os.path.getsize(y), + "data": processing_utils.encode_file_to_base64(y), + } + + def deserialize(self, x): + return processing_utils.decode_base64_to_file(x).name + + def restore_flagged(self, dir, data, encryption_key): + return self.restore_flagged_file(dir, data, encryption_key) class Dataframe(Changeable, IOComponent): diff --git a/test/test_components.py b/test/test_components.py index b88a95e615ca8..f8a24e3868e86 100644 --- a/test/test_components.py +++ b/test/test_components.py @@ -922,7 +922,7 @@ def test_component_functions(self): to_save = file_input.save_flagged(tmpdirname, "file_input", [x_file], None) self.assertEqual("file_input/1", to_save) restored = file_input.restore_flagged(tmpdirname, to_save, None) - self.assertEqual(restored, "file_input/1") + self.assertEqual(restored["name"], "file_input/1") self.assertIsInstance(file_input.generate_sample(), dict) file_input = gr.File(label="Upload Your File") diff --git a/ui/packages/app/src/components/File/File.svelte b/ui/packages/app/src/components/File/File.svelte index 6a7fda0a40412..eae52829f4df3 100644 --- a/ui/packages/app/src/components/File/File.svelte +++ b/ui/packages/app/src/components/File/File.svelte @@ -15,6 +15,7 @@ export let root: string; export let label: string; export let show_label: boolean; + export let file_count: string; export let loading_status: LoadingStatus; @@ -38,6 +39,7 @@ {label} {show_label} value={_value} + {file_count} on:change={({ detail }) => (value = detail)} on:drag={({ detail }) => (dragging = detail)} on:change diff --git a/ui/packages/file/src/File.svelte b/ui/packages/file/src/File.svelte index b87bde57b4723..3d9800b22b137 100644 --- a/ui/packages/file/src/File.svelte +++ b/ui/packages/file/src/File.svelte @@ -1,7 +1,11 @@ -{#if value === null} +{#if value === null && file_count === "single"} {drop_text}
- {or_text} -
{upload_text}
+{:else if value === null} + + {drop_text} +
- {or_text} -
+ {upload_text} +
{:else}
-
- {truncate(value.name)} + {display_file_name(value)}
- {prettyBytes(value.size || 0)} + {display_file_size(value)}
Download diff --git a/ui/packages/file/src/utils.ts b/ui/packages/file/src/utils.ts index 8a7dd00218917..f53d7e8962f27 100644 --- a/ui/packages/file/src/utils.ts +++ b/ui/packages/file/src/utils.ts @@ -1,3 +1,5 @@ +import type { FileData } from "@gradio/upload"; + export const prettyBytes = (bytes: number): string => { let units = ["B", "KB", "MB", "GB", "PB"]; let i = 0; @@ -8,3 +10,39 @@ export const prettyBytes = (bytes: number): string => { let unit = units[i]; return bytes.toFixed(1) + " " + unit; }; + +export const display_file_name = ( + value: FileData | Array +): string => { + var str: string; + if (Array.isArray(value)) { + if (value.length > 1) { + return value.length + " files"; + } else { + str = value[0].name; + } + } else { + str = value.name; + } + if (str.length > 30) { + return `${str.substr(0, 30)}...`; + } else return str; +}; + +export const download_files = (value: FileData | Array): string => { + return Array.isArray(value) ? value[0].data : value.data; +}; + +export const display_file_size = ( + value: FileData | Array +): string => { + var total_size = 0; + if (Array.isArray(value)) { + for (var file of value) { + total_size += file.size; + } + } else { + total_size = value.size; + } + return prettyBytes(total_size || 0); +}; diff --git a/ui/packages/upload/src/Upload.svelte b/ui/packages/upload/src/Upload.svelte index 1ad836014998a..5281171a91c90 100644 --- a/ui/packages/upload/src/Upload.svelte +++ b/ui/packages/upload/src/Upload.svelte @@ -4,16 +4,15 @@ export let filetype: string | undefined = undefined; export let theme: string = "default"; - export let single_file: boolean = true; export let include_file_metadata = true; export let dragging = false; export let boundedheight: boolean = true; export let click: boolean = true; export let center: boolean = true; export let flex: boolean = true; + export let file_count: string; let hidden_upload: HTMLInputElement; - let file_count: "multiple" | "directory" | "single"; const dispatch = createEventDispatcher(); @@ -47,7 +46,7 @@ } : (this.result as string); if (all_file_data.length === files.length) { - dispatch("load", single_file ? all_file_data[0] : all_file_data); + dispatch("load", all_file_data); } }; });