|
@@ -1,5 +1,5 @@
|
|
|
/**
|
|
|
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
*
|
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
|
*/
|
|
@@ -13,6 +13,27 @@ import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
|
|
import { unzip } from '../../mol-util/zip/zip';
|
|
|
import { PluginStateObject } from '../objects';
|
|
|
|
|
|
+async function processFile(file: Asset.File, plugin: PluginContext, format: string, visuals: boolean) {
|
|
|
+ const info = getFileInfo(file.file!);
|
|
|
+ const isBinary = plugin.dataFormats.binaryExtensions.has(info.ext);
|
|
|
+ const { data } = await plugin.builders.data.readFile({ file, isBinary });
|
|
|
+ const provider = format === 'auto'
|
|
|
+ ? plugin.dataFormats.auto(info, data.cell?.obj!)
|
|
|
+ : plugin.dataFormats.get(format);
|
|
|
+
|
|
|
+ if (!provider) {
|
|
|
+ plugin.log.warn(`OpenFiles: could not find data provider for '${info.name}.${info.ext}'`);
|
|
|
+ await plugin.state.data.build().delete(data).commit();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // need to await so that the enclosing Task finishes after the update is done.
|
|
|
+ const parsed = await provider.parse(plugin, data);
|
|
|
+ if (visuals) {
|
|
|
+ await provider.visuals?.(plugin, parsed);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
export const OpenFiles = StateAction.build({
|
|
|
display: { name: 'Open Files', description: 'Load one or more files and optionally create default visuals' },
|
|
|
from: PluginStateObject.Root,
|
|
@@ -36,36 +57,19 @@ export const OpenFiles = StateAction.build({
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- const processFile = async (file: Asset.File) => {
|
|
|
- const info = getFileInfo(file.file!);
|
|
|
- const isBinary = plugin.dataFormats.binaryExtensions.has(info.ext);
|
|
|
- const { data } = await plugin.builders.data.readFile({ file, isBinary });
|
|
|
- const provider = params.format.name === 'auto'
|
|
|
- ? plugin.dataFormats.auto(info, data.cell?.obj!)
|
|
|
- : plugin.dataFormats.get(params.format.params);
|
|
|
-
|
|
|
- if (!provider) {
|
|
|
- plugin.log.warn(`OpenFiles: could not find data provider for '${info.name}.${info.ext}'`);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // need to await so that the enclosing Task finishes after the update is done.
|
|
|
- const parsed = await provider.parse(plugin, data);
|
|
|
- if (params.visuals) {
|
|
|
- await provider.visuals?.(plugin, parsed);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
for (const file of params.files) {
|
|
|
try {
|
|
|
if (file.file && file.name.toLowerCase().endsWith('.zip')) {
|
|
|
const zippedFiles = await unzip(taskCtx, await file.file.arrayBuffer());
|
|
|
for (const [fn, filedata] of Object.entries(zippedFiles)) {
|
|
|
- const asset = Asset.File(new File([filedata as Uint8Array], fn));
|
|
|
- await processFile(asset);
|
|
|
+ if (!(filedata instanceof Uint8Array) || filedata.length === 0) continue;
|
|
|
+
|
|
|
+ const asset = Asset.File(new File([filedata], fn));
|
|
|
+ await processFile(asset, plugin, 'auto', params.visuals);
|
|
|
}
|
|
|
} else {
|
|
|
- await processFile(file);
|
|
|
+ const format = params.format.name === 'auto' ? 'auto' : params.format.params;
|
|
|
+ await processFile(file, plugin, format, params.visuals);
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.error(e);
|
|
@@ -79,7 +83,7 @@ export const DownloadFile = StateAction.build({
|
|
|
display: { name: 'Download File', description: 'Load one or more file from an URL' },
|
|
|
from: PluginStateObject.Root,
|
|
|
params: (a, ctx: PluginContext) => {
|
|
|
- const { options } = ctx.dataFormats;
|
|
|
+ const options = [...ctx.dataFormats.options, ['zip', 'Zip'] as const];
|
|
|
return {
|
|
|
url: PD.Url(''),
|
|
|
format: PD.Select(options[0][0], options),
|
|
@@ -92,16 +96,30 @@ export const DownloadFile = StateAction.build({
|
|
|
|
|
|
await state.transaction(async () => {
|
|
|
try {
|
|
|
- const provider = plugin.dataFormats.get(params.format);
|
|
|
- if (!provider) {
|
|
|
- plugin.log.warn(`DownloadFile: could not find data provider for '${params.format}'`);
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (params.format === 'zip') {
|
|
|
+ // TODO: add ReadZipFile transformer so this can be saved as a simple state snaphot,
|
|
|
+ // would need support for extracting individual files from zip
|
|
|
+ const data = await plugin.builders.data.download({ url: params.url, isBinary: true });
|
|
|
+ const zippedFiles = await unzip(taskCtx, (data.obj?.data as Uint8Array).buffer);
|
|
|
+ for (const [fn, filedata] of Object.entries(zippedFiles)) {
|
|
|
+ if (!(filedata instanceof Uint8Array) || filedata.length === 0) continue;
|
|
|
+
|
|
|
+ const asset = Asset.File(new File([filedata], fn));
|
|
|
|
|
|
- const data = await plugin.builders.data.download({ url: params.url, isBinary: params.isBinary });
|
|
|
- const parsed = await provider.parse(plugin, data);
|
|
|
- if (params.visuals) {
|
|
|
- await provider.visuals?.(plugin, parsed);
|
|
|
+ await processFile(asset, plugin, 'auto', params.visuals);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const provider = plugin.dataFormats.get(params.format);
|
|
|
+ if (!provider) {
|
|
|
+ plugin.log.warn(`DownloadFile: could not find data provider for '${params.format}'`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const data = await plugin.builders.data.download({ url: params.url, isBinary: params.isBinary });
|
|
|
+ const parsed = await provider.parse(plugin, data);
|
|
|
+ if (params.visuals) {
|
|
|
+ await provider.visuals?.(plugin, parsed);
|
|
|
+ }
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.error(e);
|