mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-14 10:35:11 +00:00
explorer: move export from fileStorage
This commit is contained in:
@@ -231,37 +231,6 @@ export const fileStorageDidFailToRenameFile = createAction(
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* Request to export (download) a file.
|
||||
* @param id The file handle UUID.
|
||||
*/
|
||||
export const fileStorageExportFile = createAction((fileName: string) => ({
|
||||
type: 'fileStorage.action.exportFile',
|
||||
fileName,
|
||||
}));
|
||||
|
||||
/**
|
||||
* Indicates that fileStorageExportFile(fileName) succeeded.
|
||||
* @param fileName The file handle UUID.
|
||||
*/
|
||||
export const fileStorageDidExportFile = createAction((fileName: string) => ({
|
||||
type: 'fileStorage.action.didExportFile',
|
||||
fileName,
|
||||
}));
|
||||
|
||||
/**
|
||||
* Indicates that fileStorageExportFile(fileName) failed.
|
||||
* @param fileName The file name.
|
||||
* @param error The error that was raised.
|
||||
*/
|
||||
export const fileStorageDidFailToExportFile = createAction(
|
||||
(fileName: string, error: Error) => ({
|
||||
type: 'fileStorage.action.didFailToExportFile',
|
||||
fileName,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* Request to archive (download) all files in the store.
|
||||
*/
|
||||
|
||||
@@ -15,9 +15,7 @@ import {
|
||||
fileStorageDidArchiveAllFiles,
|
||||
fileStorageDidChangeItem,
|
||||
fileStorageDidDeleteFile,
|
||||
fileStorageDidExportFile,
|
||||
fileStorageDidFailToArchiveAllFiles,
|
||||
fileStorageDidFailToExportFile,
|
||||
fileStorageDidFailToReadFile,
|
||||
fileStorageDidInitialize,
|
||||
fileStorageDidOpenFile,
|
||||
@@ -25,7 +23,6 @@ import {
|
||||
fileStorageDidRemoveItem,
|
||||
fileStorageDidRenameFile,
|
||||
fileStorageDidWriteFile,
|
||||
fileStorageExportFile,
|
||||
fileStorageOpenFile,
|
||||
fileStorageReadFile,
|
||||
fileStorageRenameFile,
|
||||
@@ -219,59 +216,6 @@ describe('rename', () => {
|
||||
await saga.end();
|
||||
});
|
||||
});
|
||||
|
||||
describe('export', () => {
|
||||
it('should fail if file does not exist', async () => {
|
||||
const testFile = 'test.file';
|
||||
|
||||
const saga = new AsyncSaga(fileStorage);
|
||||
|
||||
await expect(saga.take()).resolves.toEqual(fileStorageDidInitialize([]));
|
||||
|
||||
saga.put(fileStorageExportFile(testFile));
|
||||
|
||||
await expect(saga.take()).resolves.toEqual(
|
||||
fileStorageDidFailToExportFile(testFile, new Error('file does not exist')),
|
||||
);
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
|
||||
it('should export file', async () => {
|
||||
const saga = new AsyncSaga(fileStorage);
|
||||
|
||||
const [testFile] = await setUpTestFile(saga);
|
||||
|
||||
jest.spyOn(browserFsAccess, 'fileSave');
|
||||
|
||||
saga.put(fileStorageExportFile(testFile.path));
|
||||
|
||||
await expect(saga.take()).resolves.toEqual(
|
||||
fileStorageDidExportFile(testFile.path),
|
||||
);
|
||||
expect(browserFsAccess.fileSave).toHaveBeenCalled();
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
|
||||
it('should catch error', async () => {
|
||||
const saga = new AsyncSaga(fileStorage);
|
||||
|
||||
const [testFile] = await setUpTestFile(saga);
|
||||
|
||||
const testError = new Error('test error');
|
||||
jest.spyOn(browserFsAccess, 'fileSave').mockRejectedValue(testError);
|
||||
|
||||
saga.put(fileStorageExportFile(testFile.path));
|
||||
|
||||
await expect(saga.take()).resolves.toEqual(
|
||||
fileStorageDidFailToExportFile(testFile.path, testError),
|
||||
);
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
});
|
||||
|
||||
describe('archive', () => {
|
||||
it('should archive file', async () => {
|
||||
const saga = new AsyncSaga(fileStorage);
|
||||
|
||||
@@ -13,7 +13,6 @@ import 'dexie-observable';
|
||||
import JSZip from 'jszip';
|
||||
import { eventChannel } from 'redux-saga';
|
||||
import { call, fork, put, take, takeEvery } from 'typed-redux-saga/macro';
|
||||
import { pythonFileExtension, pythonFileMimeType } from '../pybricksMicropython/lib';
|
||||
import { ensureError, timestamp } from '../utils';
|
||||
import { sha256Digest } from '../utils/crypto';
|
||||
import {
|
||||
@@ -25,10 +24,8 @@ import {
|
||||
fileStorageDidArchiveAllFiles,
|
||||
fileStorageDidChangeItem,
|
||||
fileStorageDidDeleteFile,
|
||||
fileStorageDidExportFile,
|
||||
fileStorageDidFailToArchiveAllFiles,
|
||||
fileStorageDidFailToDeleteFile,
|
||||
fileStorageDidFailToExportFile,
|
||||
fileStorageDidFailToInitialize,
|
||||
fileStorageDidFailToOpenFile,
|
||||
fileStorageDidFailToReadFile,
|
||||
@@ -40,7 +37,6 @@ import {
|
||||
fileStorageDidRemoveItem,
|
||||
fileStorageDidRenameFile,
|
||||
fileStorageDidWriteFile,
|
||||
fileStorageExportFile,
|
||||
fileStorageOpenFile,
|
||||
fileStorageReadFile,
|
||||
fileStorageRenameFile,
|
||||
@@ -256,55 +252,6 @@ function* handleWriteFile(
|
||||
}
|
||||
}
|
||||
|
||||
function* handleExportFile(
|
||||
db: FileStorageDb,
|
||||
action: ReturnType<typeof fileStorageExportFile>,
|
||||
): Generator {
|
||||
const file = yield* call(() =>
|
||||
db.transaction('r', db.metadata, db._contents, async () => {
|
||||
const metadata = await db.metadata
|
||||
.where('path')
|
||||
.equals(action.fileName)
|
||||
.first();
|
||||
|
||||
if (!metadata) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return await db._contents.get(metadata.path);
|
||||
}),
|
||||
);
|
||||
|
||||
if (!file) {
|
||||
yield* put(
|
||||
fileStorageDidFailToExportFile(
|
||||
action.fileName,
|
||||
new Error('file does not exist'),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const blob = new Blob([file.contents], { type: `${pythonFileMimeType}` });
|
||||
|
||||
try {
|
||||
yield* call(() =>
|
||||
fileSave(blob, {
|
||||
id: 'pybricksCodeFileStorageExport',
|
||||
fileName: file.path,
|
||||
extensions: [pythonFileExtension],
|
||||
mimeTypes: [pythonFileMimeType],
|
||||
// TODO: translate description
|
||||
description: 'Python Files',
|
||||
}),
|
||||
);
|
||||
|
||||
yield* put(fileStorageDidExportFile(action.fileName));
|
||||
} catch (err) {
|
||||
yield* put(fileStorageDidFailToExportFile(action.fileName, ensureError(err)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file from storage.
|
||||
* @param db The database instance.
|
||||
@@ -466,7 +413,6 @@ function* initialize(): Generator {
|
||||
yield* takeEvery(fileStorageWriteFile, handleWriteFile, db);
|
||||
yield* takeEvery(fileStorageDeleteFile, handleDeleteFile, db);
|
||||
yield* takeEvery(fileStorageRenameFile, handleRenameFile, db);
|
||||
yield* takeEvery(fileStorageExportFile, handleExportFile, db);
|
||||
yield* takeEvery(fileStorageArchiveAllFiles, handleArchiveAllFiles, db);
|
||||
|
||||
const files = yield* call(() => db.metadata.toArray());
|
||||
|
||||
Reference in New Issue
Block a user