From b392a83b3fe0fb6156bf9650a8300fe7353a3a8a Mon Sep 17 00:00:00 2001 From: venkateswaran ubuntu Date: Fri, 24 Nov 2023 12:30:54 +0530 Subject: [PATCH] CRYPTO-NEW, EXPORT-NEW, ANSWER-JSON : RV --- .gitignore | 8 ++ addform.html | 65 ++++++++++++++- credentials/in/.gitkeep | 0 credentials/out/.gitkeep | 0 dashboard.html | 173 ++++++++++++++++++++++++++++++++++++--- decode.js | 51 ++++++++---- encode.js | 98 ++++++++++++++++++---- encodeEnv.js | 26 ++++++ html2json.js | 4 +- json2html.js | 2 + json2xml.js | 169 +++++++++++++++++++++++++++++++++++++- package-lock.json | 123 ++++++++++++++++++++++++++++ package.json | 2 + savexml.js | 99 +++++++++++++++------- style.css | 4 + xml/.gitkeep | 0 xml/Sample.xml | 1 + xml2json.js | 39 ++++++++- 18 files changed, 785 insertions(+), 79 deletions(-) create mode 100644 credentials/in/.gitkeep create mode 100644 credentials/out/.gitkeep create mode 100644 encodeEnv.js create mode 100644 xml/.gitkeep create mode 100644 xml/Sample.xml diff --git a/.gitignore b/.gitignore index 781ecc2..e0a0247 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,12 @@ dist/ .env xml/* !xml/Sample.xml +!xml/.gitkeep +credentials/in/* +credentials/out/* +!credentials/in/.gitkeep +!credentials/out/.gitkeep + + + diff --git a/addform.html b/addform.html index 7005100..5050098 100644 --- a/addform.html +++ b/addform.html @@ -399,6 +399,8 @@ border-color:#eee; margin-right: 0px; margin-top: 16px; + background: #1D3557; + } .popupbox q{ align-items: center; @@ -880,11 +882,68 @@ document.addEventListener('DOMContentLoaded', function () { } }) +// Function for Finding the JSON File in the folder +function findFile(filePath) { + try { + const stats = fs.statSync(filePath); + + if (stats.isFile()) { + + // File exists + // console.log(`File found at: ${filePath}`); + return true; + } else { + // console.error(`Path is not a file: ${filePath}`); + return false; + } + } catch (err) { + // console.error(`File not found: ${filePath}`); + return false; + } +} + + + + // Function to load XML from a file function loadXML(xmlFileName) { var decodeData =""; + var encodedXmlFilePath = `${xmlPath}${xmlFileName}`; + var jsonDecodeData = ""; + var jsonFileName = xmlFileName.split('.xml'); + var encodedJsonFilePath = `${xmlPath}${jsonFileName[0]}_answer.json`; + + var filelist = findFile(encodedJsonFilePath); + + if(filelist !== false) + { + //JSON File Read Function + new Promise((resolve, reject) => { + fs.readFile(encodedJsonFilePath, 'utf8', (error, data) => { + if (error) { + console.error('Error reading file:', error); + reject(error); + } else { + if (isEncrypted === 'YES') { + + jsonDecodeData = decode(encodedJsonFilePath); + localStorage.setItem('json_Decode_Data_For_Mcq_Crt_Ans', jsonDecodeData); + + } else{ + jsonDecodeData = data; + localStorage.setItem('json_Decode_Data_For_Mcq_Crt_Ans', jsonDecodeData); + + } + resolve(jsonDecodeData); + + } + }); + }); + } + +//XML File Read Function return new Promise((resolve, reject) => { fs.readFile(`${xmlPath}${xmlFileName}`, 'utf8', (error, data) => { if (error) { @@ -893,11 +952,13 @@ function loadXML(xmlFileName) { } else { if (isEncrypted === 'YES') { // decrypt function call go to decode.js - decodeData = decode(data); + decodeData = decode(encodedXmlFilePath); + } else{ decodeData = data; } - + + console.log('jsonDecodeData : ', jsonDecodeData); resolve(decodeData); xml2json(decodeData); // json2nav(); diff --git a/credentials/in/.gitkeep b/credentials/in/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/credentials/out/.gitkeep b/credentials/out/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/dashboard.html b/dashboard.html index 41ac827..28e08f3 100644 --- a/dashboard.html +++ b/dashboard.html @@ -302,6 +302,10 @@ margin-left: -16px; + + + + @@ -377,6 +381,8 @@ sourceStream.on('error', (err) => { diff --git a/decode.js b/decode.js index a4a4dda..ae7ba20 100644 --- a/decode.js +++ b/decode.js @@ -1,23 +1,46 @@ const crypto = require('crypto'); +function decode(encryptedDataFilePath) { + + // console.log('encryptedDataFilePath :', encryptedDataFilePath); + const privateKeyPath = process.env.PRIVATE_KEY_PATH; + const encryptedFileContent = fs.readFileSync(encryptedDataFilePath); + + // Extract the encrypted AES key, IV, and ciphertext + const encryptedAesKeyDec = encryptedFileContent.slice(0, 256); // Assuming 2048-bit RSA key, 256 bytes for the encrypted AES key + const ivDec = encryptedFileContent.slice(256, 256 + 16); // IV is 16 bytes + const ciphertext = encryptedFileContent.slice(256 + 16); -function decode(encryptedData) { try { - const algorithm = 'aes-256-cbc'; - const iv = Buffer.from(encryptedData.slice(0, 24), 'base64'); - const keyHex = 'd0ca711dc0c599de0847cb86f415cd34d602a322f0f07dc89bce9e1481f481b3'; - const derivedKey = Buffer.from(keyHex, 'hex'); - const encryptedText = encryptedData.slice(24); + + // Decrypt the AES key with the private key + const privateKeyObj = fs.readFileSync(privateKeyPath, 'utf-8'); + const decryptedAesKey = crypto.privateDecrypt( + { + key: privateKeyObj, + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, + oaepHash: 'sha256', + }, + encryptedAesKeyDec + ); - const decipher = crypto.createDecipheriv(algorithm, derivedKey, iv); - let decrypted = decipher.update(encryptedText, 'base64', 'utf8'); - decrypted += decipher.final('utf8'); + // Decrypt the file using AES + // const decipher = crypto.createDecipheriv('aes-128-cbc', decryptedAesKey, ivDec); + // let decryptedData = decipher.update(ciphertext); + // decryptedData = Buffer.concat([decryptedData, decipher.final()]); - console.log('Decrypted String:', decrypted); - return decrypted; + const decipher = crypto.createDecipheriv('aes-128-cbc', decryptedAesKey, ivDec); + let decryptedData = decipher.update(ciphertext, 'hex', 'utf-8'); + decryptedData += decipher.final('utf-8'); + + // console.log('File decrypted successfully.'); + // console.log('Decrypted String:', decryptedData); + return decryptedData; + } catch (error) { - console.error('Decryption failed:', error.message); - return null; + + console.error('Decryption failed:', error.message); + return null; } } - module.exports = decode; +module.exports = decode; diff --git a/encode.js b/encode.js index eef840a..e7aa3b6 100644 --- a/encode.js +++ b/encode.js @@ -1,23 +1,93 @@ +const fs = require('fs'); const crypto = require('crypto'); -function encode(inputString) { - try { - const algorithm = 'aes-256-cbc'; - const iv = crypto.randomBytes(16); - const keyHex = 'd0ca711dc0c599de0847cb86f415cd34d602a322f0f07dc89bce9e1481f481b3'; - const derivedKey = Buffer.from(keyHex, 'hex'); - const cipher = crypto.createCipheriv(algorithm, derivedKey, iv); +function encode(inputString, downloadFilePath = false) { - let encrypted = cipher.update(inputString, 'utf8', 'base64'); - encrypted += cipher.final('base64'); + console.log('encod downloadFilePath : ', downloadFilePath) + + var certificatePath = ''; + + if(downloadFilePath !== false) + { + certificatePath = process.env.DOWNLOAD_PUBLIC_KEY_PATH; + } + else{ + certificatePath = process.env.PUBLIC_KEY_PATH; + } + +try { + + const aesKey = crypto.randomBytes(16); // Change the byte length for different key lengths + const iv = crypto.randomBytes(16); // Initialization vector for AES-CBC + + // Encrypt the file using AES + const cipher = crypto.createCipheriv('aes-128-cbc', aesKey, iv); + let encryptedData = cipher.update(inputString); + encryptedData = Buffer.concat([encryptedData, cipher.final()]); + + // Get the public key from the self-signed certificate + const publicKey = fs.readFileSync(certificatePath, 'utf-8'); + + // Encrypt the AES key with the public key + const encryptedAesKey = crypto.publicEncrypt( + { + key: publicKey, + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, + oaepHash: 'sha256', + }, + aesKey + ); + + // Save the encrypted file and encrypted AES key + var encryptedResult = Buffer.concat([encryptedAesKey, iv, encryptedData]) + console.log('File encrypted successfully.'); + console.log('Encrypted String:', encryptedResult); + + if(downloadFilePath !== false) + { + try { + fs.writeFileSync(downloadFilePath, encryptedResult); + console.log('File downloaded successfully.'); + Swal.fire({ + title: "File Downloaded", + icon: "success" + }); + } catch (error) { + console.error('Error writing file:', error.message); + var errorMessage = ""; + + if(error.code == 'EACCES'){ + + errorMessage = `Permission Denied.
Path: ${downloadFilePath}`; + } + else if(error.code == 'ENOENT'){ + + errorMessage = `No Such File Directory.
Path: ${downloadFilePath}`; + } + else{ + errorMessage = `Unknown Error.
Path: ${downloadFilePath}`; + } + + Swal.fire({ + title: "File Download Failed", + html: errorMessage, + icon: "warning" + }); + + } + } + else{ + + return encryptedResult; + + } + +} catch (error) { - const encryptedData = iv.toString('base64') + encrypted; - console.log('Encrypted String:', encryptedData); - return encryptedData; - } catch (error) { console.error('Encryption failed:', error.message); return null; - } + +} } module.exports = encode; diff --git a/encodeEnv.js b/encodeEnv.js new file mode 100644 index 0000000..e35279c --- /dev/null +++ b/encodeEnv.js @@ -0,0 +1,26 @@ +const fs = require('fs'); + +// Function to encode data to base64 +function encodeToBase64(data) { + return Buffer.from(data, 'utf-8').toString('base64'); +} + +// Function to encode .env file to base64 +function encodeEnvFileToBase64(envFilePath, outputFilePath) { + // Read the content of the .env file + const envData = fs.readFileSync(envFilePath, 'utf-8'); + + // Encode the data to base64 + const base64Data = encodeToBase64(envData); + + // Write the base64-encoded data to a new file + fs.writeFileSync(outputFilePath, base64Data, 'utf-8'); + + console.log('File encoded to base64 successfully.'); +} + +// Example usage +const envFilePath = '/.env'; +const outputFilePath = '/encoded_base64.env'; + +encodeEnvFileToBase64(envFilePath, outputFilePath); diff --git a/html2json.js b/html2json.js index 8e9a63a..4ef33f4 100644 --- a/html2json.js +++ b/html2json.js @@ -84,7 +84,7 @@ function html2json() { var groupChoiceId = ((element.id).split('_').slice(-1)[0]).split('.').slice(0)[0]; var individualChoiceId = (element.id).split('.').slice(-1)[0]; - console.log('newChoiceTextField_'+groupChoiceId+'.'+individualChoiceId); + // console.log('newChoiceTextField_'+groupChoiceId+'.'+individualChoiceId); var choice_math_Enabled = document.getElementById('choice_math_' + groupChoiceId + '.' + individualChoiceId).checked; var choice_name = ""; @@ -276,6 +276,6 @@ function html2json() { // console.log((formData)); // console.log(JSON.stringify(formData, null, 1)); localStorage.setItem("json", JSON.stringify((formData))); - console.log(JSON.stringify(formData)); + // console.log(JSON.stringify(formData)); // console.log(OBJtoXML(({'question_paper' : formData}))); } diff --git a/json2html.js b/json2html.js index aebdf74..d239567 100644 --- a/json2html.js +++ b/json2html.js @@ -5,6 +5,7 @@ function jsonToHtml(jsonData) { localStorage.setItem('scroll', 1) localStorage.setItem('EditNavExpend', 1) + const count = jsonData.sections.length; // console.log(`Count of sections: ${count}`); @@ -138,6 +139,7 @@ function QuestionsForEach(Question, questionAreaId, questionRandomNo){ groupQuestion(false, false, false, questionTitle, questionDescription, questionType, questionSubType, mathEnabled, Choice, questionAreaId, questionRandomNo, questionMarks, questionUUID, questionDisplayMarks,); // groupQuestion(QuestionObj); + Choice = Choice.slice(1); Choice.forEach(function(choicenames, index) { var choiceName = choicenames.choice_name; diff --git a/json2xml.js b/json2xml.js index 9a1060e..9830368 100644 --- a/json2xml.js +++ b/json2xml.js @@ -1,6 +1,143 @@ function json2xml() { // console.clear(); var obj = localStorage.getItem("json"); + // var obj = `{ + // "question_paper_title": "


", + // "question_paper_description": "


", + // "max_marks": "", + // "course_ID": "", + // "course_Code": "", + // "subject_ID": "", + // "subject_Code": "", + // "paper_No": "", + // "subject_Name": "", + // "sub_Paper_Prefix": "", + // "question_Paper_uuid": "f676ad21-b0d2-4a80-8c77-6cd2b35f1b34", + // "sections": [ + // { + // "section_title": "

0

", + // "section_description": "


", + // "section_marks": "0", + // "section_uuid": "7c62e594-3b93-444f-9fa6-a05f87869db6", + // "section_display_marks": true, + // "section_attempt_any": "", + // "questions": [ + // { + // "question": "

1

", + // "question_description": "


", + // "question_type": "group", + // "question_sub_type": false, + // "is_math_enabled": false, + // "display_marks": true, + // "marks": "", + // "choice_question_uuid": "40f37294-e7cb-4f19-9166-72f7a04f6391", + // "answers": [ + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "387d9b85-4702-4e77-a8c3-29d713b7689e", + // "no": "a" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "1a6be686-9e7c-4b07-bf15-b9e07a01fd62", + // "no": "b" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "0640c05b-522e-422c-8050-0d5982aa3c74", + // "no": "c" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "e59f90b0-79d5-413e-85a4-ee3c181230d8", + // "no": "d" + // } + // ], + // "correct_answer": ["1a6be686-9e7c-4b07-bf15-b9e07a01fd62"] + // }, + // { + // "question": "

2

", + // "question_description": "


", + // "question_type": "group", + // "question_sub_type": false, + // "is_math_enabled": false, + // "display_marks": true, + // "marks": "", + // "choice_question_uuid": "7a1c83e7-e9ae-4424-9336-6135eaa6b833", + // "answers": [ + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "0cbb8330-8ce9-4d69-b547-68cee529a636", + // "no": "a" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "25dc4fdc-7bcf-4bea-aaa5-dc42a22c08b5", + // "no": "b" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "5b0da327-076f-488c-a46e-0b8251c83283", + // "no": "c" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "d3934305-d6fd-4601-8b1b-08067f47a8dd", + // "no": "d" + // } + // ], + // "correct_answer": ["d3934305-d6fd-4601-8b1b-08067f47a8dd"] + // }, + // { + // "question": "

3

", + // "question_description": "


", + // "question_type": "group", + // "question_sub_type": false, + // "is_math_enabled": false, + // "display_marks": true, + // "marks": "", + // "choice_question_uuid": "6f929b53-9ebc-40fb-800e-46c42b75f2d9", + // "answers": [ + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "f839312c-8de5-4cd5-8d6c-3ffd3b9efea6", + // "no": "a" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "905db769-82b2-4240-af06-fe0b15ee1f73", + // "no": "b" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "6a16126f-8100-49f8-ae33-71d4848030cf", + // "no": "c" + // }, + // { + // "choice_name": "


", + // "is_math_enabled": false, + // "choice_uuid": "143f648a-d52c-42ff-9428-1c080326e1c8", + // "no": "d" + // } + // ], + // "correct_answer": ["143f648a-d52c-42ff-9428-1c080326e1c8", "6a16126f-8100-49f8-ae33-71d4848030cf"] + // } + // ] + // } + // ] + // } + // ` // console.log(obj); // console.log('***********************************************************'); @@ -177,7 +314,7 @@ function json2xml() { //create section related xml nodes var tempSection = questionPaper['sections'][section]; - console.log(tempSection); + // console.log(tempSection); var sectionElement = createElementWithText(xmlDoc, rootItemsElement, 'Question', '', { 'xsi:type': 'QuestionPaperSection', @@ -199,6 +336,14 @@ function json2xml() { if (tempSection['questions'].length != 0) { for (question in tempSection['questions']) { var singleQuestion = tempSection['questions'][question]; + + //for Separate Correct Answer From MCQ + if(singleQuestion.question_type == 'group'){ + + separateCorrectAnswerFromMcqAsJson(singleQuestion) + } + + if (singleQuestion.hasOwnProperty('question_type')) // normal questions { var singleQuestionElement = getXMLNodesOfQuestionData(singleQuestion); @@ -224,3 +369,25 @@ function json2xml() { localStorage.setItem("xml", xmlString); } + + +const outputJson = { questions: [] }; + +function separateCorrectAnswerFromMcqAsJson(tempSection) { + +const questionId = tempSection.choice_question_uuid; +const answers = tempSection.correct_answer; + +// Create an object for each question and push it to the output array +outputJson.questions.push({ + questionId, + answers +}); + +// Convert the output object to JSON string +const outputJsonString = JSON.stringify(outputJson, null, 2); +localStorage.setItem("Correct_Answer_Json", outputJsonString); +console.log('outputJsonString : ', outputJsonString); + +} + diff --git a/package-lock.json b/package-lock.json index 65ec8da..ad2b5b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "cheerio": "^1.0.0-rc.12", "desandro-matches-selector": "^2.0.2", "dotenv": "^16.3.1", + "electron-dl": "^3.5.1", + "electron-download-manager": "^2.1.2", "ev-emitter": "^2.1.2", "fizzy-ui-utils": "^3.0.0", "formidable": "^3.5.1", @@ -1043,6 +1045,27 @@ "node": ">= 12.20.55" } }, + "node_modules/electron-dl": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.5.1.tgz", + "integrity": "sha512-5Yb9s/iPVJ5mW5x3j6XkKxt7WEqREr/AhYxZmtEfW1ffQHs1+aGoiQ2fXCAU6UIXMnWog2MXK82vrxJsjA3nbQ==", + "dependencies": { + "ext-name": "^5.0.0", + "pupa": "^2.0.1", + "unused-filename": "^2.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-download-manager": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/electron-download-manager/-/electron-download-manager-2.1.2.tgz", + "integrity": "sha512-9v8aeMVZTX69NjEveKlKfTlJY74twpKktTXrmDI+UcQHZg7FtwuqxWw0ZNrjtVAOBcVNKzwG4ekn44B+xhz1tg==" + }, "node_modules/electron-packager": { "version": "17.1.2", "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-17.1.2.tgz", @@ -1255,6 +1278,14 @@ "dev": true, "optional": true }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "engines": { + "node": ">=8" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1278,6 +1309,29 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -2145,6 +2199,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -2440,6 +2502,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/modify-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz", + "integrity": "sha512-EickqnKq3kVVaZisYuCxhtKbZjInCuwgwZWyAmRIp1NTMhri7r3380/uqwrUHfaDiPzLVTuoNy4whX66bxPVog==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2947,6 +3017,17 @@ "node": ">=6" } }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -3213,6 +3294,28 @@ "node": ">=8" } }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -3415,6 +3518,26 @@ "node": ">= 4.0.0" } }, + "node_modules/unused-filename": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-2.1.0.tgz", + "integrity": "sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==", + "dependencies": { + "modify-filename": "^1.1.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unused-filename/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", diff --git a/package.json b/package.json index bc37070..9fa0ad9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,8 @@ "cheerio": "^1.0.0-rc.12", "desandro-matches-selector": "^2.0.2", "dotenv": "^16.3.1", + "electron-dl": "^3.5.1", + "electron-download-manager": "^2.1.2", "ev-emitter": "^2.1.2", "fizzy-ui-utils": "^3.0.0", "formidable": "^3.5.1", diff --git a/savexml.js b/savexml.js index 99f5213..af79875 100644 --- a/savexml.js +++ b/savexml.js @@ -34,53 +34,90 @@ files.forEach((file) => { //////// //end the autosave -function saveXmlToFile(xmlData, filePath,reorder=false, xmlfilename) { - // console.log(xmlfilename); - // console.log(filePath); - // Check if the file path is provided - if (!filePath) { - console.error('File path is required.'); - return; - } + function saveXmlToFile(xmlData, filePath,reorder=false, xmlfilename, jsonData, jsonfilePath) { + // console.log(xmlData); + // console.log(filePath); + // Check if the file path is provided + if (!filePath) { + console.error('File path is required.'); + return; + } + + // Write the XML data to the specified file path + fs.writeFileSync(filePath, xmlData, 'utf8', (err) => { + console.log("fs write inside "); + alert("fs write inside") + if (err) { + console.error('Error writing XML file:', err); + } else { + console.log('XML file saved successfully.'); + + // Clear all data in local storage + localStorage.clear(); + + } + }); - // Write the XML data to the specified file path - fs.writeFileSync(filePath, xmlData, 'utf8', (err) => { - console.log("fs write inside "); - alert("fs write inside") - if (err) { - console.error('Error writing XML file:', err); - } else { - console.log('XML file saved successfully.'); + if(jsonData !== ""){ - // Clear all data in local storage - localStorage.clear(); + // Write the JSON data to the specified file path + fs.writeFileSync(jsonfilePath, jsonData, 'utf8', (err) => { + + if (err) { + console.error('Error writing XML file:', err); + } else { + console.log('JSON file saved successfully.'); + + localStorage.clear(); + + } + }); } - }); - localStorage.clear(); - if(reorder){ - window.location.reload(); - }else{ - window.location.href = 'addform.html?filename=' + xmlfilename; - // window.location.reload(); + - } + + localStorage.clear(); + if(reorder){ + window.location.reload(); + }else{ + window.location.href = 'addform.html?filename=' + xmlfilename; + // window.location.reload(); - } + } + + } function savexml(UserFilename,reorder=false) { console.log("reorder",reorder); // Get the XML string from localStorage var xmlString = localStorage.getItem("xml"); + var jsonString = localStorage.getItem("Correct_Answer_Json"); + console.log('save json : ', jsonString); + console.log('save xml : ', xmlString); + //check Encrypted or not var enc = ""; + var encJson = ""; if (isEncrypted === 'YES') { // Encrypt enc = encode(xmlString); + if(jsonString) + { + encJson = encode(jsonString); + } } else { enc = xmlString; + if(jsonString) + { + encJson = jsonString; + } + } + + console.log('save xml : ', enc); + //XmlPath get from .env const xmlPathenv=process.env.XML_FILE_PATH; const xmlPath = path.join(__dirname, xmlPathenv) @@ -89,20 +126,20 @@ function savexml(UserFilename,reorder=false) { // Create a filename using on the subtitle var xmlfilename = `${UserFilename}.xml`; - console.log('xmlfilename : ', xmlfilename) - // var jsonfilename = `${UserFilename}.json`; + var jsonfilename = `${UserFilename}_answer.json`; // file path where you want to save the XML file // const xmlfilePath = process.cwd() + `/${xmlPath}` + xmlfilename; const xmlfilePath = `${xmlPath}` + xmlfilename; + const jsonfilePath = `${xmlPath}` + jsonfilename; // const jsonfilePath = process.cwd() + '/xml/' + jsonfilename; if(reorder){ - saveXmlToFile(enc, xmlfilePath,reorder=true, xmlfilename); + saveXmlToFile(enc, xmlfilePath,reorder=true, xmlfilename, encJson, jsonfilePath); }else{ // Call the function to save the XML file - saveXmlToFile(enc, xmlfilePath, false, xmlfilename); + saveXmlToFile(enc, xmlfilePath, false, xmlfilename, encJson, jsonfilePath); } } diff --git a/style.css b/style.css index 5076511..0e86996 100644 --- a/style.css +++ b/style.css @@ -3712,6 +3712,10 @@ width:85px; .modal_form_button button:hover{ background: #bf303b; +} +.popup-save button:hover{ + background: #bf303b; + } ::-webkit-scrollbar-thumb { diff --git a/xml/.gitkeep b/xml/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/xml/Sample.xml b/xml/Sample.xml new file mode 100644 index 0000000..5e65272 --- /dev/null +++ b/xml/Sample.xml @@ -0,0 +1 @@ +<p><strong>Monthly Question Paper what </strong><span class="ql-cursor"></span></p><p>May Month Test Question Paper</p><p>Section c</p><p>Two Mark Question</p>2000true2<p>What is Laptop</p><p>Describe 20 words</p>1000truefalse<p>Who discover the laptop</p><p>pick one answer</p>1000falsefalsetrue8322d364-db1d-444d-bab0-dec8dd668375a<p>ch 1</p>false2b7a8bd3-db2b-4a97-bc78-59a77e72e0a7b<p>ch 1</p>false1a755857-3e4d-436a-a4f7-aaf29171e349c<p>ch 2</p>falseba1299c9-97e4-4d99-a183-e1f7b719bb96d\sqrt2true<p>s1 q1</p><p>Description</p>1000false1<p>Describe the Mobile Phone</p><p>Describe 20 words</p>1000falsefalse<p>1</p><p>pick one answer</p>1000falsefalsefalse7d15a61c-e4dc-47a5-93d1-41f00611814ca<p>ch 1</p>falsee777ddfe-d7b3-4563-8282-944f46716bffb<p>ch 2</p>falsefb957850-9d6b-4fed-8ad9-bfaf8261a7e8c<p>ch 3</p>false<p>s1 q2</p><p>Description</p>1000false2<p>1</p><p>Describe 20 words</p>500falsefalse<p>Who Discover the mouse</p><p>pick one answer</p>500falsefalsefalsea80ce15a-bed0-4543-ab0f-361f55ba5a27a<p>ch 1</p>falseb73e9ab0-5351-4e62-83a9-69a6a87ac3c2b<p>ch2</p>false4b798f3d-5004-49d1-b008-57fb607d3e68c<p>ch3</p>false0dc2a56e-0d28-4f2a-bfc2-18e105569c07d<p>ch4</p>false<p>s1 q3</p><p>Desciption</p>500false1<p>What is RAM</p><p>Describe 20 words</p>500falsefalse<p>Who Discover the RAM</p><p>pick one answer</p>500falsefalsefalse10d6607c-29a8-4885-ad12-f2118e12f1e7a<p>ch 1</p>falseb831ded1-3550-432a-b0bb-a180847a14b9b<p>ch 2</p>false32c91506-b8af-44f7-b548-97fd3c456cfbc<p>ch 3</p>false<p>s1 q4</p><p>description</p>500false2<p>solve it that is tje what is the werwerer</p>\sqrt{25}=?250falsetrue<p>solve it</p>\sqrt{25}=?250falsetruefalse213a3ffd-4680-456a-b459-8e0a5023838da5true98a2297b-08fe-416d-acb8-28794962d2e7b<p><br></p>false04ae1f66-8099-4fc9-b3f1-09c12a303646c<p><br></p>false89d8e74d-f3fb-4817-b756-aca13b52b41ed<p><br></p>false<p>1</p><p><br></p>250truefalse<p>1</p><p><br></p>1000truefalse<p>Section B</p><p>Description</p>20true<p>S2 Q1</p><p><br></p>2truefalse<p>S2 QG1 2</p><p>dfdasdfasd</p>16true<p>S2 QG1 Q2</p><p>sdgdfgdfgdfgsdgsddgsdgsddgsdgsddgfs</p>2truefalsetruea04d0e78-7892-4a49-9e45-363be6985aa3a<p>fhgfdgh</p>falsebe8a955e-dadd-44f0-9f59-a182fa7ebb8fb<p>fdghdfgh</p>false47bb7bb9-337e-4838-9fbf-1c8678ba3e22c<p>fghdgfghdgf</p>false61fec00a-4075-4807-88bc-be278a3c4992d<p>dfghdfghd</p>falsedb3f1ca5-083a-432d-8fae-f94d944e4989e<p>dfgdfgsdfg</p>false<p>S2 QG2 Q1</p><p>dsfgsdfgsdfgsdfg</p>2falsefalse<p>S2 QG2</p><p>dfgsdfgsdfgsdfg</p>12false<p>S2 QG2 Q1</p><p>fdgdsfgsdfgsdfgsdfgsdfg</p>2falsefalse<p>S2 QG2 Q2</p><p>fdgsdfgdsfgsdfg</p>2truefalsetrue0df34d5a-927a-4ecf-b22f-8acf66a2f979a<p>fsdgsdfgsdfgsdf</p>false03cbc474-aeea-4a81-9c97-ee14843f3e89b<p>sdfgsdfgsdfgsd</p>false038e0125-dab8-48e0-9e89-2b1417221b9bc<p>dfgdsfgdsf</p>falseeaba5d1a-a0c5-4d8e-827f-03fd094345d9d<p>fgsdfgdsfgsdfgdsfgdfgsdf</p>false<p>S2 QG3</p><p><br></p>8false<p>S2 QG3 Q1</p><p><br></p>2truefalse<p>S2 QG3 Q2</p><p><br></p>2truefalsetrue94c5fd0e-444f-4fca-a516-a6bb93b52602a<p><br></p>false<p>S2 QG4</p><p><br></p>4true<p>S2 QG4 Q1</p><p><br></p>2truefalse<p>S2 QG4 Q2</p><p>xfdgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsd</p>2truefalsetrue30dbde59-a12e-4fb5-b0cf-2a0ef997ece6atrue1394d4bd-cd38-47a7-9e80-c4f26466cc78btrue43c3971a-9799-4698-8570-6048d4b79b67ctrue8410a092-c4e1-46da-8215-7bb8b3b50dacdtrue<p>S2 Q2</p><p><br></p>2truefalsetruefa186388-6f21-40dc-bf5c-e52910f560a1a<p><br></p>false<p>test</p><p><br></p>truefalse \ No newline at end of file diff --git a/xml2json.js b/xml2json.js index e8a7d6a..fd07522 100644 --- a/xml2json.js +++ b/xml2json.js @@ -1,9 +1,11 @@ - function xml2json(xmlData) { // console.clear(); // console.log('xml to json converstion'); // console.log(xmlData); +var jsonDecodeData = localStorage.getItem('json_Decode_Data_For_Mcq_Crt_Ans'); +// console.log(jsonDecodeData); + function getAttributesOfXMLNode(node) { // Get attributes of the node (if any) @@ -45,6 +47,7 @@ function getQuestionsNodes(questionNode,type) questionObj['display_marks'] = questionNode.childNodes[3].firstChild.nodeValue; questionObj['is_math_enabled'] = questionNode.childNodes[4].firstChild.nodeValue; questionObj['answers'] = []; + questionObj['correct_answer'] = []; var choiceList = questionNode.childNodes[6].childNodes; @@ -61,6 +64,36 @@ function getQuestionsNodes(questionNode,type) questionObj['answers'].push(tempChoiceobj); } } + if(jsonDecodeData !== null) + { + var jsonParsedData = JSON.parse(jsonDecodeData); + + // console.log('jsonParsedData : ', jsonParsedData) + + // Iterate over each question + for (const question of jsonParsedData.questions) { + + const questionId = question.questionId; + const answers = question.answers; + + console.log(typeof answers) + + // console.log(`Question ID: ${questionId}`); + + if(answers !== undefined) { + // console.log(`Not Undifined Answer`); + for (const answer of answers) { + + // console.log(` Answer ID: ${answer}`); + + if(questionId == questionObj['attributes']['Id']) { + questionObj['correct_answer'].push(answer); + } + } + } + } + // console.log('jsonDecodeData.length', jsonDecodeData); + } } return questionObj; @@ -165,10 +198,12 @@ jsonObj['sections'] = []; var jsonData = JSON.stringify(jsonObj); // console.log('Xml to Json Conversion '); - // console.log(jsonData); + console.log('jsonData : ', jsonData); // console.log(jsonObj); jsonToHtml(jsonObj); // console.log(jsonToHtml(jsonObj)) + localStorage.removeItem('json_Decode_Data_For_Mcq_Crt_Ans'); + }