Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added export and import zip functionality for text transaltion #311

Merged
merged 2 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 55 additions & 31 deletions renderer/src/layouts/projects/Export/ExportProjectPopUp.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default function ExportProjectPopUp(props) {
const [metadata, setMetadata] = React.useState({});
const [audioExport, setAudioExport] = React.useState('default');
const [checkText, setCheckText] = React.useState(false);
const [checkZip, setCheckZip] = React.useState(true);

const [totalExported, setTotalExported] = React.useState(0);
const [totalExports, setTotalExports] = React.useState(0);
Expand Down Expand Up @@ -87,38 +88,51 @@ export default function ExportProjectPopUp(props) {
const updateCommon = (fs, path, folder, project) => {
const fse = window.require('fs-extra');
logger.debug('ExportProjectPopUp.js', 'Updated Scripture burrito');
let data = fs.readFileSync(path.join(folder, 'metadata.json'), 'utf-8');
const sb = JSON.parse(data);
// Adding the below line in 0.5.8 version, since the id in the previous versions is autographa.org
sb.idAuthorities.scribe.id = 'http://www.scribe.bible';
if (!sb.copyright?.shortStatements && sb.copyright?.licenses) {
delete sb.copyright.publicDomain;
data = JSON.stringify(sb);
}
const success = validate('metadata', path.join(folder, 'metadata.json'), data, sb.meta.version);
if (success) {
logger.debug('ExportProjectPopUp.js', 'Burrito validated successfully');
fse.copy(folder, path.join(folderPath, project.name))
.then(() => {
deleteGitAfterCopy(fs, path.join(folderPath, project.name), path)
.then(() => {
resetExportProgress(); // reset export states
logger.debug('ExportProjectPopUp.js', 'Exported Successfully');
setNotify('success');
setSnackText(t('dynamic-msg-export-success'));
setOpenSnackBar(true);
closePopUp(false);
let data = fs.readFileSync(path.join(folder, 'metadata.json'), 'utf-8');
const sb = JSON.parse(data);
// Adding the below line in 0.5.8 version, since the id in the previous versions is autographa.org
sb.idAuthorities.scribe.id = 'http://www.scribe.bible';
if (!sb.copyright?.shortStatements && sb.copyright?.licenses) {
delete sb.copyright.publicDomain;
data = JSON.stringify(sb);
}
const success = validate('metadata', path.join(folder, 'metadata.json'), data, sb.meta.version);
if (success) {
logger.debug('ExportProjectPopUp.js', 'Burrito validated successfully');
fse.copy(folder, path.join(folderPath, project.name))
.then(() => {
deleteGitAfterCopy(fs, path.join(folderPath, project.name), path)
.then(async () => {
// convert to zip if text translation and zip checked
if (project?.type === 'Text Translation' && checkZip) {
const AdmZip = window.require('adm-zip');
const zip = new AdmZip();
zip.addLocalFolder(path.join(folderPath, project.name));
zip.writeZip(path.join(folderPath, `${project.name}.zip`));
// delete folder
await fs.rmdirSync(path.join(folderPath, project.name), { recursive: true }, async (err) => {
if (err) {
throw new Error(`Remove Org Exported Dir failed : ${err}`);
}
});
})
.catch((err) => {
resetExportProgress(); // reset export states
logger.error('ExportProjectPopUp.js', `Failed to export ${err}`);
setNotify('failure');
setSnackText(t('dynamic-msg-export-fail'));
setOpenSnackBar(true);
closePopUp(false);
});
}
}
resetExportProgress(); // reset export states
logger.debug('ExportProjectPopUp.js', 'Exported Successfully');
setNotify('success');
setSnackText(t('dynamic-msg-export-success'));
setOpenSnackBar(true);
closePopUp(false);
});
})
.catch((err) => {
resetExportProgress(); // reset export states
logger.error('ExportProjectPopUp.js', `Failed to export ${err}`);
setNotify('failure');
setSnackText(t('dynamic-msg-export-fail'));
setOpenSnackBar(true);
closePopUp(false);
});
}
};

const updateBurritoVersion = (username, fs, path, folder) => {
Expand Down Expand Up @@ -295,6 +309,16 @@ export default function ExportProjectPopUp(props) {
<span className=" ml-4 text-xs font-bold" title="All takes of every verse saved as a ZIP archive within Scripture Burrito">Full project</span>
</div>
</div>
)}
{project?.type === 'Text Translation' && (

<div className="w-full py-3 flex">
<div className="flex flex-row justify-end mr-3">
<input id="visible_1" className="visible" type="checkbox" checked={checkZip} onClick={() => setCheckZip(!checkZip)} />
<span className="ml-2 text-xs font-bold" title="">Project as zip</span>
</div>
</div>

)}
<div className="absolute bottom-0 right-0 left-0 bg-white">
<div className="flex gap-6 mx-5 justify-end">
Expand Down
83 changes: 67 additions & 16 deletions renderer/src/layouts/projects/ImportProjectPopUp.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default function ImportProjectPopUp(props) {
const [processMerge, setProcessMerge] = React.useState(false);
const [currentUser, setCurrentUser] = React.useState();
const [sbData, setSbData] = React.useState({});
const [importingIsZip, setImportingIsZip] = React.useState(false);
const [model, setModel] = React.useState({
openModel: false,
title: '',
Expand All @@ -58,37 +59,71 @@ export default function ImportProjectPopUp(props) {
completedSteps: 0,
});

function close() {
logger.debug('ImportProjectPopUp.js', 'Closing the Dialog box');
async function close(triggeredFrom) {
logger.debug('ImportProjectPopUp.js', `Closing the Dialog box : Triggered from : ${triggeredFrom}`);
removeExtractedZipDir()
setValid(false);
setSbData()
setFolderPath()
closePopUp(false);
setShow(false);
setImportProgress((prev)=>({...prev, importStarted:false, completedSteps: 0, totalSteps: 4}))
}

const openFileDialogSettingData = async () => {
logger.debug('ImportProjectPopUp.js', 'Inside openFileDialogSettingData');
const options = { properties: ['openDirectory'] };
// const options = { properties: ['openFile','openDirectory'] };
const options = importingIsZip ? { properties: ['openFile'], filters: [{name:'zip file', extensions:["zip"]}] } : { properties: ['openDirectory'] };
const { dialog } = window.require('@electron/remote');
const chosenFolder = await dialog.showOpenDialog(options);
let selectedFolderPath;
if ((chosenFolder.filePaths).length > 0) {
logger.debug('ImportProjectPopUp.js', 'Selected a directory');
await localforage.getItem('userProfile').then(async (value) => {
setShow(true);
// setShow(true);
setCurrentUser(value.username)
// Adding 'projects' to check the duplication in the user project resources list
const result = await viewBurrito(chosenFolder.filePaths[0], value.username, 'projects');
selectedFolderPath = chosenFolder.filePaths[0]
// check if zip
if(chosenFolder.filePaths[0].endsWith('.zip')) {
const AdmZip = window.require('adm-zip');
setImportingIsZip(true)
const path = require('path');
const zip = new AdmZip(chosenFolder.filePaths[0]);
const extractFileName = chosenFolder.filePaths[0].replace('.zip',"__extracted")
zip.extractAllTo(path.join(extractFileName),true);
// change the choosefolder Filepath to new path
selectedFolderPath = extractFileName
}

const result = await viewBurrito(selectedFolderPath, value.username, 'projects');
setSbData(result);
});
} else {
logger.debug('ImportProjectPopUp.js', 'Didn\'t select any project');
setSbData({});
close();
close("else");
}
setFolderPath(chosenFolder.filePaths[0]);
setFolderPath(selectedFolderPath);
};

const modelClose = () => {
const removeExtractedZipDir = async() => {
const path = require('path');
const fs = window.require('fs');
// delete the extracted zip file after successfull / failed import
if(importingIsZip && folderPath) {
setImportingIsZip(false)
if (fs.existsSync(path.join(folderPath))) {
await fs.rmdirSync(path.join(folderPath), { recursive: true }, async (err) => {
if (err) {
throw new Error(`Remove extracted zip folder : ${err}`);
}
});
}
}
}

const modelClose = async () => {
setModel({
openModel: false,
title: '',
Expand All @@ -99,11 +134,15 @@ export default function ImportProjectPopUp(props) {
};

const callImport = async (updateBurriot) => {
modelClose();
await modelClose();
setImportProgress((prev)=>({...prev, importStarted:true, completedSteps: prev.completedSteps + 1 }))
logger.debug('ImportProjectPopUp.js', 'Inside callImport');
const path = require('path');
const fs = window.require('fs');
await localforage.getItem('userProfile').then(async (value) => {
const status = await importBurrito(folderPath, value.username, updateBurriot, languages);
// delete the extracted zip file after successfull / failed import
await removeExtractedZipDir()
setImportProgress((prev)=>({...prev, importStarted:true, completedSteps: prev.completedSteps + 1 }))
setOpenSnackBar(true);
closePopUp(false);
Expand All @@ -112,7 +151,7 @@ export default function ImportProjectPopUp(props) {
setImportProgress((prev)=>({...prev, importStarted:true, completedSteps: 0, totalSteps: 0}))
if (status[0].type === 'success') {
setSbData({});
close();
close("Success");
FetchProjects();
router.push('/projects');
}
Expand Down Expand Up @@ -188,7 +227,8 @@ export default function ImportProjectPopUp(props) {
React.useEffect(() => {
if (open) {
setImportProgress((prev)=>({...prev, importStarted:false, completedSteps: 0, totalSteps: 4}))
openFileDialogSettingData();
// openFileDialogSettingData();
setShow(true);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [open]);
Expand All @@ -210,7 +250,8 @@ export default function ImportProjectPopUp(props) {
initialFocus={cancelButtonRef}
static
open={show}
onClose={close}
// onClose={() => close('X')}
onClose={() => {}}
>
<Dialog.Overlay className="fixed inset-0 bg-black opacity-30" />
<div className="flex items-center justify-center h-screen">
Expand All @@ -221,7 +262,7 @@ export default function ImportProjectPopUp(props) {
{t('label-import-project')}
</div>
<button
onClick={close}
onClick={() => close('Backdrop')}
type="button"
className="focus:outline-none"
>
Expand Down Expand Up @@ -270,8 +311,18 @@ export default function ImportProjectPopUp(props) {
</div>

<div>
<h4 className="text-red-500">{valid === true ? t('label-enter-location') : (sbData?.fileExist ? '' : t('dynamic-msg-unable-find-buritto-snack'))}</h4>
<h4 className="text-red-500">{valid === true ? t('label-enter-location') : ((sbData?.fileExist || !folderPath) ? '' : t('dynamic-msg-unable-find-buritto-snack'))}</h4>
</div>

{/* check zip or folder */}
{!folderPath && (
<div className="w-full flex">
<div className="flex flex-row justify-end mr-3">
<input id="visible_1" className="visible" type="checkbox" checked={importingIsZip} onClick={() => setImportingIsZip(!importingIsZip)} />
<span className="ml-2 text-xs font-bold" title="">Project as zip</span>
</div>
</div>
)}

</div>

Expand Down Expand Up @@ -310,13 +361,13 @@ export default function ImportProjectPopUp(props) {
</label>
)}
</div>
)}
) }

<div className="flex gap-6 mb-5 justify-end">

<button
type="button"
onClick={close}
onClick={() => close('cancel')}
className="py-2 px-6 rounded shadow bg-error text-white uppercase text-xs tracking-widest font-semibold"
>
{t('btn-cancel')}
Expand Down
Loading