123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
- import { PluginStateTransform } from '../objects';
- import { PluginStateObject as SO } from '../objects';
- import { Task } from '../../mol-task';
- import { CIF } from '../../mol-io/reader/cif'
- import { PluginContext } from '../../mol-plugin/context';
- import { ParamDefinition as PD } from '../../mol-util/param-definition';
- import { StateTransformer, StateObject } from '../../mol-state';
- import { readFromFile, ajaxGetMany } from '../../mol-util/data-source';
- import * as CCP4 from '../../mol-io/reader/ccp4/parser'
- import * as DSN6 from '../../mol-io/reader/dsn6/parser'
- import * as PLY from '../../mol-io/reader/ply/parser'
- import { parsePsf } from '../../mol-io/reader/psf/parser';
- import { isTypedArray } from '../../mol-data/db/column-helpers';
- export { Download }
- type Download = typeof Download
- const Download = PluginStateTransform.BuiltIn({
- name: 'download',
- display: { name: 'Download', description: 'Download string or binary data from the specified URL' },
- from: [SO.Root],
- to: [SO.Data.String, SO.Data.Binary],
- params: {
- url: PD.Text('https://www.ebi.ac.uk/pdbe/static/entry/1cbs_updated.cif', { description: 'Resource URL. Must be the same domain or support CORS.' }),
- label: PD.Optional(PD.Text('')),
- isBinary: PD.Optional(PD.Boolean(false, { description: 'If true, download data as binary (string otherwise)' })),
- body: PD.Optional(PD.Text(''))
- }
- })({
- apply({ params: p }, globalCtx: PluginContext) {
- return Task.create('Download', async ctx => {
- const data = await globalCtx.fetch({ url: p.url, type: p.isBinary ? 'binary' : 'string', body: p.body }).runInContext(ctx);
- return p.isBinary
- ? new SO.Data.Binary(data as Uint8Array, { label: p.label ? p.label : p.url })
- : new SO.Data.String(data as string, { label: p.label ? p.label : p.url });
- });
- },
- update({ oldParams, newParams, b }) {
- if (oldParams.url !== newParams.url || oldParams.isBinary !== newParams.isBinary) return StateTransformer.UpdateResult.Recreate;
- if (oldParams.label !== newParams.label) {
- b.label = newParams.label || newParams.url;
- return StateTransformer.UpdateResult.Updated;
- }
- return StateTransformer.UpdateResult.Unchanged;
- }
- });
- export { DownloadBlob }
- type DownloadBlob = typeof DownloadBlob
- const DownloadBlob = PluginStateTransform.BuiltIn({
- name: 'download-blob',
- display: { name: 'Download Blob', description: 'Download multiple string or binary data from the specified URLs.' },
- from: SO.Root,
- to: SO.Data.Blob,
- params: {
- sources: PD.ObjectList({
- id: PD.Text('', { label: 'Unique ID' }),
- url: PD.Text('https://www.ebi.ac.uk/pdbe/static/entry/1cbs_updated.cif', { description: 'Resource URL. Must be the same domain or support CORS.' }),
- isBinary: PD.Optional(PD.Boolean(false, { description: 'If true, download data as binary (string otherwise)' })),
- body: PD.Optional(PD.Text('')),
- canFail: PD.Optional(PD.Boolean(false, { description: 'Indicate whether the download can fail and not be included in the blob as a result.' }))
- }, e => `${e.id}: ${e.url}`),
- maxConcurrency: PD.Optional(PD.Numeric(4, { min: 1, max: 12, step: 1 }, { description: 'The maximum number of concurrent downloads.' }))
- }
- })({
- apply({ params }, plugin: PluginContext) {
- return Task.create('Download Blob', async ctx => {
- const entries: SO.Data.BlobEntry[] = [];
- const data = await ajaxGetMany(ctx, params.sources, params.maxConcurrency || 4);
- for (let i = 0; i < data.length; i++) {
- const r = data[i], src = params.sources[i];
- if (r.kind === 'error') plugin.log.warn(`Download ${r.id} (${src.url}) failed: ${r.error}`);
- else {
- entries.push(src.isBinary
- ? { id: r.id, kind: 'binary', data: r.result as Uint8Array }
- : { id: r.id, kind: 'string', data: r.result as string });
- }
- }
- return new SO.Data.Blob(entries, { label: 'Data Blob', description: `${entries.length} ${entries.length === 1 ? 'entry' : 'entries'}` });
- });
- },
- // TODO: ??
- // update({ oldParams, newParams, b }) {
- // return 0 as any;
- // // if (oldParams.url !== newParams.url || oldParams.isBinary !== newParams.isBinary) return StateTransformer.UpdateResult.Recreate;
- // // if (oldParams.label !== newParams.label) {
- // // (b.label as string) = newParams.label || newParams.url;
- // // return StateTransformer.UpdateResult.Updated;
- // // }
- // // return StateTransformer.UpdateResult.Unchanged;
- // }
- });
- export { RawData }
- type RawData = typeof RawData
- const RawData = PluginStateTransform.BuiltIn({
- name: 'raw-data',
- display: { name: 'Raw Data', description: 'Raw data supplied by value.' },
- from: [SO.Root],
- to: [SO.Data.String, SO.Data.Binary],
- params: {
- data: PD.Value<string | number[]>('', { isHidden: true }),
- label: PD.Optional(PD.Text(''))
- }
- })({
- apply({ params: p }) {
- return Task.create('Raw Data', async () => {
- if (typeof p.data !== 'string' && isTypedArray(p.data)) {
- throw new Error('Supplied binary data must be a plain array.');
- }
- return typeof p.data === 'string'
- ? new SO.Data.String(p.data as string, { label: p.label ? p.label : 'String' })
- : new SO.Data.Binary(new Uint8Array(p.data), { label: p.label ? p.label : 'Binary' });
- });
- },
- update({ oldParams, newParams, b }) {
- if (oldParams.data !== newParams.data) return StateTransformer.UpdateResult.Recreate;
- if (oldParams.label !== newParams.label) {
- b.label = newParams.label || b.label;
- return StateTransformer.UpdateResult.Updated;
- }
- return StateTransformer.UpdateResult.Unchanged;
- }
- });
- export { ReadFile }
- type ReadFile = typeof ReadFile
- const ReadFile = PluginStateTransform.BuiltIn({
- name: 'read-file',
- display: { name: 'Read File', description: 'Read string or binary data from the specified file' },
- from: SO.Root,
- to: [SO.Data.String, SO.Data.Binary],
- params: {
- file: PD.File(),
- label: PD.Optional(PD.Text('')),
- isBinary: PD.Optional(PD.Boolean(false, { description: 'If true, open file as as binary (string otherwise)' }))
- }
- })({
- apply({ params: p }, plugin: PluginContext) {
- return Task.create('Open File', async ctx => {
- if (p.file === null) {
- plugin.log.error('No file(s) selected')
- return StateObject.Null;
- }
- const data = await readFromFile(p.file, p.isBinary ? 'binary' : 'string').runInContext(ctx);
- return p.isBinary
- ? new SO.Data.Binary(data as Uint8Array, { label: p.label ? p.label : p.file.name })
- : new SO.Data.String(data as string, { label: p.label ? p.label : p.file.name });
- });
- },
- update({ oldParams, newParams, b }) {
- if (oldParams.label !== newParams.label) {
- (b.label as string) = newParams.label || oldParams.file?.name || '';
- return StateTransformer.UpdateResult.Updated;
- }
- return StateTransformer.UpdateResult.Unchanged;
- },
- isSerializable: () => ({ isSerializable: false, reason: 'Cannot serialize user loaded files.' })
- });
- export { ParseBlob }
- type ParseBlob = typeof ParseBlob
- const ParseBlob = PluginStateTransform.BuiltIn({
- name: 'parse-blob',
- display: { name: 'Parse Blob', description: 'Parse multiple data enties' },
- from: SO.Data.Blob,
- to: SO.Format.Blob,
- params: {
- formats: PD.ObjectList({
- id: PD.Text('', { label: 'Unique ID' }),
- format: PD.Select<'cif'>('cif', [['cif', 'cif']])
- }, e => `${e.id}: ${e.format}`)
- }
- })({
- apply({ a, params }, plugin: PluginContext) {
- return Task.create('Parse Blob', async ctx => {
- const map = new Map<string, string>();
- for (const f of params.formats) map.set(f.id, f.format);
- const entries: SO.Format.BlobEntry[] = [];
- for (const e of a.data) {
- if (!map.has(e.id)) continue;
- const parsed = await (e.kind === 'string' ? CIF.parse(e.data) : CIF.parseBinary(e.data)).runInContext(ctx);
- if (parsed.isError) throw new Error(`${e.id}: ${parsed.message}`);
- entries.push({ id: e.id, kind: 'cif', data: parsed.result });
- }
- return new SO.Format.Blob(entries, { label: 'Format Blob', description: `${entries.length} ${entries.length === 1 ? 'entry' : 'entries'}` });
- });
- },
- // TODO: ??
- // update({ oldParams, newParams, b }) {
- // return 0 as any;
- // // if (oldParams.url !== newParams.url || oldParams.isBinary !== newParams.isBinary) return StateTransformer.UpdateResult.Recreate;
- // // if (oldParams.label !== newParams.label) {
- // // (b.label as string) = newParams.label || newParams.url;
- // // return StateTransformer.UpdateResult.Updated;
- // // }
- // // return StateTransformer.UpdateResult.Unchanged;
- // }
- });
- export { ParseCif }
- type ParseCif = typeof ParseCif
- const ParseCif = PluginStateTransform.BuiltIn({
- name: 'parse-cif',
- display: { name: 'Parse CIF', description: 'Parse CIF from String or Binary data' },
- from: [SO.Data.String, SO.Data.Binary],
- to: SO.Format.Cif
- })({
- apply({ a }) {
- return Task.create('Parse CIF', async ctx => {
- const parsed = await (SO.Data.String.is(a) ? CIF.parse(a.data) : CIF.parseBinary(a.data)).runInContext(ctx);
- if (parsed.isError) throw new Error(parsed.message);
- return new SO.Format.Cif(parsed.result);
- });
- }
- });
- export { ParsePsf }
- type ParsePsf = typeof ParsePsf
- const ParsePsf = PluginStateTransform.BuiltIn({
- name: 'parse-psf',
- display: { name: 'Parse PSF', description: 'Parse PSF from String data' },
- from: [SO.Data.String],
- to: SO.Format.Psf
- })({
- apply({ a }) {
- return Task.create('Parse PSF', async ctx => {
- const parsed = await parsePsf(a.data).runInContext(ctx);
- if (parsed.isError) throw new Error(parsed.message);
- return new SO.Format.Psf(parsed.result);
- });
- }
- });
- export { ParsePly }
- type ParsePly = typeof ParsePly
- const ParsePly = PluginStateTransform.BuiltIn({
- name: 'parse-ply',
- display: { name: 'Parse PLY', description: 'Parse PLY from String data' },
- from: [SO.Data.String],
- to: SO.Format.Ply
- })({
- apply({ a }) {
- return Task.create('Parse PLY', async ctx => {
- const parsed = await PLY.parse(a.data).runInContext(ctx);
- if (parsed.isError) throw new Error(parsed.message);
- return new SO.Format.Ply(parsed.result, { label: parsed.result.comments[0] || 'PLY Data' });
- });
- }
- });
- export { ParseCcp4 }
- type ParseCcp4 = typeof ParseCcp4
- const ParseCcp4 = PluginStateTransform.BuiltIn({
- name: 'parse-ccp4',
- display: { name: 'Parse CCP4/MRC/MAP', description: 'Parse CCP4/MRC/MAP from Binary data' },
- from: [SO.Data.Binary],
- to: SO.Format.Ccp4
- })({
- apply({ a }) {
- return Task.create('Parse CCP4/MRC/MAP', async ctx => {
- const parsed = await CCP4.parse(a.data).runInContext(ctx);
- if (parsed.isError) throw new Error(parsed.message);
- return new SO.Format.Ccp4(parsed.result);
- });
- }
- });
- export { ParseDsn6 }
- type ParseDsn6 = typeof ParseDsn6
- const ParseDsn6 = PluginStateTransform.BuiltIn({
- name: 'parse-dsn6',
- display: { name: 'Parse DSN6/BRIX', description: 'Parse CCP4/BRIX from Binary data' },
- from: [SO.Data.Binary],
- to: SO.Format.Dsn6
- })({
- apply({ a }) {
- return Task.create('Parse DSN6/BRIX', async ctx => {
- const parsed = await DSN6.parse(a.data).runInContext(ctx);
- if (parsed.isError) throw new Error(parsed.message);
- return new SO.Format.Dsn6(parsed.result);
- });
- }
- });
- export { ImportString }
- type ImportString = typeof ImportString
- const ImportString = PluginStateTransform.BuiltIn({
- name: 'import-string',
- display: { name: 'Import String', description: 'Import given data as a string' },
- from: SO.Root,
- to: SO.Data.String,
- params: {
- data: PD.Value(''),
- label: PD.Optional(PD.Text('')),
- }
- })({
- apply({ params: { data, label } }) {
- return new SO.Data.String(data, { label: label || '' });
- },
- update({ oldParams, newParams, b }) {
- if (oldParams.data !== newParams.data) return StateTransformer.UpdateResult.Recreate;
- if (oldParams.label !== newParams.label) {
- b.label = newParams.label || '';
- return StateTransformer.UpdateResult.Updated;
- }
- return StateTransformer.UpdateResult.Unchanged;
- },
- isSerializable: () => ({ isSerializable: false, reason: 'Cannot serialize user imported strings.' })
- });
- export { ImportJson }
- type ImportJson = typeof ImportJson
- const ImportJson = PluginStateTransform.BuiltIn({
- name: 'import-json',
- display: { name: 'Import JSON', description: 'Import given data as a JSON' },
- from: SO.Root,
- to: SO.Format.Json,
- params: {
- data: PD.Value<any>({}),
- label: PD.Optional(PD.Text('')),
- }
- })({
- apply({ params: { data, label } }) {
- return new SO.Format.Json(data, { label: label || '' });
- },
- update({ oldParams, newParams, b }) {
- if (oldParams.data !== newParams.data) return StateTransformer.UpdateResult.Recreate;
- if (oldParams.label !== newParams.label) {
- b.label = newParams.label || '';
- return StateTransformer.UpdateResult.Updated;
- }
- return StateTransformer.UpdateResult.Unchanged;
- },
- isSerializable: () => ({ isSerializable: false, reason: 'Cannot serialize user imported JSON.' })
- });
- export { ParseJson }
- type ParseJson = typeof ParseJson
- const ParseJson = PluginStateTransform.BuiltIn({
- name: 'parse-json',
- display: { name: 'Parse JSON', description: 'Parse JSON from String data' },
- from: [SO.Data.String],
- to: SO.Format.Json
- })({
- apply({ a }) {
- return Task.create('Parse JSON', async ctx => {
- const json = await (new Response(a.data)).json(); // async JSON parsing via fetch API
- return new SO.Format.Json(json)
- });
- }
- });
|