From 1f2abee2fdfaacd10b6741dc8913826c0751fab7 Mon Sep 17 00:00:00 2001 From: Garrett Date: Thu, 14 Sep 2023 11:59:40 -0700 Subject: [PATCH 1/6] Complete symlinked file demo --- pyflask/apis/neuroconv.py | 62 +++++++------- pyflask/manageNeuroconv/__init__.py | 3 + pyflask/manageNeuroconv/info/__init__.py | 2 +- pyflask/manageNeuroconv/info/urls.py | 7 +- pyflask/manageNeuroconv/manage_neuroconv.py | 83 ++++++++++++++++++- .../src/stories/FileSystemSelector.js | 20 ++--- src/renderer/src/stories/JSONSchemaInput.js | 9 +- .../src/stories/pages/inspect/InspectPage.js | 32 ++++--- 8 files changed, 154 insertions(+), 64 deletions(-) diff --git a/pyflask/apis/neuroconv.py b/pyflask/apis/neuroconv.py index e719625c1..0db136328 100644 --- a/pyflask/apis/neuroconv.py +++ b/pyflask/apis/neuroconv.py @@ -13,7 +13,11 @@ validate_metadata, listen_to_neuroconv_events, generate_dataset, + inspect_nwb_file, + inspect_nwb_folder, + inspect_multiple_filesystem_objects ) + from errorHandlers import notBadRequestException neuroconv_api = Namespace("neuroconv", description="Neuroconv neuroconv_api for the NWB GUIDE.") @@ -141,54 +145,44 @@ class InspectNWBFile(Resource): @neuroconv_api.doc(responses={200: "Success", 400: "Bad Request", 500: "Internal server error"}) def post(self): try: - import json - from nwbinspector import inspect_nwbfile - from nwbinspector.nwbinspector import InspectorOutputJSONEncoder - - return json.loads( - json.dumps( - list( - inspect_nwbfile( - ignore=[ - "check_description", - "check_data_orientation", - ], # TODO: remove when metadata control is exposed - **neuroconv_api.payload, - ) - ), - cls=InspectorOutputJSONEncoder, - ) - ) - + return inspect_nwb_file(neuroconv_api.payload) except Exception as e: if notBadRequestException(e): neuroconv_api.abort(500, str(e)) + @neuroconv_api.route("/inspect_folder") class InspectNWBFolder(Resource): @neuroconv_api.doc(responses={200: "Success", 400: "Bad Request", 500: "Internal server error"}) def post(self): try: - import json - from nwbinspector import inspect_all - from nwbinspector.nwbinspector import InspectorOutputJSONEncoder + return inspect_nwb_folder(neuroconv_api.payload) + + except Exception as e: + if notBadRequestException(e): + neuroconv_api.abort(500, str(e)) - messages = list( - inspect_all( - n_jobs=-2, # uses number of CPU - 1 - ignore=[ - "check_description", - "check_data_orientation", - ], # TODO: remove when metadata control is exposed - **neuroconv_api.payload, - ) - ) - # messages = organize_messages(messages, levels=["importance", "message"]) +@neuroconv_api.route("/inspect") +class InspectNWBFolder(Resource): + @neuroconv_api.doc(responses={200: "Success", 400: "Bad Request", 500: "Internal server error"}) + def post(self): + + from os.path import isfile + + try: + paths = neuroconv_api.payload["paths"] - return json.loads(json.dumps(messages, cls=InspectorOutputJSONEncoder)) + if (len(paths) == 1): + if (isfile(paths[0])): + return inspect_nwb_file({ "path": paths[0] }) + else: + return inspect_nwb_folder({ "path": paths[0] }) + else: + return inspect_multiple_filesystem_objects(paths) + except Exception as e: if notBadRequestException(e): neuroconv_api.abort(500, str(e)) diff --git a/pyflask/manageNeuroconv/__init__.py b/pyflask/manageNeuroconv/__init__.py index 7f84d44c5..8adea2add 100644 --- a/pyflask/manageNeuroconv/__init__.py +++ b/pyflask/manageNeuroconv/__init__.py @@ -9,6 +9,9 @@ upload_folder_to_dandi, listen_to_neuroconv_events, generate_dataset, + inspect_nwb_file, + inspect_nwb_folder, + inspect_multiple_filesystem_objects ) diff --git a/pyflask/manageNeuroconv/info/__init__.py b/pyflask/manageNeuroconv/info/__init__.py index a3d9f9d41..6d76218b7 100644 --- a/pyflask/manageNeuroconv/info/__init__.py +++ b/pyflask/manageNeuroconv/info/__init__.py @@ -1 +1 @@ -from .urls import resource_path, STUB_SAVE_FOLDER_PATH, CONVERSION_SAVE_FOLDER_PATH, TUTORIAL_SAVE_FOLDER_PATH +from .urls import resource_path, GUIDE_ROOT_FOLDER, STUB_SAVE_FOLDER_PATH, CONVERSION_SAVE_FOLDER_PATH, TUTORIAL_SAVE_FOLDER_PATH diff --git a/pyflask/manageNeuroconv/info/urls.py b/pyflask/manageNeuroconv/info/urls.py index ef9a4bd8c..662adc29d 100644 --- a/pyflask/manageNeuroconv/info/urls.py +++ b/pyflask/manageNeuroconv/info/urls.py @@ -20,8 +20,9 @@ def resource_path(relative_path): ) # NOTE: Must have pyflask for running the GUIDE as a whole, but errors for just the server f = path_config.open() data = json.load(f) -STUB_SAVE_FOLDER_PATH = Path(Path.home(), data["root"], *data["subfolders"]["stubs"]) -CONVERSION_SAVE_FOLDER_PATH = Path(Path.home(), data["root"], *data["subfolders"]["conversions"]) -TUTORIAL_SAVE_FOLDER_PATH = Path(Path.home(), data["root"], *data["subfolders"]["tutorial"]) +GUIDE_ROOT_FOLDER = Path(Path.home(), data["root"]) +STUB_SAVE_FOLDER_PATH = Path(GUIDE_ROOT_FOLDER, *data["subfolders"]["stubs"]) +CONVERSION_SAVE_FOLDER_PATH = Path(GUIDE_ROOT_FOLDER, *data["subfolders"]["conversions"]) +TUTORIAL_SAVE_FOLDER_PATH = Path(GUIDE_ROOT_FOLDER, *data["subfolders"]["tutorial"]) f.close() diff --git a/pyflask/manageNeuroconv/manage_neuroconv.py b/pyflask/manageNeuroconv/manage_neuroconv.py index 1aaf6e1ce..f5b898e72 100644 --- a/pyflask/manageNeuroconv/manage_neuroconv.py +++ b/pyflask/manageNeuroconv/manage_neuroconv.py @@ -7,7 +7,7 @@ from pathlib import Path from sse import MessageAnnouncer -from .info import STUB_SAVE_FOLDER_PATH, CONVERSION_SAVE_FOLDER_PATH, TUTORIAL_SAVE_FOLDER_PATH +from .info import GUIDE_ROOT_FOLDER, STUB_SAVE_FOLDER_PATH, CONVERSION_SAVE_FOLDER_PATH, TUTORIAL_SAVE_FOLDER_PATH announcer = MessageAnnouncer() @@ -418,3 +418,84 @@ def generate_dataset(test_data_directory_path: str): phy_output_dir.symlink_to(phy_base_directory, True) return {"output_directory": str(output_directory)} + +def inspect_nwb_file(payload): + import json + from nwbinspector import inspect_nwbfile + from nwbinspector.nwbinspector import InspectorOutputJSONEncoder + + return json.loads( + json.dumps( + list( + inspect_nwbfile( + ignore=[ + "check_description", + "check_data_orientation", + ], # TODO: remove when metadata control is exposed + **payload, + ) + ), + cls=InspectorOutputJSONEncoder, + ) + ) + + +def inspect_nwb_file(payload): + import json + from nwbinspector import inspect_nwbfile + from nwbinspector.nwbinspector import InspectorOutputJSONEncoder + + return json.loads( + json.dumps( + list( + inspect_nwbfile( + ignore=[ + "check_description", + "check_data_orientation", + ], # TODO: remove when metadata control is exposed + **payload, + ) + ), + cls=InspectorOutputJSONEncoder, + ) + ) + +def inspect_nwb_folder(payload): + + import json + from nwbinspector import inspect_all + from nwbinspector.nwbinspector import InspectorOutputJSONEncoder + + messages = list( + inspect_all( + n_jobs=-2, # uses number of CPU - 1 + ignore=[ + "check_description", + "check_data_orientation", + ], # TODO: remove when metadata control is exposed + **payload, + ) + ) + + # messages = organize_messages(messages, levels=["importance", "message"]) + + return json.loads(json.dumps(messages, cls=InspectorOutputJSONEncoder)) + + +def aggregate_in_temp_directory(paths, reason = ''): + + tmp_folder_path = GUIDE_ROOT_FOLDER / ".temp" / reason / f"temp_{datetime.now().strftime('%Y%m%d-%H%M%S')}" + tmp_folder_path.mkdir(parents=True) + + for path in paths: + path = Path(path) + (tmp_folder_path / path.name).symlink_to(path, path.is_dir()) + + return tmp_folder_path + + +def inspect_multiple_filesystem_objects(paths): + tmp_folder_path = aggregate_in_temp_directory(paths, 'inspect') + result = inspect_nwb_folder({"path": tmp_folder_path}) + rmtree(tmp_folder_path) + return result diff --git a/src/renderer/src/stories/FileSystemSelector.js b/src/renderer/src/stories/FileSystemSelector.js index df79bc57f..fdf71b649 100644 --- a/src/renderer/src/stories/FileSystemSelector.js +++ b/src/renderer/src/stories/FileSystemSelector.js @@ -10,7 +10,7 @@ function getObjectTypeReferenceString(type, multiple, { nested, native } = {}) { .join(" / ")}`; const isDir = type === "directory"; - return multiple && (!isDir || (isDir && !native)) + return multiple && (!isDir || (isDir && !native) || dialog) ? type === "directory" ? "directories" : "files" @@ -122,7 +122,7 @@ export class FilesystemSelector extends LitElement { }; #onCancel = () => { - this.#onThrow(`No ${this.type} selected`, "The request was cancelled by the user"); + this.#onThrow(`No ${getObjectTypeReferenceString(this.type, this.multiple, { native: true })} selected`, "The request was cancelled by the user"); }; #checkType = (value) => { @@ -133,12 +133,13 @@ export class FilesystemSelector extends LitElement { #handleFiles = async (pathOrPaths) => { if (!pathOrPaths) - this.#onThrow("No paths detected", `Unable to parse ${this.type} path${this.multiple ? "s" : ""}`); + this.#onThrow("No paths detected", `Unable to parse ${getObjectTypeReferenceString(this.type, false, { native: true })} path${this.multiple ? "s" : ""}`); if (Array.isArray(pathOrPaths)) pathOrPaths.forEach(this.#checkType); else this.#checkType(pathOrPaths); let resolvedValue = pathOrPaths; + if (Array.isArray(resolvedValue) && !this.multiple) { if (resolvedValue.length > 1) this.#onThrow( @@ -158,9 +159,9 @@ export class FilesystemSelector extends LitElement { async selectFormat(type = this.type) { if (dialog) { - const file = await this.#useElectronDialog(type); - const path = file.filePath ?? file.filePaths?.[0]; - this.#handleFiles(path); + const results = await this.#useElectronDialog(type); + // const path = file.filePath ?? file.filePaths?.[0]; + this.#handleFiles(results.filePath ?? results.filePaths); } else { let handles = await (type === "directory" ? window.showDirectoryPicker() @@ -168,6 +169,7 @@ export class FilesystemSelector extends LitElement { ).catch((e) => this.#onCancel()); // Call using the same options const result = Array.isArray(handles) ? handles.map((o) => o.name) : handles.name; + console.log(result, handles) this.#handleFiles(result); } } @@ -236,11 +238,9 @@ export class FilesystemSelector extends LitElement { >Drop ${objectTypeReference} here${isMultipleTypes ? "" - : `, or click to choose ${getObjectTypeReferenceString(this.type, this.multiple, { - native: true, - })}`}${this.multiple && - (this.type === "directory" || (isMultipleTypes && this.type.includes("directory"))) + (this.type === "directory" || (isMultipleTypes && this.type.includes("directory") && !dialog)) ? html`
Multiple directory support only available using drag-and-drop.` diff --git a/src/renderer/src/stories/JSONSchemaInput.js b/src/renderer/src/stories/JSONSchemaInput.js index e7391570e..ecde119a5 100644 --- a/src/renderer/src/stories/JSONSchemaInput.js +++ b/src/renderer/src/stories/JSONSchemaInput.js @@ -148,6 +148,8 @@ export class JSONSchemaInput extends LitElement { `; } + #onThrow = (...args) => this.onThrow ? this.onThrow(...args) : this.form?.onThrow(...args) + #render() { const { validateOnChange, info, path: fullPath } = this; @@ -157,7 +159,8 @@ export class JSONSchemaInput extends LitElement { const isArray = info.type === "array"; // Handle string (and related) formats / types const hasItemsRef = "items" in info && "$ref" in info.items; - if (!("items" in info) || (!("type" in info.items) && !hasItemsRef)) info.items = { type: "string" }; + if (!("items" in info)) info.items = {}; + if (!("type" in info.items) && !hasItemsRef) info.items.type = "string" ; // Handle file and directory formats const createFilesystemSelector = (format) => { @@ -166,7 +169,7 @@ export class JSONSchemaInput extends LitElement { value: this.value, onSelect: (filePath) => this.#updateData(fullPath, filePath), onChange: (filePath) => validateOnChange && this.#triggerValidation(name, el, path), - onThrow: (...args) => this.form?.onThrow(...args), + onThrow: (...args) => this.#onThrow(...args), dialogOptions: this.form?.dialogOptions, dialogType: this.form?.dialogType, multiple: isArray, @@ -203,7 +206,7 @@ export class JSONSchemaInput extends LitElement { this.form.checkAllLoaded(); } }, - onThrow: (...args) => this.form?.onThrow(...args), + onThrow: (...args) => this.#onThrow(...args) }; return (this.form.tables[name] = diff --git a/src/renderer/src/stories/pages/inspect/InspectPage.js b/src/renderer/src/stories/pages/inspect/InspectPage.js index 5b5164a2c..96d4c8fbb 100644 --- a/src/renderer/src/stories/pages/inspect/InspectPage.js +++ b/src/renderer/src/stories/pages/inspect/InspectPage.js @@ -6,7 +6,7 @@ import { Button } from "../../Button.js"; import { run } from "../guided-mode/options/utils.js"; import { JSONSchemaInput } from "../../JSONSchemaInput.js"; import { Modal } from "../../Modal"; -import { truncateFilePaths } from "../../preview/NWBFilePreview.js"; +import { getSharedPath, truncateFilePaths } from "../../preview/NWBFilePreview.js"; import { InspectorList } from "../../preview/inspector/InspectorList.js"; export class InspectPage extends Page { @@ -15,25 +15,30 @@ export class InspectPage extends Page { } showReport = async (value) => { + if (!value) { - const message = "Please provide a folder to inspect."; + const message = "Please provide filesystem entries to inspect."; onThrow(message); throw new Error(message); } + const result = await run("inspect", { paths: value }, { title: "Inspecting selected filesystem entries." }).catch((e) => { + this.notify(e.message, "error"); + throw e; + }) + + if (!result.length) return this.notify('No messages received from the NWB Inspector') + const items = truncateFilePaths( - await run("inspect_folder", { path: value }, { title: "Inspecting your files" }).catch((e) => { - this.notify(e.message, "error"); - throw e; - }), - value + result, + getSharedPath(result.map(o => o.file_path)) ); const list = new InspectorList({ items }); list.style.padding = "25px"; const modal = new Modal({ - header: value, + header: value.length === 1 ? value : `Selected Filesystem Entries`, }); modal.append(list); document.body.append(modal); @@ -42,17 +47,20 @@ export class InspectPage extends Page { }; input = new JSONSchemaInput({ - path: ["folder_path"], + path: ["filesystem_paths"], info: { - type: "string", - format: "directory", + type: "array", + items: { + format: ["file", "directory"], + multiple: true + } }, onThrow, }); render() { const button = new Button({ - label: "Inspect Files", + label: "Start Inspection", onClick: async () => this.showReport(this.input.value), }); From 8b9f105a64f967e7f62a261285d7b14dbbc5d76a Mon Sep 17 00:00:00 2001 From: Garrett Date: Fri, 15 Sep 2023 09:21:25 -0700 Subject: [PATCH 2/6] Update manage_neuroconv.py --- pyflask/manageNeuroconv/manage_neuroconv.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyflask/manageNeuroconv/manage_neuroconv.py b/pyflask/manageNeuroconv/manage_neuroconv.py index f5b898e72..b3da52419 100644 --- a/pyflask/manageNeuroconv/manage_neuroconv.py +++ b/pyflask/manageNeuroconv/manage_neuroconv.py @@ -420,7 +420,6 @@ def generate_dataset(test_data_directory_path: str): return {"output_directory": str(output_directory)} def inspect_nwb_file(payload): - import json from nwbinspector import inspect_nwbfile from nwbinspector.nwbinspector import InspectorOutputJSONEncoder @@ -441,7 +440,6 @@ def inspect_nwb_file(payload): def inspect_nwb_file(payload): - import json from nwbinspector import inspect_nwbfile from nwbinspector.nwbinspector import InspectorOutputJSONEncoder @@ -462,7 +460,6 @@ def inspect_nwb_file(payload): def inspect_nwb_folder(payload): - import json from nwbinspector import inspect_all from nwbinspector.nwbinspector import InspectorOutputJSONEncoder From da51e2a24d96b2d98796e81388316b6d46745ea7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:23:49 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyflask/apis/neuroconv.py | 14 ++++++------- pyflask/manageNeuroconv/__init__.py | 2 +- pyflask/manageNeuroconv/info/__init__.py | 8 +++++++- pyflask/manageNeuroconv/manage_neuroconv.py | 18 ++++++++--------- .../src/stories/FileSystemSelector.js | 18 +++++++++++++---- src/renderer/src/stories/JSONSchemaInput.js | 8 ++++---- .../src/stories/pages/inspect/InspectPage.js | 20 +++++++++---------- 7 files changed, 51 insertions(+), 37 deletions(-) diff --git a/pyflask/apis/neuroconv.py b/pyflask/apis/neuroconv.py index 0db136328..ea9ade85e 100644 --- a/pyflask/apis/neuroconv.py +++ b/pyflask/apis/neuroconv.py @@ -15,7 +15,7 @@ generate_dataset, inspect_nwb_file, inspect_nwb_folder, - inspect_multiple_filesystem_objects + inspect_multiple_filesystem_objects, ) from errorHandlers import notBadRequestException @@ -151,7 +151,6 @@ def post(self): neuroconv_api.abort(500, str(e)) - @neuroconv_api.route("/inspect_folder") class InspectNWBFolder(Resource): @neuroconv_api.doc(responses={200: "Success", 400: "Bad Request", 500: "Internal server error"}) @@ -168,21 +167,20 @@ def post(self): class InspectNWBFolder(Resource): @neuroconv_api.doc(responses={200: "Success", 400: "Bad Request", 500: "Internal server error"}) def post(self): - from os.path import isfile try: paths = neuroconv_api.payload["paths"] - if (len(paths) == 1): - if (isfile(paths[0])): - return inspect_nwb_file({ "path": paths[0] }) + if len(paths) == 1: + if isfile(paths[0]): + return inspect_nwb_file({"path": paths[0]}) else: - return inspect_nwb_folder({ "path": paths[0] }) + return inspect_nwb_folder({"path": paths[0]}) else: return inspect_multiple_filesystem_objects(paths) - + except Exception as e: if notBadRequestException(e): neuroconv_api.abort(500, str(e)) diff --git a/pyflask/manageNeuroconv/__init__.py b/pyflask/manageNeuroconv/__init__.py index 8adea2add..b3fae5e89 100644 --- a/pyflask/manageNeuroconv/__init__.py +++ b/pyflask/manageNeuroconv/__init__.py @@ -11,7 +11,7 @@ generate_dataset, inspect_nwb_file, inspect_nwb_folder, - inspect_multiple_filesystem_objects + inspect_multiple_filesystem_objects, ) diff --git a/pyflask/manageNeuroconv/info/__init__.py b/pyflask/manageNeuroconv/info/__init__.py index 6d76218b7..f1fa1a023 100644 --- a/pyflask/manageNeuroconv/info/__init__.py +++ b/pyflask/manageNeuroconv/info/__init__.py @@ -1 +1,7 @@ -from .urls import resource_path, GUIDE_ROOT_FOLDER, STUB_SAVE_FOLDER_PATH, CONVERSION_SAVE_FOLDER_PATH, TUTORIAL_SAVE_FOLDER_PATH +from .urls import ( + resource_path, + GUIDE_ROOT_FOLDER, + STUB_SAVE_FOLDER_PATH, + CONVERSION_SAVE_FOLDER_PATH, + TUTORIAL_SAVE_FOLDER_PATH, +) diff --git a/pyflask/manageNeuroconv/manage_neuroconv.py b/pyflask/manageNeuroconv/manage_neuroconv.py index b3da52419..0e1512d4d 100644 --- a/pyflask/manageNeuroconv/manage_neuroconv.py +++ b/pyflask/manageNeuroconv/manage_neuroconv.py @@ -419,6 +419,7 @@ def generate_dataset(test_data_directory_path: str): return {"output_directory": str(output_directory)} + def inspect_nwb_file(payload): from nwbinspector import inspect_nwbfile from nwbinspector.nwbinspector import InspectorOutputJSONEncoder @@ -458,8 +459,8 @@ def inspect_nwb_file(payload): ) ) -def inspect_nwb_folder(payload): +def inspect_nwb_folder(payload): from nwbinspector import inspect_all from nwbinspector.nwbinspector import InspectorOutputJSONEncoder @@ -479,20 +480,19 @@ def inspect_nwb_folder(payload): return json.loads(json.dumps(messages, cls=InspectorOutputJSONEncoder)) -def aggregate_in_temp_directory(paths, reason = ''): - +def aggregate_in_temp_directory(paths, reason=""): tmp_folder_path = GUIDE_ROOT_FOLDER / ".temp" / reason / f"temp_{datetime.now().strftime('%Y%m%d-%H%M%S')}" tmp_folder_path.mkdir(parents=True) for path in paths: - path = Path(path) - (tmp_folder_path / path.name).symlink_to(path, path.is_dir()) + path = Path(path) + (tmp_folder_path / path.name).symlink_to(path, path.is_dir()) return tmp_folder_path def inspect_multiple_filesystem_objects(paths): - tmp_folder_path = aggregate_in_temp_directory(paths, 'inspect') - result = inspect_nwb_folder({"path": tmp_folder_path}) - rmtree(tmp_folder_path) - return result + tmp_folder_path = aggregate_in_temp_directory(paths, "inspect") + result = inspect_nwb_folder({"path": tmp_folder_path}) + rmtree(tmp_folder_path) + return result diff --git a/src/renderer/src/stories/FileSystemSelector.js b/src/renderer/src/stories/FileSystemSelector.js index fdf71b649..d03491ca1 100644 --- a/src/renderer/src/stories/FileSystemSelector.js +++ b/src/renderer/src/stories/FileSystemSelector.js @@ -122,7 +122,10 @@ export class FilesystemSelector extends LitElement { }; #onCancel = () => { - this.#onThrow(`No ${getObjectTypeReferenceString(this.type, this.multiple, { native: true })} selected`, "The request was cancelled by the user"); + this.#onThrow( + `No ${getObjectTypeReferenceString(this.type, this.multiple, { native: true })} selected`, + "The request was cancelled by the user" + ); }; #checkType = (value) => { @@ -133,7 +136,12 @@ export class FilesystemSelector extends LitElement { #handleFiles = async (pathOrPaths) => { if (!pathOrPaths) - this.#onThrow("No paths detected", `Unable to parse ${getObjectTypeReferenceString(this.type, false, { native: true })} path${this.multiple ? "s" : ""}`); + this.#onThrow( + "No paths detected", + `Unable to parse ${getObjectTypeReferenceString(this.type, false, { native: true })} path${ + this.multiple ? "s" : "" + }` + ); if (Array.isArray(pathOrPaths)) pathOrPaths.forEach(this.#checkType); else this.#checkType(pathOrPaths); @@ -169,7 +177,7 @@ export class FilesystemSelector extends LitElement { ).catch((e) => this.#onCancel()); // Call using the same options const result = Array.isArray(handles) ? handles.map((o) => o.name) : handles.name; - console.log(result, handles) + console.log(result, handles); this.#handleFiles(result); } } @@ -238,7 +246,9 @@ export class FilesystemSelector extends LitElement { >Drop ${objectTypeReference} here${isMultipleTypes ? "" - : `, or click to choose ${getObjectTypeReferenceString(this.type, this.multiple, { native: true })}`}${this.multiple && (this.type === "directory" || (isMultipleTypes && this.type.includes("directory") && !dialog)) ? html`
this.onThrow ? this.onThrow(...args) : this.form?.onThrow(...args) + #onThrow = (...args) => (this.onThrow ? this.onThrow(...args) : this.form?.onThrow(...args)); #render() { const { validateOnChange, info, path: fullPath } = this; @@ -159,8 +159,8 @@ export class JSONSchemaInput extends LitElement { const isArray = info.type === "array"; // Handle string (and related) formats / types const hasItemsRef = "items" in info && "$ref" in info.items; - if (!("items" in info)) info.items = {}; - if (!("type" in info.items) && !hasItemsRef) info.items.type = "string" ; + if (!("items" in info)) info.items = {}; + if (!("type" in info.items) && !hasItemsRef) info.items.type = "string"; // Handle file and directory formats const createFilesystemSelector = (format) => { @@ -206,7 +206,7 @@ export class JSONSchemaInput extends LitElement { this.form.checkAllLoaded(); } }, - onThrow: (...args) => this.#onThrow(...args) + onThrow: (...args) => this.#onThrow(...args), }; return (this.form.tables[name] = diff --git a/src/renderer/src/stories/pages/inspect/InspectPage.js b/src/renderer/src/stories/pages/inspect/InspectPage.js index 96d4c8fbb..b2889987a 100644 --- a/src/renderer/src/stories/pages/inspect/InspectPage.js +++ b/src/renderer/src/stories/pages/inspect/InspectPage.js @@ -15,24 +15,24 @@ export class InspectPage extends Page { } showReport = async (value) => { - if (!value) { const message = "Please provide filesystem entries to inspect."; onThrow(message); throw new Error(message); } - const result = await run("inspect", { paths: value }, { title: "Inspecting selected filesystem entries." }).catch((e) => { + const result = await run( + "inspect", + { paths: value }, + { title: "Inspecting selected filesystem entries." } + ).catch((e) => { this.notify(e.message, "error"); throw e; - }) + }); - if (!result.length) return this.notify('No messages received from the NWB Inspector') + if (!result.length) return this.notify("No messages received from the NWB Inspector"); - const items = truncateFilePaths( - result, - getSharedPath(result.map(o => o.file_path)) - ); + const items = truncateFilePaths(result, getSharedPath(result.map((o) => o.file_path))); const list = new InspectorList({ items }); list.style.padding = "25px"; @@ -52,8 +52,8 @@ export class InspectPage extends Page { type: "array", items: { format: ["file", "directory"], - multiple: true - } + multiple: true, + }, }, onThrow, }); From d80cb1fc8df6c2d2f439b4a31fe43594626adaa4 Mon Sep 17 00:00:00 2001 From: Garrett Date: Thu, 28 Sep 2023 14:49:50 -0700 Subject: [PATCH 4/6] Create subfolders and only create symlinks for files --- pyflask/manageNeuroconv/manage_neuroconv.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pyflask/manageNeuroconv/manage_neuroconv.py b/pyflask/manageNeuroconv/manage_neuroconv.py index 0e1512d4d..8a28682f7 100644 --- a/pyflask/manageNeuroconv/manage_neuroconv.py +++ b/pyflask/manageNeuroconv/manage_neuroconv.py @@ -480,19 +480,25 @@ def inspect_nwb_folder(payload): return json.loads(json.dumps(messages, cls=InspectorOutputJSONEncoder)) -def aggregate_in_temp_directory(paths, reason=""): - tmp_folder_path = GUIDE_ROOT_FOLDER / ".temp" / reason / f"temp_{datetime.now().strftime('%Y%m%d-%H%M%S')}" - tmp_folder_path.mkdir(parents=True) +def aggregate_symlinks_in_new_directory(paths, reason="", folder_path = None): + if (folder_path is None): + folder_path = GUIDE_ROOT_FOLDER / ".temp" / reason / f"temp_{datetime.now().strftime('%Y%m%d-%H%M%S')}" + + folder_path.mkdir(parents=True) for path in paths: path = Path(path) - (tmp_folder_path / path.name).symlink_to(path, path.is_dir()) + new_path = folder_path / path.name + if (path.is_dir()): + aggregate_symlinks_in_new_directory(list(map(lambda name: os.path.join(path, name), os.listdir(path))), None, new_path) + else: + new_path.symlink_to(path, path.is_dir()) - return tmp_folder_path + return folder_path def inspect_multiple_filesystem_objects(paths): - tmp_folder_path = aggregate_in_temp_directory(paths, "inspect") + tmp_folder_path = aggregate_symlinks_in_new_directory(paths, "inspect") result = inspect_nwb_folder({"path": tmp_folder_path}) rmtree(tmp_folder_path) return result From 6e7cd7190b223ece69d6ffa8651eb4a28b888824 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 21:51:25 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyflask/manageNeuroconv/manage_neuroconv.py | 10 ++++++---- src/main/main.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pyflask/manageNeuroconv/manage_neuroconv.py b/pyflask/manageNeuroconv/manage_neuroconv.py index ec1b7347d..912f3acb3 100644 --- a/pyflask/manageNeuroconv/manage_neuroconv.py +++ b/pyflask/manageNeuroconv/manage_neuroconv.py @@ -559,8 +559,8 @@ def inspect_nwb_folder(payload): return json.loads(json.dumps(messages, cls=InspectorOutputJSONEncoder)) -def aggregate_symlinks_in_new_directory(paths, reason="", folder_path = None): - if (folder_path is None): +def aggregate_symlinks_in_new_directory(paths, reason="", folder_path=None): + if folder_path is None: folder_path = GUIDE_ROOT_FOLDER / ".temp" / reason / f"temp_{datetime.now().strftime('%Y%m%d-%H%M%S')}" folder_path.mkdir(parents=True) @@ -568,8 +568,10 @@ def aggregate_symlinks_in_new_directory(paths, reason="", folder_path = None): for path in paths: path = Path(path) new_path = folder_path / path.name - if (path.is_dir()): - aggregate_symlinks_in_new_directory(list(map(lambda name: os.path.join(path, name), os.listdir(path))), None, new_path) + if path.is_dir(): + aggregate_symlinks_in_new_directory( + list(map(lambda name: os.path.join(path, name), os.listdir(path))), None, new_path + ) else: new_path.symlink_to(path, path.is_dir()) diff --git a/src/main/main.ts b/src/main/main.ts index 0f78f25c1..f15f363fb 100755 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -184,7 +184,7 @@ const exitPyProc = async () => { const killAllPreviousProcesses = async () => { const fetch = globalThis.fetch - + if (fetch){ console.log("Killing all previous processes"); From e60e6d922b8cc44318fe196ea8ee07ef79311f36 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 22:11:11 +0000 Subject: [PATCH 6/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/renderer/src/progress/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/src/progress/index.js b/src/renderer/src/progress/index.js index b30fb5eb7..14bc2a2f1 100644 --- a/src/renderer/src/progress/index.js +++ b/src/renderer/src/progress/index.js @@ -42,7 +42,7 @@ function decode(message) { function drill(o, callback) { if (o && typeof o === "object") { - const copy = Array.isArray(o) ? [...o] : { ...o } ; + const copy = Array.isArray(o) ? [...o] : { ...o }; for (let k in copy) copy[k] = drill(copy[k], callback); return copy; } else return callback(o);