silx-kit / h5web

React components for data visualization and exploration
https://h5web.panosc.eu/
MIT License
183 stars 18 forks source link

Allow loading of files with non-standard extensions in h5wasm demo #1126

Closed bmaranville closed 2 years ago

bmaranville commented 2 years ago

Is your feature request related to a problem?

This is just a minor issue - all of our NeXus files are written with a file name matching this format: long_filename0001.nxs.<instrument-specific-extension> where the instrument-specific extension is something like cgd or vsans The way the dropzone loader is configure in the h5wasm demo, none of our files will load without changing the extension and re-saving the file.

Requested solution or feature

Reconfigure dropzone configuration so that it will still allow loading when the extension doesn't match one of the items in the list:

const EXT = ['.h5', '.hdf5', '.hdf', '.nx', '.nx5', '.nexus', '.nxs', '.cxi'];

It is probably still preferred that those extensions are used to populate the search in the file loader dialog, but then disabling the strict check in react-dropzone that forbids loading files with other extensions would be useful.

Alternatives you've considered

Additional context

I'd be happy to help out with this.

axelboc commented 2 years ago

Totally agree, but I was under the impression that allowing all extensions, while still filtering files in the file loader dialog was not possible due to both features being controlled by the same accept configuration (and HTML attribute). Is there a workaround that I'm not aware of, like passing a validator function to react-dropzone or something? If so, then please do share it in a PR. :raised_hands:

bmaranville commented 2 years ago

In principle, they are separate - but the library is controlling them from the same list. You can select files in the file picker that don't match the suggested glob pattern, but there is a bit of code in the library that is then checking the filename and rejecting ones that don't match. A custom validator could solve the problem. We could even test for the HDF5 magic number with a custom validator... so maybe that's the way to go!

axelboc commented 2 years ago

Since you mention it, we've had a case where someone had an HDF5 file that didn't quite start with the HDF5 magic number; there were a few bytes before it for some reason I can't remember. Not sure if this is spec-compliant, but because of the throw, we couldn't verify at the time whether h5wasm would have been able to handle the file anyway. Perhaps we should consider logging a warning instead of throwing an error?

bmaranville commented 2 years ago

Unfortunately the validators in react-dropzone are not allowed to be async, so they can't inspect the file contents.

bmaranville commented 2 years ago

While it would be nice to inspect the file to check for the HDF5 signature, this very small change will populate the file picker with the appropriate filters, but will still allow files that don't match the patterns to be loaded (by selecting "All Files" in the picker).

diff --git a/apps/demo/src/h5wasm/DropZone.tsx b/apps/demo/src/h5wasm/DropZone.tsx
index 83e10267..8daa9435 100644
--- a/apps/demo/src/h5wasm/DropZone.tsx
+++ b/apps/demo/src/h5wasm/DropZone.tsx
@@ -31,7 +31,6 @@ function DropZone(props: Props) {

   const { getRootProps, getInputProps, open, isDragActive, fileRejections } =
     useDropzone({
-      accept: { 'application/x-hdf5': EXT },
       multiple: false,
       noClick: true,
       noKeyboard: true,
@@ -46,7 +45,7 @@ function DropZone(props: Props) {
         'data-disabled': isReadingFile || undefined,
       })}
     >
-      <input {...getInputProps()} />
+      <input {...getInputProps()} accept={EXT.join(',')} />
       <div className={styles.inner}>
         {isDragActive ? (
           <p className={styles.dropIt}>Drop it!</p>