Unverified Commit b62425bb authored by Kartheek Palla's avatar Kartheek Palla Committed by GitHub
Browse files

Merge pull request #147 from Samagra-Development/release-3.9.0

SB-23979: Support Comprehension Questions for Print Preview
No related merge requests found
Showing with 231 additions and 42 deletions
+231 -42
......@@ -15,6 +15,8 @@
"bluebird": "^3.7.2",
"cassandra-driver": "^4.4.0",
"chai-sorted": "^0.2.0",
"cheerio": "^1.0.0-rc.5",
"cheerio-tableparser": "^1.0.1",
"compression": "^1.7.4",
"cookie-parser": "~1.4.4",
"dateformat": "^3.0.3",
......
......@@ -29,7 +29,7 @@ async function printPDF(req, res) {
content_id: id,
base64string: binary,
},
};
};
res.send(resJSON);
} else {
res.contentType(`application/pdf; name=${id}.pdf`);
......
var PdfPrinter = require("pdfmake");
const { getData } = require("./dataImporter");
var {
docDefinition,
getStudentTeacherDetails,
......@@ -16,7 +15,13 @@ var {
getSA,
getVSA,
getLA,
getComprehension,
getMTFHeader,
getMTFChoice,
} = require("./utils/docDefinition");
var cheerio = require("cheerio");
var cheerioTableparser = require("cheerio-tableparser");
// /Users/apple/chaks/sunbird/exp/program-service/src/service/print/service/print/utils/fonts/Roboto/DroidSans-Bold.ttf
var fonts = {
Roboto: {
......@@ -64,6 +69,7 @@ const buildPDF = async (id) => {
const buildPDFWithCallback = (id, callback) => {
let error = false;
let errorMsg = "";
let totalMarks = 0;
getData(id)
.then((data) => {
if (data.error) {
......@@ -76,13 +82,19 @@ const buildPDFWithCallback = (id, callback) => {
let language = data.paperData.medium[0];
// const language = "Noto";
data.sectionData.forEach((d) => {
d.questions.forEach((element, index) => {
const marks = parseInt(d.section.children[index].marks);
if (!isNaN(marks)) totalMarks += marks;
});
});
const contentBase = [
getStudentTeacherDetails(),
getExamName(examName),
getGradeHeader(grade),
getSubject(subject),
getTimeAndMarks(),
getTimeAndMarks(90, totalMarks),
getInstructions(instructions, language),
];
......@@ -102,22 +114,26 @@ const buildPDFWithCallback = (id, callback) => {
questionCounter += 1;
const marks = section.children[index].marks;
let questionContent;
try {
try {
if (question.category === "MCQ")
questionContent = renderMCQ(question, questionCounter, marks);
questionContent = [renderMCQ(question, questionCounter, marks)];
else if (question.category === "FTB") {
questionContent = renderFTB(question, questionCounter, marks);
questionContent = [renderFTB(question, questionCounter, marks)];
} else if (question.category === "SA") {
questionContent = renderSA(question, questionCounter, marks);
questionContent = [renderSA(question, questionCounter, marks)];
} else if (question.category === "LA") {
questionContent = renderLA(question, questionCounter, marks);
questionContent = [renderLA(question, questionCounter, marks)];
} else if (question.category === "VSA") {
questionContent = renderVSA(question, questionCounter, marks);
questionContent = [renderVSA(question, questionCounter, marks)];
} else if (question.category === "TF") {
questionContent = renderTF(question, questionCounter, marks);
}
questionContent = [renderTF(question, questionCounter, marks)];
} else if (question.category === "MTF") {
questionContent = renderMTF(question, questionCounter, marks);
} else if(question.category === 'COMPREHENSION') {
questionContent = [renderComprehension(question, questionCounter, marks)]
}
questionPaperContent.push(questionContent);
questionPaperContent.push(...questionContent);
} catch (e) {
console.log(e);
}
......@@ -147,9 +163,9 @@ const buildPDFWithCallback = (id, callback) => {
});
};
const cleanHTML = (str) => {
const cleanHTML = (str, nbspAsLineBreak = false) => {
// Remove HTML characters since we are not converting HTML to PDF.
return str.replace(/<[^>]+>/g, "").replace("&nbsp;", "");
return str.replace(/<[^>]+>/g, "").replace(/&nbsp;/g, nbspAsLineBreak ? "\n" : "");
};
const detectLanguage = (str) => {
......@@ -228,6 +244,12 @@ function renderLA(question, questionCounter, marks) {
return getLA(questionTitle, detectLanguage(questionTitle[0]), marks);
}
function renderComprehension(question, questionCounter, marks) {
const questionTitle =
questionCounter + "." + cleanHTML(question.editorState.question, true);
return getComprehension(questionTitle, detectLanguage(questionTitle[0], marks));
}
function renderVSA(question, questionCounter, marks) {
const questionTitle =
questionCounter + ". " + cleanHTML(question.editorState.question);
......@@ -240,6 +262,35 @@ function renderTF(question, questionCounter, marks) {
return getTF(questionTitle, detectLanguage(questionTitle[0]), marks);
}
function renderMTF(question, questionCounter, marks) {
$ = cheerio.load(question.editorState.question);
cheerioTableparser($);
var data = [];
var columns = $("table").parsetable(false, false, false);
let transposeColumns = columns[0].map((_, colIndex) =>
columns.map((row) => row[colIndex])
);
const heading = questionCounter + ". " + cleanHTML($("p").text());
data.push(getFTB(heading, detectLanguage(heading), marks));
data.push(
getMTFHeader(
cleanHTML(transposeColumns[0][0]),
cleanHTML(transposeColumns[0][1]),
detectLanguage(cleanHTML(transposeColumns[0][0]))
)
);
transposeColumns.shift();
const rows = transposeColumns.map((r) => {
return getMTFChoice(cleanHTML(r[0]), cleanHTML(r[1]), detectLanguage(r[0]));
});
return data.concat(rows);
}
module.exports = {
buildPDF,
buildPDFWithCallback,
......
......@@ -47,27 +47,69 @@ const docDefinition = {
styles: styles,
};
function getLA() {
function getComprehension(questionTitle, language, marks) {
return {
text: "21. What advice did the old bird give to the other birds?",
style: "question_LA",
table: {
widths: ['100%', 'auto'],
body: [
[
{
border: [false, false, false, false],
text: questionTitle,
style: "question_COMPREHENSION",
font: language
},
{
border: [false, false, false, false],
text: marks,
style: "header_right"
}
]
]
}
}
}
function getLA(questionTitle, language, marks) {
return {
// Time + Marks
table: {
widths: ["*"],
widths: ["*", "auto"],
body: [
[
{
border: [false, false, false, false],
text: "21. What advice did the old bird give to the other birds?",
// Question LA
text: questionTitle,
style: "question_LA",
font: language,
table: {
widths: ["*"],
body: [
[
{
border: [false, false, false, false],
text: questionTitle,
style: "question_LA",
font: language,
},
],
[
{
border: [false, false, false, false],
text:
"_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________\n\n_______________________________________________________________________________________",
style: "question_VSA",
},
],
],
},
},
],
[
{
border: [false, false, false, false],
text:
"____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________\n\n____________________________________________________________________________________________",
style: "question_VSA",
text: marks,
style: "header_right",
},
],
],
......@@ -78,22 +120,38 @@ function getLA() {
function getVSA(questionTitle, language, marks) {
return {
table: {
widths: ["*"],
widths: ["*", "auto"],
body: [
[
{
border: [false, false, false, false],
text: questionTitle,
style: "question_VSA",
font: language,
// Question VSA
table: {
widths: ["*"],
body: [
[
{
border: [false, false, false, false],
text: questionTitle,
style: "question_VSA",
font: language,
},
],
[
{
border: [false, false, false, false],
text:
"______________________________________________________________________________________",
style: "question_VSA",
},
],
],
},
},
],
[
{
border: [false, false, false, false],
text:
"____________________________________________________________________________________________",
style: "question_VSA",
text: marks,
style: "header_right",
},
],
],
......@@ -167,6 +225,60 @@ function getTF(questionTitle, language, marks) {
};
}
function getMTFHeader(left, right, language) {
return {
table: {
widths: ["*", "*"],
body: [
[
{
border: [false, false, true, true],
margin: [40, 0],
text: left,
style: "question_MTF",
font: language,
bold: "true",
},
{
border: [false, false, false, true],
margin: [40, 0],
text: right,
style: "question_MTF",
bold: "true",
font: language,
},
],
],
},
};
}
function getMTFChoice(left, right, language) {
return {
table: {
widths: ["*", "*"],
body: [
[
{
border: [false, false, true, true],
text: left,
margin: [40, 0],
style: "question_MTF",
font: language,
},
{
border: [false, false, false, true],
text: right,
margin: [40, 0],
style: "question_MTF",
font: language,
},
],
],
},
};
}
function getFTB(questionTitle, language, marks) {
return {
// Time + Marks
......@@ -283,22 +395,17 @@ function getInstructions(instructions, language) {
};
}
function getTimeAndMarks() {
function getTimeAndMarks(time, marks) {
return {
table: {
widths: ["*", "*"],
widths: ["*"],
body: [
[
{
border: [false, false, false, false],
text: "Time - " + "90" + "Minutes",
text: "Marks - " + marks,
style: "header_left",
},
{
border: [false, false, false, false],
text: "Marks - " + "100",
style: "header_right",
},
],
],
},
......@@ -327,4 +434,7 @@ module.exports = {
getSA,
getVSA,
getLA,
getComprehension,
getMTFHeader,
getMTFChoice,
};
......@@ -48,6 +48,14 @@ const styles = {
fontSize: 12,
margin: [5, 5, 0, 5],
},
question_MTF: {
fontSize: 12,
margin: [5, 5, 0, 5],
},
question_COMPREHENSION: {
fontSize: 12,
margin: [5, 5, 0, 5]
}
};
function getInstructionStyle() {
......
......@@ -24,6 +24,9 @@ const getQuestionForSection = dataImporter.__get__("getQuestionForSection");
const getItemsFromItemset = dataImporter.__get__("getItemsFromItemset");
const getQuestionFromItem = dataImporter.__get__("getQuestionFromItem");
var cheerio = require("cheerio");
var cheerioTableparser = require("cheerio-tableparser");
// eslint-disable-next-line no-undef
describe("Print Service", () => {
it("[Integration test] should output error for wrong heirarchy ID", (done) => {
......@@ -119,7 +122,7 @@ describe("Print Service", () => {
"do_113213251762339840191",
(base64PDF, error, errorMsg) => {
expect(error).to.be.false;
expect(errorMsg).to.equal("");
expect(errorMsg).to.equal("");
done();
}
);
......@@ -143,4 +146,19 @@ describe("Print Service", () => {
done(e);
});
});
it("Should parse table", (done) => {
const table = `<p>Match the following:</p><figure class="table"><table><tbody><tr><td><strong>Column 1</strong></td><td><strong>Column 2</strong></td></tr><tr><td>1</td><td>1</td></tr></tbody></table></figure>`;
$ = cheerio.load(table);
cheerioTableparser($);
var data = [];
var columns = $("table").parsetable(false, false, false);
const transposeColumns = columns[0].map((_, colIndex) =>
columns.map((row) => row[colIndex])
);
const heading = $("p").text();
console.log(heading);
done();
});
});
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment