commit 71cb49a7e42f7c895a193e47dbe0157774fce082 Author: Matei Adriel Date: Thu Nov 5 08:48:37 2020 +0200 javascript(quizizz-hack): feat: cli Signed-off-by: prescientmoon diff --git a/javascript/quizizz-hack/.gitignore b/javascript/quizizz-hack/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/javascript/quizizz-hack/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/javascript/quizizz-hack/file.json b/javascript/quizizz-hack/file.json new file mode 100644 index 0000000..7297271 --- /dev/null +++ b/javascript/quizizz-hack/file.json @@ -0,0 +1 @@ +{"success":true,"message":"Ok","data":{"quiz":{"isTagged":false,"isLoved":false,"stats":{"played":1028,"totalPlayers":1275,"totalCorrect":4570,"totalQuestions":9060},"love":0,"cloned":false,"parentDetail":null,"deleted":false,"draftVersion":null,"publishedVersion":"5eb92da422b3ee001b108a59","type":"quiz","_id":"5eb925fb3cd22e001daa1bde","info":{"_id":"5eb92da422b3ee001b108a59","traits":{"isQuizWithoutCorrectAnswer":false},"pref":{"time":null},"lang":"Romanian, Moldavian, Moldovan","visibility":true,"questions":[{"_id":"5eb92642fd4004001c79d153","type":"MCQ","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"kind":"MCQ","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

Este egalitate.

","media":[]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

Its a tie.

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

It's a tie.

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

Tie.

","media":[]}],"answer":1,"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:17:38.188Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000},{"_id":"5eb9271dfbed6b001bd44777","type":"BLANK","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"answer":[],"kind":"BLANK","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

Choose the correct form of the word coechipier

teammate / mate / colleague

","media":[]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"teammate ","media":[]}],"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:21:17.638Z","updated":"2020-10-12T16:29:18.682Z","topics":[],"cached":true,"time":10000},{"_id":"5eb92836574fd4001c510aa1","type":"MSQ","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"answer":[2],"kind":"MSQ","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

Football is a sport that can be played outdoor also.

","media":[]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

Fotbalul este un sport care se poate juca doar afară.

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

Fotbalul este un sport.

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

Fotbalul este un sport care se poate juca și afară.

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

Fotbalul este un sport care se joacă doar afară.

","media":[]}],"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:25:58.316Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000},{"_id":"5eb928ecef7bb4001b8f6e83","type":"BLANK","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"answer":[],"kind":"BLANK","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

What is this?

","media":[{"type":"image","url":"https://quizizz.com/media/resource/gs/quizizz-media/quizzes/a5f19ee0-db31-4f79-9e0c-4b0b9ddabd7d","meta":{"width":275,"height":183,"text":null,"bgColor":null}}]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"award","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"prize","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"trophy","media":[]}],"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:29:00.673Z","updated":"2020-10-12T16:29:18.682Z","topics":[],"cached":true,"time":10000},{"_id":"5eb92969340ff4001c09d3ba","type":"MCQ","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"kind":"MCQ","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

to dribble = _______________?

","media":[]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

a dribla

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

a pasa

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

a lovi

","media":[]}],"answer":0,"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:31:05.378Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000},{"_id":"5eb92a13f240fb001bf388e2","type":"BLANK","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"answer":[],"kind":"BLANK","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

Write the suitable verb:

","media":[{"type":"image","url":"https://quizizz.com/media/resource/gs/quizizz-media/quizzes/4d900dbb-6124-4e25-becc-ca1f409dc614","meta":{"width":2000,"height":1335,"text":null,"bgColor":null}}]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"to cheer on","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"cheer on ","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"cheering on ","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"to encourage","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"encourage","media":[]}],"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:33:55.574Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000},{"_id":"5eb92a8e44acee001c920b2b","type":"MSQ","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"answer":[1],"kind":"MSQ","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

Netball is similar to ___________

","media":[]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

volleyball

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

basketball

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

swimming

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

football

","media":[]}],"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:35:58.434Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000},{"_id":"5eb92b7a22b3ee001b1088d8","type":"MCQ","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"kind":"MCQ","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"","media":[{"type":"image","url":"https://quizizz.com/media/resource/gs/quizizz-media/quizzes/4ff5b765-09ba-470c-a03b-104e663c6bbe","meta":{"width":259,"height":194,"text":null,"bgColor":null}}]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

It's a tie.

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

It's tie.

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

Tie.

","media":[]}],"answer":0,"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:39:54.130Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000},{"_id":"5eb92bab68b5c6001cd30787","type":"MSQ","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"answer":[0],"kind":"MSQ","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

Tie can also mean:

","media":[]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

cravată

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

eșarfă

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

cămașă

","media":[]}],"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:40:43.785Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000},{"_id":"5eb92c7fef7bb4001b8f70ff","type":"MSQ","published":true,"structure":{"settings":{"hasCorrectAnswer":true},"answer":[2,0],"kind":"MSQ","query":{"math":{"latex":[],"template":null},"type":null,"hasMath":false,"text":"

This makes you think about ...

","media":[{"type":"image","url":"https://quizizz.com/media/resource/gs/quizizz-media/quizzes/9311836c-1106-4092-8a22-8a0c60dc49e5","meta":{"width":1600,"height":1098,"text":null,"bgColor":null}}]},"options":[{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

free time

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

work

","media":[]},{"math":{"latex":[],"template":null},"type":"text","hasMath":false,"text":"

leisure time

","media":[]}],"hasMath":false},"standards":[],"createdAt":"2020-05-11T10:44:15.347Z","updated":"2020-05-11T10:49:23.315Z","topics":[],"cached":true,"time":10000}],"subjects":["English"],"topics":[],"subtopics":[],"grade":["3","6"],"gradeLevel":null,"deleted":false,"standards":[],"name":"Sports","image":"https://quizizz.com/media/resource/gs/quizizz-media/quizzes/d84034df-e1a8-4b35-a58b-0eaf704dfae0","qm":{"5eb92642fd4004001c79d153":{"time":10000},"5eb9271dfbed6b001bd44777":{"time":10000},"5eb92836574fd4001c510aa1":{"time":10000},"5eb928ecef7bb4001b8f6e83":{"time":10000},"5eb92969340ff4001c09d3ba":{"time":10000},"5eb92a13f240fb001bf388e2":{"time":10000},"5eb92a8e44acee001c920b2b":{"time":10000},"5eb92b7a22b3ee001b1088d8":{"time":10000},"5eb92bab68b5c6001cd30787":{"time":10000},"5eb92c7fef7bb4001b8f70ff":{"time":10000}},"createdAt":"2020-05-11T10:49:08.702Z","updated":"2020-05-11T10:49:23.317Z","profane":false,"isProfane":false,"whitelisted":true,"cached":true,"courses":[]},"createdBy":{"local":{"username":"luanarusu_40925","casedUsername":"luanarusu_40925"},"google":{"createdAt":"2020-03-12T15:51:44.449Z","profileId":"114348773100945102940","email":"luanarusu@gmail.com","displayName":"Luana S. Rusu","firstName":"Luana","lastName":"Rusu","image":"https://lh3.googleusercontent.com/a-/AOh14GiafsFlgPUPGZ_12C1QJ2t0b00my3P59Q7v-5-G"},"student":null,"deactivated":false,"deleted":false,"_id":"5e6a5a90db7068001ba21559","country":"RO","media":"https://lh3.googleusercontent.com/a-/AOh14GiafsFlgPUPGZ_12C1QJ2t0b00my3P59Q7v-5-G","firstName":"Luana","lastName":"Rusu","occupation":"teacher","id":"5e6a5a90db7068001ba21559"},"createdAt":"2020-05-11T10:16:27.220Z","updated":"2020-10-25T14:22:05.153Z","hasPublishedVersion":true,"hasDraftVersion":false},"draft":null},"meta":{"service":"q_api_all","version":"6ab75e6_30e4a80"}} \ No newline at end of file diff --git a/javascript/quizizz-hack/index.js b/javascript/quizizz-hack/index.js new file mode 100644 index 0000000..6ccb52f --- /dev/null +++ b/javascript/quizizz-hack/index.js @@ -0,0 +1,109 @@ +const fetch = require("node-fetch"); +const chalk = require("chalk"); +const { default: readline } = require("readline-promise"); + +const id = process.argv[2]; + +const rlp = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: true, +}); + +const tags = ["p", "strong", "em"]; + +function removeTags(input) { + let copy = input.replace('"', '\\"'); + + for (const tag of tags) + copy = copy.replace(`<${tag}>`, "").replace(``, ""); + + return copy; +} + +// Here is the function to parse the json object. +// It returns object with key/value pair where key is the question and value is the answer +function parseFile(fileObject) { + const allAnswers = {}; + + for (const question of fileObject.data.quiz.info.questions) { + let answer; + + if (question.type === "MCQ") { + if (question.structure.options[question.structure.answer].text == "") { + answer = + question.structure.options[question.structure.answer].media[0].url; + } else { + answer = removeTags( + question.structure.options[question.structure.answer].text + ); + } + } else if (question.type == "MSQ") { + answer = question.structure.answer + .map((answerC) => { + if (question.structure.options[answerC].text == "") { + return question.structure.options[answerC].media[0].url; + } else { + return removeTags(question.structure.options[answerC].text); + } + }) + .filter((a) => a !== undefined); + } else if (question.type == "BLANK") { + answer = question.structure.options.map((o) => removeTags(o.text)); + } + + const questionStr = removeTags(question.structure.query.text); + + allAnswers[questionStr] = answer; + } + + return allAnswers; +} + +function printQuestion(question) { + console.log(chalk.italic(chalk.blue(question[0]))); + console.log(chalk.green(question[1])); +} + +async function repl(o) { + const answer = await rlp.questionAsync(">"); + + if (answer === "all") { + for (const question of o) { + printQuestion(question); + } + } else { + console.log(chalk.underline(answer)); + + for (const question of o) { + let ok = true; + + for (let i = 0; i < question[0].length; i++) { + if (answer[i] === undefined) break; + + if (question[0][i] !== answer[i]) { + ok = false; + break; + } + } + + if (ok) { + printQuestion(question); + } + } + } + + repl(o); +} + +async function main() { + const res = await fetch(`https://quizizz.com/quiz/${id}`); + const jsonObject = await res.json(); + const answers = parseFile(jsonObject); + + const sorted = Object.entries(answers).sort(); + + repl(sorted); +} + +main(); diff --git a/javascript/quizizz-hack/package.json b/javascript/quizizz-hack/package.json new file mode 100644 index 0000000..133e1a7 --- /dev/null +++ b/javascript/quizizz-hack/package.json @@ -0,0 +1 @@ +{"dependencies":{"chalk":"^4.1.0","node-fetch":"^2.6.1","readline-promise":"^1.0.4"}} diff --git a/javascript/quizizz-hack/pnpm-lock.yaml b/javascript/quizizz-hack/pnpm-lock.yaml new file mode 100644 index 0000000..2e81039 --- /dev/null +++ b/javascript/quizizz-hack/pnpm-lock.yaml @@ -0,0 +1,63 @@ +dependencies: + chalk: 4.1.0 + node-fetch: 2.6.1 + readline-promise: 1.0.4 +lockfileVersion: 5.1 +packages: + /ansi-styles/4.3.0: + dependencies: + color-convert: 2.0.1 + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + /chalk/4.1.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + engines: + node: '>=10' + resolution: + integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + /color-convert/2.0.1: + dependencies: + color-name: 1.1.4 + dev: false + engines: + node: '>=7.0.0' + resolution: + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + /color-name/1.1.4: + dev: false + resolution: + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + /has-flag/4.0.0: + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + /node-fetch/2.6.1: + dev: false + engines: + node: 4.x || >=6.0.0 + resolution: + integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + /readline-promise/1.0.4: + dev: false + resolution: + integrity: sha512-b6fycDK7CZWpVXbTl8qnW2jovXPduWKpZGyVZbjK/V4A9iiTU4gur+JEkjjgGKLiDZOftkRCT/dxGLG6hR9HyA== + /supports-color/7.2.0: + dependencies: + has-flag: 4.0.0 + dev: false + engines: + node: '>=8' + resolution: + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== +specifiers: + chalk: ^4.1.0 + node-fetch: ^2.6.1 + readline-promise: ^1.0.4