Fix storage paths, update INI parser (#377)

This commit is contained in:
Piotr Rogowski 2022-01-16 16:38:48 +01:00 committed by GitHub
parent 83963dd8c7
commit affdae49e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 450 additions and 555 deletions

968
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
"@reduxjs/toolkit": "^1.7.1", "@reduxjs/toolkit": "^1.7.1",
"@sentry/react": "^6.16.1", "@sentry/react": "^6.16.1",
"@sentry/tracing": "^6.16.1", "@sentry/tracing": "^6.16.1",
"@speedy-tuner/ini": "^0.2.2", "@speedy-tuner/ini": "^0.3.0",
"@speedy-tuner/types": "^0.3.0", "@speedy-tuner/types": "^0.3.0",
"antd": "^4.18.3", "antd": "^4.18.3",
"firebase": "^9.6.3", "firebase": "^9.6.3",
@ -54,7 +54,6 @@
"devDependencies": { "devDependencies": {
"@craco/craco": "^6.4.3", "@craco/craco": "^6.4.3",
"@speedy-tuner/eslint-config": "^0.1.3", "@speedy-tuner/eslint-config": "^0.1.3",
"@types/d3": "^7.0.0",
"@types/node": "^17.0.8", "@types/node": "^17.0.8",
"@types/pako": "^1.0.3", "@types/pako": "^1.0.3",
"@types/react": "^17.0.38", "@types/react": "^17.0.38",

View File

@ -9,7 +9,7 @@ import {
uploadBytesResumable, uploadBytesResumable,
} from '../firebase'; } from '../firebase';
const TUNES_PATH = 'public/users'; const BASE_PATH = 'public/users';
const genericError = (error: Error) => notification.error({ message: 'Database Error', description: error.message }); const genericError = (error: Error) => notification.error({ message: 'Database Error', description: error.message });
@ -30,7 +30,7 @@ const useServerStorage = () => {
const removeFile = async (path: string) => { const removeFile = async (path: string) => {
try { try {
await deleteObject(storageRef(storage, `${TUNES_PATH}/${path}`)); await deleteObject(storageRef(storage, path));
return Promise.resolve(); return Promise.resolve();
} catch (error) { } catch (error) {
@ -43,7 +43,7 @@ const useServerStorage = () => {
}; };
const uploadFile = (path: string, file: File, data: Uint8Array) => const uploadFile = (path: string, file: File, data: Uint8Array) =>
uploadBytesResumable(storageRef(storage, `${TUNES_PATH}/${path}`), data, { uploadBytesResumable(storageRef(storage, path), data, {
customMetadata: { customMetadata: {
name: file.name, name: file.name,
size: `${file.size}`, size: `${file.size}`,
@ -54,6 +54,7 @@ const useServerStorage = () => {
getFile: (path: string): Promise<ArrayBuffer> => getFile(path), getFile: (path: string): Promise<ArrayBuffer> => getFile(path),
removeFile: (path: string): Promise<void> => removeFile(path), removeFile: (path: string): Promise<void> => removeFile(path),
uploadFile: (path: string, file: File, data: Uint8Array): UploadTask => uploadFile(path, file, data), uploadFile: (path: string, file: File, data: Uint8Array): UploadTask => uploadFile(path, file, data),
basePathForFile: (userUuid: string, tuneId: string, fileName: string): string => `${BASE_PATH}/${userUuid}/tunes/${tuneId}/${fileName}`,
}; };
}; };

View File

@ -114,8 +114,8 @@ const UploadPage = () => {
const { currentUser, refreshToken } = useAuth(); const { currentUser, refreshToken } = useAuth();
const history = useHistory(); const history = useHistory();
const { storageSet, storageGet, storageDelete } = useBrowserStorage(); const { storageSet, storageGet, storageDelete } = useBrowserStorage();
const { removeFile, uploadFile, basePathForFile } = useServerStorage();
const { updateData, getTune } = useDb(); const { updateData, getTune } = useDb();
const { removeFile, uploadFile } = useServerStorage();
const requiredRules = [{ required: true, message: 'This field is required!' }]; const requiredRules = [{ required: true, message: 'This field is required!' }];
const [readme, setReadme] = useState('# My Tune\n\ndescription'); const [readme, setReadme] = useState('# My Tune\n\ndescription');
@ -201,23 +201,23 @@ const UploadPage = () => {
}; };
const tuneFileData = () => ({ const tuneFileData = () => ({
path: `${currentUser!.uid}/tunes/${newTuneId}/${nanoid()}.msq.gz`, path: basePathForFile(currentUser!.uid, newTuneId!, `tune/${nanoid()}.msq.gz`),
}); });
const logFileData = (file: UploadFile) => { const logFileData = (file: UploadFile) => {
const { name } = file; const { name } = file;
const extension = name.split('.').pop(); const extension = name.split('.').pop();
return { return {
path: `${currentUser!.uid}/tunes/${newTuneId}/logs/${nanoid()}.${extension}.gz`, path: basePathForFile(currentUser!.uid, newTuneId!, `logs/${nanoid()}.${extension}.gz`),
}; };
}; };
const toothLogFilesData = () => ({ const toothLogFilesData = () => ({
path: `${currentUser!.uid}/tunes/${newTuneId}/tooth-logs/${nanoid()}.csv.gz`, path: basePathForFile(currentUser!.uid, newTuneId!, `tooth-logs/${nanoid()}.csv.gz`),
}); });
const customIniFileData = () => ({ const customIniFileData = () => ({
path: `${currentUser!.uid}/tunes/${newTuneId}/${nanoid()}.ini.gz`, path: basePathForFile(currentUser!.uid, newTuneId!, `ini/${nanoid()}.ini.gz`),
}); });
const uploadTune = async (options: UploadRequestOption) => { const uploadTune = async (options: UploadRequestOption) => {
@ -347,10 +347,15 @@ const UploadPage = () => {
return { result, message }; return { result, message };
} }
// TODO: change to common interface, add some validation method let validationMessage = 'INI file is empty or not valid!';
// Create INI parser let valid = false;
const parser = new INI((new TextDecoder()).decode(await file.arrayBuffer())); try {
const valid = parser.parse().megaTune.signature.length > 0; const parser = new INI(await file.arrayBuffer()).parse();
valid = parser.getResults().megaTune.signature.length > 0;
} catch (error) {
valid = false;
validationMessage = (error as Error).message;
}
if (valid) { if (valid) {
setCustomIniFile(tune); setCustomIniFile(tune);
@ -358,7 +363,7 @@ const UploadPage = () => {
return { return {
result: valid, result: valid,
message: 'INI file is empty or not valid!', message: validationMessage,
}; };
}); });
}; };

View File

@ -22,7 +22,7 @@ export const loadTune = async (tuneRaw: ArrayBuffer, iniRaw: ArrayBuffer) => {
} }
const buff = pako.inflate(new Uint8Array(iniRaw)); const buff = pako.inflate(new Uint8Array(iniRaw));
const config = new INI((new TextDecoder()).decode(buff)).parse(); const config = new INI(buff).parse().getResults();
// override / merge standard dialogs, constants and help // override / merge standard dialogs, constants and help
config.dialogs = { config.dialogs = {