Skip to content

Commit

Permalink
implemented download project functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Ketan Kumar Baboo authored and RevantCI committed Dec 5, 2024
1 parent 67395dd commit 1fe1e84
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 28 deletions.
10 changes: 5 additions & 5 deletions UI/app/components/BooksList.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ import useAudioTranscription from "./useAudioTranscription";
import TextToAudioConversion from "./TextToAudioConversion";
import source_languages from "../store/source_languages.json";
import major_languages from "../store/major_languages.json";
import DownloadProject from "./DownloadProject";

const BooksList = ({
projectInstance,
files,
setFiles,
jsonFiles,
projectName,
bibleMetaData,
licenseData
}) => {
const [books, setBooks] = useState([]);
const [bookData, setBookData] = useState(null);
Expand Down Expand Up @@ -627,7 +629,7 @@ const BooksList = ({
}, [playingAudio]);

const downloadUSFM = (book) => {
processUSFM(projectInstance, book.name, bibleMetaData);
processUSFM(projectInstance, book.name, true);
};

const resetProject = () => {
Expand Down Expand Up @@ -986,9 +988,7 @@ const BooksList = ({
>
Reset Project
</Button>
<Button variant="contained" sx={styles.Button} disabled>
Download Project
</Button>
<DownloadProject projectName = {projectName} projectInstance={projectInstance} jsonFiles={jsonFiles} licenseData= {licenseData} />
</Box>
</Card>
);
Expand Down
143 changes: 143 additions & 0 deletions UI/app/components/DownloadProject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { Button } from "@mui/material";
import { styles } from "../StyledComponents";
import JSZip from "jszip";
import { processUSFM } from "../utils/usfmProcessor";
import Swal from "sweetalert2";

const DownloadProject = ({
projectName,
projectInstance,
jsonFiles,
licenseData,
}) => {
const downloadProject = async () => {
const zip = new JSZip();
const projectFolder = zip.folder(projectName);
const textFolder = projectFolder?.folder("text-1");
const audioFolder = projectFolder?.folder("audio");
const audioIngredientsFolder = audioFolder?.folder("ingredients");
const textIngredientsFolder = textFolder?.folder("ingredients");
let metaData;
let versification;
let projectSetting;

console.log("json files", jsonFiles);
console.log("licenseData", licenseData);

if (licenseData) {
textIngredientsFolder?.file("license.md", licenseData);
audioIngredientsFolder?.file("license.md", licenseData);
}

for (const json of jsonFiles) {
if (json?.name.endsWith("metadata.json")) {
metaData = json?.content || null;
projectFolder?.file("metadata.json", JSON.stringify(metaData, null, 2));
textFolder?.file("metadata.json", JSON.stringify(metaData, null, 2));
} else if (json?.name.endsWith("versification.json")) {
versification = json?.content || null;
textIngredientsFolder?.file(
"versification.json",
JSON.stringify(versification, null, 2)
);
audioIngredientsFolder?.file(
"versification.json",
JSON.stringify(versification, null, 2)
);
} else if (
json?.name.endsWith("ag-settings.json") ||
json?.name.endsWith("scribe-settings.json")
) {
projectSetting = json?.content || null;
const fileName = json?.name.endsWith("scribe-settings.json")
? "scribe-settings.json"
: "ag-settings.json";

textIngredientsFolder?.file(
fileName,
JSON.stringify(projectSetting, null, 2)
);
audioIngredientsFolder?.file(
fileName,
JSON.stringify(projectSetting, null, 2)
);
}
}

try {
const keys = await projectInstance.keys();
const fetchedData = (
await Promise.all(keys.map((key) => projectInstance.getItem(key)))
).filter((data) => data !== null);

console.log("fetched data from indexed db", fetchedData);

for (const data of fetchedData) {
if (!data?.book) continue;

console.log("processing data for book:", data.book);

// const bookTextFolder = textFolder?.folder(data.book);
const usfmBookData = await processUSFM(
projectInstance,
data.book,
false
);
if (usfmBookData) {
const encoder = new TextEncoder();
const usfmBytes = encoder.encode(usfmBookData);

textIngredientsFolder?.file(`${data.book}.usfm`, usfmBytes, {
binary: true,
compression: "DEFLATE",
compressionOptions: {
level: 6,
},
comment: "UTF-8 encoded USFM file",
});
}

if (data?.generatedAudio) {
const bookAudioFolder = audioIngredientsFolder?.folder(data.book);
const chapterFolder = bookAudioFolder?.folder(data.chapter);
const audioBlob = await data.generatedAudio.arrayBuffer();
const audioExtension = data.generatedAudio.name.split('.').pop();
const audioFileName = `${data.chapter}_${data.verse}.${audioExtension}`
chapterFolder?.file(audioFileName, audioBlob);
}
}

const zipBlob = await zip.generateAsync({
type: "blob",
compression: "DEFLATE",
compressionOptions: {
level: 6,
},
});

const blobUrl = URL.createObjectURL(zipBlob);
const a = document.createElement("a");
a.href = blobUrl;
a.download = "project.zip";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(blobUrl);
} catch (error) {
console.error("Error during project download:", error);
Swal.fire("Error", `Error during downloading project`, "error");
}
};

return (
<Button
variant="contained"
sx={styles.downloadButton}
onClick={downloadProject}
>
Download Project
</Button>
);
};

export default DownloadProject;
14 changes: 7 additions & 7 deletions UI/app/components/DragAndDrop.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const DragAndDrop = ({ onFilesExtracted }) => {
const extractedBooks = [];
const jsonFiles = [];
let maxVersesData = {};
let bibleMetaData = {};
let projectName = "";
let licenseContent = "";

const processAudioFile = (
bookName,
Expand Down Expand Up @@ -52,6 +52,11 @@ const DragAndDrop = ({ onFilesExtracted }) => {

if (!projectName) projectName = pathParts[0];

if (relativePath.endsWith("license.md")) {
licenseContent = await file.async("string");
continue;
}

if (relativePath.endsWith(".json")) {
const fileData = await file.async("string");
const parsedContent = JSON.parse(fileData);
Expand All @@ -78,11 +83,6 @@ const DragAndDrop = ({ onFilesExtracted }) => {
file.name.endsWith("metadata.json")
) {
try {
const localizedBibles = parsedContent["localizedNames"];
bibleMetaData =
typeof localizedBibles === "string"
? JSON.parse(localizedBibles)
: localizedBibles;
const metadataProjectname =
parsedContent["identification"]?.name?.["en"];
if (
Expand Down Expand Up @@ -125,7 +125,7 @@ const DragAndDrop = ({ onFilesExtracted }) => {
jsonFiles,
projectName,
maxVersesData,
bibleMetaData
licenseContent
);
} catch (error) {
console.error("Error extracting zip file:", error);
Expand Down
9 changes: 5 additions & 4 deletions UI/app/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export default function Home() {
const [files, setFiles] = useState([]);
const [jsonFiles, setJsonFiles] = useState([]);
const [maxVerses, setMaxVerses] = useState(null);
const [bibleMetaData, setBibleMetadata] = useState(null);
const [projectName, setProjectName] = useState("");
const [projectDB, setProjectDB] = useState(null);
const [licenseData, setLicenseData] = useState(null);

useEffect(() => {
if (projectName) {
Expand All @@ -30,12 +30,12 @@ export default function Home() {
jsonFiles,
projectName,
maxVersesData,
bibleMetaData
licenseContent
) => {
setJsonFiles(jsonFiles);
setProjectName(projectName);
setMaxVerses(maxVersesData);
setBibleMetadata(bibleMetaData);
setLicenseData(licenseContent)
validateBooks(extractedFiles, maxVersesData);
const sortedBooks = sortBooks(extractedFiles);
setFiles(sortedBooks);
Expand Down Expand Up @@ -164,8 +164,9 @@ export default function Home() {
projectInstance={projectDB}
files={files}
setFiles={setFiles}
jsonFiles ={jsonFiles}
projectName={projectName}
bibleMetaData={bibleMetaData}
licenseData = {licenseData}
/>
</Box>
)}
Expand Down
26 changes: 14 additions & 12 deletions UI/app/utils/usfmProcessor.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Swal from "sweetalert2";
import LocalizedNames from "../store/localizedNames.json";

export const processUSFM = async (projectInstance, selectedBook, bibleMetaData) => {
export const processUSFM = async (projectInstance, selectedBook, download = true) => {
const keys = await projectInstance.keys();
const filteredKeys = keys.filter((key) => key.startsWith(selectedBook));

Expand All @@ -20,20 +20,22 @@ export const processUSFM = async (projectInstance, selectedBook, bibleMetaData)
}
return a.chapter - b.chapter; // Sort by chapter
});
// const metaData = bibleMetaData[selectedBook]
const metaData = LocalizedNames[selectedBook]
const usfmContent = generateUSFMContent(sortedData, selectedBook, metaData);

// Create a Blob and trigger download
const blob = new Blob([usfmContent], { type: "text/plain;charset=utf-8" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = `${selectedBook}.usfm`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
if (download) {
const blob = new Blob([usfmContent], { type: "text/plain;charset=utf-8" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = `${selectedBook}.usfm`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
} else {
return usfmContent;
}
};

const generateUSFMContent = (sortedData, selectedBook, metaData) => {
Expand Down

0 comments on commit 1fe1e84

Please sign in to comment.