From b0dd3e505302a3891e87f96aa168e47a9d1fafe2 Mon Sep 17 00:00:00 2001 From: rmkolany Date: Fri, 27 Oct 2023 16:20:19 -0700 Subject: [PATCH 1/3] A fix of the file widget to allow for upload of multiple files. Fix works in Jupyter, help still needed on React side of UI. --- mercury/widgets/file.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/mercury/widgets/file.py b/mercury/widgets/file.py index 76388162..d1040827 100644 --- a/mercury/widgets/file.py +++ b/mercury/widgets/file.py @@ -12,20 +12,21 @@ class File: def __init__( - self, label="File upload", max_file_size="100MB", disabled=False, hidden=False + self, label="File upload", max_file_size="100MB", disabled=False, hidden=False, multiple=False ): self.max_file_size = max_file_size self.code_uid = WidgetsManager.get_code_uid("File") self.temp_dir = None atexit.register(self.cleanup) self.hidden = hidden + self.multiple = multiple if WidgetsManager.widget_exists(self.code_uid): self.file = WidgetsManager.get_widget(self.code_uid) self.file.description = label self.file.disabled = disabled else: - self.file = ipywidgets.FileUpload(description=label, disabled=disabled) + self.file = ipywidgets.FileUpload(description=label, disabled=disabled, multiple=multiple) self.file.filepath = None self.file.filename = None WidgetsManager.add_widget(self.file.model_id, self.code_uid, self.file) @@ -33,9 +34,10 @@ def __init__( @property def value(self): - if len(self.file.value): + if self.multiple: + return [file.content for file in self.file.value] + elif len(self.file.value): return self.file.value[0].content - if self.file.filepath is not None: # read that file with open(self.file.filepath, "rb") as fin: @@ -45,7 +47,9 @@ def value(self): @property def filename(self): - if len(self.file.value): + if self.multiple: + return [file.name for file in self.file.value] + elif len(self.file.value): return self.file.value[0].name if self.file.filename is not None: return self.file.filename @@ -55,21 +59,27 @@ def filename(self): def filepath(self): if self.file.filepath is not None: return self.file.filepath - if ( len(self.file.value) and self.filename is not None and self.value is not None ): - # store file in temp dir - # and return the path self.temp_dir = tempfile.mkdtemp() - self.file.filepath = os.path.join(self.temp_dir, self.filename) - - with open(self.file.filepath, "wb") as fout: - fout.write(self.value) - - return self.file.filepath + if self.multiple: + # create filepath list, write all files, return path + self.file.filepath = [] + for fn,val in zip(self.filename,self.value): + path = os.path.join(self.temp_dir,fn) + self.file.filepath.append(path) + with open(path, "wb") as fout: + fout.write(val) + return self.file.filepath + else: + # create filepath, write file, return path + self.file.filepath = os.path.join(self.temp_dir, self.filename) + with open(self.file.filepath, "wb") as fout: + fout.write(self.value) + return self.file.filepath return None From 7d78406a3650b1da1455c635dd8a0dccb8b50b41 Mon Sep 17 00:00:00 2001 From: rmkolany Date: Mon, 30 Oct 2023 09:27:23 -0700 Subject: [PATCH 2/3] Updated React code --- frontend/src/widgets/File.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/widgets/File.tsx b/frontend/src/widgets/File.tsx index e830fd9c..f321ad1d 100644 --- a/frontend/src/widgets/File.tsx +++ b/frontend/src/widgets/File.tsx @@ -31,6 +31,7 @@ type FileProps = { maxFileSize: string | null; disabled: boolean; hidden: boolean; + multiple: boolean; value: string[]; runNb: () => void; }; @@ -41,6 +42,7 @@ export default function FileWidget({ maxFileSize, disabled, hidden, + multiple, value, runNb, }: FileProps) { From 622e01d85886cb28d5feac3c8a4fed51dfb861da Mon Sep 17 00:00:00 2001 From: Reed Kolany <80431379+rmkolany@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:52:10 -0700 Subject: [PATCH 3/3] Update package.json --- frontend/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/package.json b/frontend/package.json index 3f3af341..693f67d1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,6 +24,7 @@ "font-awesome": "^4.7.0", "history": "^5.1.0", "js-file-download": "^0.4.12", + "mercury": "rmkolany/mercury#multiple-files-widget" "popper": "^1.0.1", "react": "^17.0.2", "react-block-ui": "^1.3.5",