diff --git a/web/src/views/FileBrowserView/FileBrowser.vue b/web/src/views/FileBrowserView/FileBrowser.vue index 8907f9ba9..da050c105 100644 --- a/web/src/views/FileBrowserView/FileBrowser.vue +++ b/web/src/views/FileBrowserView/FileBrowser.vue @@ -265,7 +265,7 @@ import axios from 'axios'; import { dandiRest } from '@/rest'; import { useDandisetStore } from '@/stores/dandiset'; -import type { AssetFile, AssetPath } from '@/types'; +import type { AssetPath } from '@/types'; import FileBrowserPagination from '@/components/FileBrowser/FileBrowserPagination.vue'; import FileUploadInstructions from '@/components/FileBrowser/FileUploadInstructions.vue'; @@ -309,35 +309,35 @@ const EXTERNAL_SERVICES = [ name: 'Bioimagesuite/Viewer', regex: /\.nii(\.gz)?$/, maxsize: 1e9, - endpoint: 'https://bioimagesuiteweb.github.io/unstableapp/viewer.html?image=', + endpoint: 'https://bioimagesuiteweb.github.io/unstableapp/viewer.html?image=$asset_s3_download_url$', }, { name: 'MetaCell/NWBExplorer', regex: /\.nwb$/, maxsize: 1e9, - endpoint: 'http://nwbexplorer.opensourcebrain.org/nwbfile=', + endpoint: 'http://nwbexplorer.opensourcebrain.org/nwbfile=$asset_s3_download_url$', }, { name: 'VTK/ITK Viewer', regex: /\.ome\.zarr$/, maxsize: Infinity, - endpoint: 'https://kitware.github.io/itk-vtk-viewer/app/?gradientOpacity=0.3&image=', + endpoint: 'https://kitware.github.io/itk-vtk-viewer/app/?gradientOpacity=0.3&image=$asset_s3_download_url$', }, { name: 'OME Zarr validator', regex: /\.ome\.zarr$/, maxsize: Infinity, - endpoint: 'https://ome.github.io/ome-ngff-validator/?source=', + endpoint: 'https://ome.github.io/ome-ngff-validator/?source=$asset_s3_download_url$', }, { name: 'Neurosift', regex: /\.nwb$/, maxsize: Infinity, - endpoint: 'https://flatironinstitute.github.io/neurosift?p=/nwb&url=', + endpoint: 'https://flatironinstitute.github.io/neurosift?p=/nwb&url=$asset_api_download_url$', }, ]; type Service = typeof EXTERNAL_SERVICES[0]; @@ -377,6 +377,18 @@ const isOwner = computed(() => !!( )); const itemsNotFound = computed(() => items.value && !items.value.length); +function replaceStringsInEndpoint( + endpoint: string, + substitutions: {[key: string]: string} | undefined, +) { + if (!substitutions) return endpoint; + let result = endpoint; + Object.entries(substitutions).forEach(([key, value]) => { + result = result.replace(key, value); + }); + return result; +} + function getExternalServices(path: AssetPath) { const servicePredicate = (service: Service, _path: AssetPath) => ( new RegExp(service.regex).test(path.path) @@ -384,11 +396,19 @@ function getExternalServices(path: AssetPath) { && _path.aggregate_size <= service.maxsize ); + const baseApiUrl = trimEnd(process.env.VUE_APP_DANDI_API_ROOT, '/'); + + const substitutions = path.asset ? { + $asset_s3_download_url$: trimEnd(path.asset.url, '/'), + $asset_api_download_url$: `${baseApiUrl}/assets/${path.asset.asset_id}/download/`, + $asset_id$: path.asset.asset_id, + } : undefined; + return EXTERNAL_SERVICES .filter((service) => servicePredicate(service, path)) .map((service) => ({ name: service.name, - url: `${service.endpoint}${trimEnd((path.asset as AssetFile).url, '/')}`, + url: replaceStringsInEndpoint(service.endpoint, substitutions), })); }