+++ /dev/null
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { CollectionService } from "../collection-service/collection-service";
-import { parseKeepManifestText, stringifyKeepManifest } from "./collection-manifest-parser";
-import { mapManifestToCollectionFilesTree } from "./collection-manifest-mapper";
-
-export class CollectionFilesService {
-
- constructor(private collectionService: CollectionService) { }
-
- getFiles(collectionUuid: string) {
- return this.collectionService
- .get(collectionUuid)
- .then(collection =>
- mapManifestToCollectionFilesTree(
- parseKeepManifestText(
- collection.manifestText
- )
- )
- );
- }
-
- async renameFile(collectionUuid: string, file: { name: string, path: string }, newName: string) {
- const collection = await this.collectionService.get(collectionUuid);
- const manifest = parseKeepManifestText(collection.manifestText);
- const updatedManifest = manifest.map(
- stream => stream.name === file.path
- ? {
- ...stream,
- files: stream.files.map(
- f => f.name === file.name
- ? { ...f, name: newName }
- : f
- )
- }
- : stream
- );
- const manifestText = stringifyKeepManifest(updatedManifest);
- return this.collectionService.update(collectionUuid, { manifestText });
- }
-
- async deleteFile(collectionUuid: string, file: { name: string, path: string }) {
- const collection = await this.collectionService.get(collectionUuid);
- const manifest = parseKeepManifestText(collection.manifestText);
- const updatedManifest = manifest.map(stream =>
- stream.name === file.path
- ? {
- ...stream,
- files: stream.files.filter(f => f.name !== file.name)
- }
- : stream
- );
- const manifestText = stringifyKeepManifest(updatedManifest);
- return this.collectionService.update(collectionUuid, { manifestText });
- }
-}
+++ /dev/null
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { parseKeepManifestText } from "./collection-manifest-parser";
-import { mapManifestToFiles, mapManifestToDirectories, mapManifestToCollectionFilesTree, mapCollectionFilesTreeToManifest } from "./collection-manifest-mapper";
-
-test('mapManifestToFiles', () => {
- const manifestText = `. 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n./c d41d8cd98f00b204e9800998ecf8427e+0 0:0:d`;
- const manifest = parseKeepManifestText(manifestText);
- const files = mapManifestToFiles(manifest);
- expect(files).toEqual([{
- path: '',
- id: '/a',
- name: 'a',
- size: 0,
- type: 'file',
- url: ''
- }, {
- path: '',
- id: '/b',
- name: 'b',
- size: 0,
- type: 'file',
- url: ''
- }, {
- path: '',
- id: '/output.txt',
- name: 'output.txt',
- size: 33,
- type: 'file',
- url: ''
- }, {
- path: '/c',
- id: '/c/d',
- name: 'd',
- size: 0,
- type: 'file',
- url: ''
- },]);
-});
-
-test('mapManifestToDirectories', () => {
- const manifestText = `./c/user/results 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n`;
- const manifest = parseKeepManifestText(manifestText);
- const directories = mapManifestToDirectories(manifest);
- expect(directories).toEqual([{
- path: "",
- id: '/c',
- name: 'c',
- type: 'directory',
- url: ''
- }, {
- path: '/c',
- id: '/c/user',
- name: 'user',
- type: 'directory',
- url: ''
- }, {
- path: '/c/user',
- id: '/c/user/results',
- name: 'results',
- type: 'directory',
- url: ''
- },]);
-});
-
-test('mapCollectionFilesTreeToManifest', () => {
- const manifestText = `. 930625b054ce894ac40596c3f5a0d947+33 0:22:test.txt\n./c/user/results 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n`;
- const tree = mapManifestToCollectionFilesTree(parseKeepManifestText(manifestText));
- const manifest = mapCollectionFilesTreeToManifest(tree);
- expect(manifest).toEqual([{
- name: '',
- locators: [],
- files: [{
- name: 'test.txt',
- position: '',
- size: 22
- },],
- }, {
- name: '/c/user/results',
- locators: [],
- files: [{
- name: 'a',
- position: '',
- size: 0
- }, {
- name: 'b',
- position: '',
- size: 0
- }, {
- name: 'output.txt',
- position: '',
- size: 33
- },],
- },]);
-
-});
\ No newline at end of file
+++ /dev/null
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { uniqBy, groupBy } from 'lodash';
-import { KeepManifestStream, KeepManifestStreamFile, KeepManifest } from "~/models/keep-manifest";
-import { TreeNode, setNode, createTree, getNodeDescendantsIds, getNodeValue, TreeNodeStatus } from '~/models/tree';
-import { CollectionFilesTree, CollectionFile, CollectionDirectory, createCollectionDirectory, createCollectionFile, CollectionFileType } from '../../models/collection-file';
-
-export const mapCollectionFilesTreeToManifest = (tree: CollectionFilesTree): KeepManifest => {
- const values = getNodeDescendantsIds('')(tree).map(id => getNodeValue(id)(tree));
- const files = values.filter(value => value && value.type === CollectionFileType.FILE) as CollectionFile[];
- const fileGroups = groupBy(files, file => file.path);
- return Object
- .keys(fileGroups)
- .map(dirName => ({
- name: dirName,
- locators: [],
- files: fileGroups[dirName].map(mapCollectionFile)
- }));
-};
-
-export const mapManifestToCollectionFilesTree = (manifest: KeepManifest): CollectionFilesTree =>
- manifestToCollectionFiles(manifest)
- .map(mapCollectionFileToTreeNode)
- .reduce((tree, node) => setNode(node)(tree), createTree<CollectionFile>());
-
-
-export const mapCollectionFileToTreeNode = (file: CollectionFile): TreeNode<CollectionFile> => ({
- children: [],
- id: file.id,
- parent: file.path,
- value: file,
- active: false,
- selected: false,
- expanded: false,
- status: TreeNodeStatus.INITIAL,
-});
-
-export const manifestToCollectionFiles = (manifest: KeepManifest): Array<CollectionDirectory | CollectionFile> => ([
- ...mapManifestToDirectories(manifest),
- ...mapManifestToFiles(manifest)
-]);
-
-export const mapManifestToDirectories = (manifest: KeepManifest): CollectionDirectory[] =>
- uniqBy(
- manifest
- .map(mapStreamDirectory)
- .map(splitDirectory)
- .reduce((all, splitted) => ([...all, ...splitted]), []),
- directory => directory.id);
-
-export const mapManifestToFiles = (manifest: KeepManifest): CollectionFile[] =>
- manifest
- .map(stream => stream.files.map(mapStreamFile(stream)))
- .reduce((all, current) => ([...all, ...current]), []);
-
-const splitDirectory = (directory: CollectionDirectory): CollectionDirectory[] => {
- return directory.name
- .split('/')
- .slice(1)
- .map(mapPathComponentToDirectory);
-};
-
-const mapPathComponentToDirectory = (component: string, index: number, components: string[]): CollectionDirectory =>
- createCollectionDirectory({
- path: index === 0 ? '' : joinPathComponents(components, index),
- id: joinPathComponents(components, index + 1),
- name: component,
- });
-
-const joinPathComponents = (components: string[], index: number) =>
- `/${components.slice(0, index).join('/')}`;
-
-const mapCollectionFile = (file: CollectionFile): KeepManifestStreamFile => ({
- name: file.name,
- position: '',
- size: file.size
-});
-
-const mapStreamDirectory = (stream: KeepManifestStream): CollectionDirectory =>
- createCollectionDirectory({
- path: '',
- id: stream.name,
- name: stream.name,
- });
-
-const mapStreamFile = (stream: KeepManifestStream) =>
- (file: KeepManifestStreamFile): CollectionFile =>
- createCollectionFile({
- path: stream.name,
- id: `${stream.name}/${file.name}`,
- name: file.name,
- size: file.size,
- });
-
+++ /dev/null
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { parseKeepManifestText, parseKeepManifestStream, stringifyKeepManifest } from "./collection-manifest-parser";
-
-describe('parseKeepManifestText', () => {
- it('should parse text into streams', () => {
- const manifestText = `. 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n./c d41d8cd98f00b204e9800998ecf8427e+0 0:0:d\n`;
- const manifest = parseKeepManifestText(manifestText);
- expect(manifest[0].name).toBe('');
- expect(manifest[1].name).toBe('/c');
- expect(manifest.length).toBe(2);
- });
-});
-
-describe('parseKeepManifestStream', () => {
- const streamText = './c 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt';
- const stream = parseKeepManifestStream(streamText);
-
- it('should parse stream name', () => {
- expect(stream.name).toBe('/c');
- });
- it('should parse stream locators', () => {
- expect(stream.locators).toEqual(['930625b054ce894ac40596c3f5a0d947+33']);
- });
- it('should parse stream files', () => {
- expect(stream.files).toEqual([
- { name: 'a', position: '0', size: 0 },
- { name: 'b', position: '0', size: 0 },
- { name: 'output.txt', position: '0', size: 33 },
- ]);
- });
-});
-
-test('stringifyKeepManifest', () => {
- const manifestText = `. 930625b054ce894ac40596c3f5a0d947+33 0:22:test.txt\n./c/user/results 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n`;
- const manifest = parseKeepManifestText(manifestText);
- expect(stringifyKeepManifest(manifest)).toEqual(`. 930625b054ce894ac40596c3f5a0d947+33 0:22:test.txt\n./c/user/results 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n`);
-});
\ No newline at end of file
+++ /dev/null
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { KeepManifestStream, KeepManifestStreamFile, KeepManifest } from "~/models/keep-manifest";
-
-/**
- * Documentation [http://doc.arvados.org/api/storage.html](http://doc.arvados.org/api/storage.html)
- */
-export const parseKeepManifestText: (text: string) => KeepManifestStream[] = (text: string) =>
- text
- .split(/\n/)
- .filter(streamText => streamText.length > 0)
- .map(parseKeepManifestStream);
-
-/**
- * Documentation [http://doc.arvados.org/api/storage.html](http://doc.arvados.org/api/storage.html)
- */
-export const parseKeepManifestStream = (stream: string): KeepManifestStream => {
- const tokens = stream.split(' ');
- return {
- name: streamName(tokens),
- locators: locators(tokens),
- files: files(tokens)
- };
-};
-
-export const stringifyKeepManifest = (manifest: KeepManifest) =>
- manifest.map(stringifyKeepManifestStream).join('');
-
-export const stringifyKeepManifestStream = (stream: KeepManifestStream) =>
- `.${stream.name} ${stream.locators.join(' ')} ${stream.files.map(stringifyFile).join(' ')}\n`;
-
-const FILE_LOCATOR_REGEXP = /^([0-9a-f]{32})\+([0-9]+)(\+[A-Z][-A-Za-z0-9@_]*)*$/;
-
-const FILE_REGEXP = /([0-9]+):([0-9]+):(.*)/;
-
-const streamName = (tokens: string[]) => tokens[0].slice(1);
-
-const locators = (tokens: string[]) => tokens.filter(isFileLocator);
-
-const files = (tokens: string[]) => tokens.filter(isFile).map(parseFile);
-
-const isFileLocator = (token: string) => FILE_LOCATOR_REGEXP.test(token);
-
-const isFile = (token: string) => FILE_REGEXP.test(token);
-
-const parseFile = (token: string): KeepManifestStreamFile => {
- const match = FILE_REGEXP.exec(token);
- const [position, size, name] = match!.slice(1);
- return { name, position, size: parseInt(size, 10) };
-};
-
-const stringifyFile = (file: KeepManifestStreamFile) =>
- `${file.position}:${file.size}:${file.name}`;
import { FavoriteService } from "./favorite-service/favorite-service";
import { CollectionService } from "./collection-service/collection-service";
import { TagService } from "./tag-service/tag-service";
-import { CollectionFilesService } from "./collection-files-service/collection-files-service";
import { KeepService } from "./keep-service/keep-service";
import { WebDAV } from "~/common/webdav";
import { Config } from "~/common/config";
const ancestorsService = new AncestorService(groupsService, userService);
const authService = new AuthService(apiClient, config.rootUrl, actions);
const collectionService = new CollectionService(apiClient, webdavClient, authService, actions);
- const collectionFilesService = new CollectionFilesService(collectionService);
const favoriteService = new FavoriteService(linkService, groupsService);
const tagService = new TagService(linkService);
const searchService = new SearchService();
apiClientAuthorizationService,
authService,
authorizedKeysService,
- collectionFilesService,
collectionService,
containerRequestService,
containerService,