QRespostas++

This script add the functionality to Qmágico(formally Eduqo) to view answers and to watch vídeo automatitlly.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name QRespostas++
// @namespace https://github.com/sirmonteiro
// @license MIT
// @description This script add the functionality to Qmágico(formally Eduqo) to view answers and to watch vídeo automatitlly.
// @description:pt-BR Esse script adiciona a funcionalidade para o Qmágico(formalmente Eduqo) de ver respostas e assistir vídeos automaticamente.
// @version 0.1.3
// @icon https://i.imgur.com/9IV3lZq.png
// @match https://*.qmagico.com.br/cadernos/caderno/*
// @match https://*.qmagico.com.br/atividades/resolver/*
// @grant unsafeWindow
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// ==/UserScript==

(function (open) {
  let answerLetters = ["A", "B", "C", "D", "E"];
  unsafeWindow.XMLHttpRequest.prototype.open = function () {
    this.addEventListener(
      "readystatechange",
      async function () {
        if (this.readyState == "4" && this.status == 200) {
          let response = JSON.parse(this.response);

          if (this.responseURL.includes("api/get_token_data")) {
            let userID = response.user_id;
            GM.setValue("userID", userID);
          }

          if (
            this.responseURL.includes(
              "rest_api/qplano_rest_api/api/load_caderno"
            )
          ) {
            let cadernoID = response.caderno.id.toString();
            GM.setValue("cadernoID", cadernoID);
          }

          if (this.responseURL.includes("api/get_content")) {
            let exerciselistID = response.id.toString();
            let exerciseKind = response.kind;
            if (exerciseKind == "EXERCISELIST") {
              let exercicesIDs = [];
              response.data.contents.forEach((exercise) => {
                exercicesIDs.push(exercise.id);
              });

              GM.setValue("exercicesIDs", exercicesIDs);
            }
            GM.setValue("exerciselistID", exerciselistID);
            GM.setValue("exerciseKind", exerciseKind);
          }

          if (
            this.responseURL.includes(
              "rest_api/resolver_atividades_rest_api/api/save_state"
            )
          ) {
            if (
              !document.getElementById("scriptbtndiv") &&
              document.getElementsByClassName("exam-card-body")[0]
            ) {
              let exerciseBoxDiv = document.createElement("div");
              exerciseBoxDiv.id = "scriptbtndiv";
              exerciseBoxDiv.style.display = "flex";
              exerciseBoxDiv.style.justifyContent = "center";
              exerciseBoxDiv.style.marginBottom = "16px";
              exerciseBoxDiv.innerHTML = `
                <button class='btn btn-large' id='pausebtn'>Pausar atividade</button>        
              `;
              document
                .getElementsByClassName("exam-card-body")[0]
                .appendChild(exerciseBoxDiv);
              let pausebtn = document.getElementById("pausebtn");
              pausebtn.addEventListener("click", async () => {
                alert(
                  "Atividade pausada, o tempo que você ficou fora da aba não será contado!"
                );
              });
            }
          }

          if (this.responseURL.includes("rest_api/metrics_rest_api/api/save")) {
            if (
              !document.getElementById("scriptbtndiv") &&
              document.getElementsByClassName("emg-exercise-box-padding")[0]
            ) {
              let exerciseBoxDiv = document.createElement("div");
              exerciseBoxDiv.style.display = "inline";
              exerciseBoxDiv.id = "scriptbtndiv";
              exerciseBoxDiv.innerHTML = `
              <button class='btn btn-large' id='answerbtn'>Ver resposta</button>
              `;

              document
                .getElementsByClassName("emg-exercise-box-padding")[0]
                .appendChild(exerciseBoxDiv);
              let answerbtn = document.getElementById("answerbtn");
              answerbtn.addEventListener("click", async () => {
                answerbtn.classList.add("btn-progress");
                answerbtn.classList.add("btn-progress-diagonal");

                let actualExercise = Number(
                  document
                    .getElementsByClassName("box-title")[0]
                    .innerText.split(" ")[1]
                );

                let userID = await GM.getValue("userID");
                let cadernoID = await GM.getValue("cadernoID");
                let exerciselistID = await GM.getValue("exerciselistID");
                let exercicesIDs = await GM.getValue("exercicesIDs");

                let bodyManipulado = `metrics=[{"action":"ContentAccessLog","content_id":"","creation":1000000000000.0,"time_spent_milis":13304,"context":{"page":"VISUALIZAR_CURSO+-+MAIN","course_id":""},"last_update":1000000000000.0,"closed":true},{"action":"ContentAccessLog","user_id":"${userID}","content_id":"${
                  exercicesIDs[actualExercise - 1]
                }","creation":1000000000000,"time_spent_milis":0,"exerciselist":{"id":${exerciselistID},"kind":"EXERCISELIST","metadata":{},"data":{"content_ids":[]}},"context":{"page":"VISUALIZAR_CURSO+-+MAIN","course_id":"${cadernoID}"}}]`;

                await fetch(
                  "https://integradaeducativa.qmagico.com.br/rest_api/metrics_rest_api/api/save",
                  {
                    credentials: "include",
                    headers: {
                      "User-Agent":
                        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0",
                      Accept: "application/json, text/plain, */*",
                      "Accept-Language": "pt-BR,en-US;q=0.7,en;q=0.3",
                      "Content-Type":
                        "application/x-www-form-urlencoded;charset=utf-8",
                      "X-Requested-With": "XMLHttpRequest",
                    },
                    body: bodyManipulado,
                    method: "POST",
                    mode: "cors",
                  }
                )
                  .then(async (res) => {
                    let data = await res.json();
                    if (res.ok) {
                      // let exercise = (data[0].log.question_index) + 1
                      // let alternative = answerLetters[data[0].content.data.answers.correct_answer]
                      let correctAnswerIndex =
                        data[0].content.data.answers.correct_answer;
                      let answerdiv = document.createElement("div");
                      if (
                        !data[0].content.data.answers.correct_answer.toString()
                      ) {
                        let answerComment =
                          data[0].content.data.answers.comment;
                        if (!answerComment) {
                          answerComment =
                            "<h3>Infelizmente o professor não colocou comentário da resposta :(</h3>";
                        }
                        answerdiv.innerHTML = `
                  <div class="divisor-line divisor-line-darker" />
                  <div class='emg-exercise-gabarito'>
                    <div class='emg-exercise-gabarito-comentario p-margin-2'>
                      <strong class='emg-exercise-gabarito-comentario-title'>Comentário da resposta</strong>
                      <span style='font-size: 12pt'>
                      ${answerComment}
                      </span>
                    </div>
                  </div>
                  `;
                      } else {
                        answerdiv.innerHTML = `
                  <div class="divisor-line divisor-line-emboss" />
                  <div class='emg-exercise-gabarito'>
                    <p class='emg-exercise-gabarito-label'>
                      <strong>
                        Resposta correta:
                        <span class="badge badge-circle badge-small badge-success">
                        ${answerLetters[correctAnswerIndex]}
                        </span>
                      </strong>
                    </p>
                  </div>
                  `;
                        document
                          .getElementsByClassName(
                            "emg-exercise-multiple-choice-answer-item"
                          )
                          [correctAnswerIndex].click();
                      }
                      document
                        .getElementsByClassName("emg-exercise-footer")[0]
                        .appendChild(answerdiv);
                      answerbtn.classList.remove("btn-progress");
                      answerbtn.classList.remove("btn-progress-diagonal");
                      answerbtn.disabled = "disabled";
                      GM.deleteValue(exerciselistID);
                      GM.deleteValue(exercicesIDs);
                      // alert(exercise + ':' + alternative)
                    } else {
                      console.log("erro", res.status);
                    }
                  })
                  .catch((err) => {
                    throw err;
                  });
              });
            }
          }

          if (
            this.responseURL.includes(
              "rest_api/listing_rest_api/home/list_my_interactions"
            )
          ) {
            if (
              (await GM.getValue("exerciseKind", false)) == "VIDEO" &&
              !document.getElementById("scriptbtndiv")
            ) {
              let scriptbtndiv = document.createElement("div");
              scriptbtndiv.id = "scriptbtndiv";
              scriptbtndiv.innerHTML = `
              <button class='btn btn-large' id='videobtn'>Assistir Vídeo</button>
              `;
              document
                .getElementsByClassName("qm-content-toolbar-actions-wrapper")[0]
                .insertAdjacentElement("afterbegin", scriptbtndiv);

              let videobtn = document.getElementById("videobtn");
              videobtn.addEventListener("click", async () => {
                videobtn.classList.add("btn-progress");
                videobtn.classList.add("btn-progress-diagonal");

                let userID = await GM.getValue("userID");
                let cadernoID = await GM.getValue("cadernoID");
                let videoID = await GM.getValue("exerciselistID");

                let videoBody = `metrics=[{"action":"ContentInteraction","kind":"VIDEO","user_id":"${userID}","content_id":"${videoID}","creation":1000000000000,"last_update":1000000000000,"accesses":0,"context":{"page":"VISUALIZAR_CURSO+-+MAIN","course_id":"${cadernoID}"},"key":"","stop":20000}]`;

                await fetch(
                  "https://integradaeducativa.qmagico.com.br/rest_api/metrics_rest_api/api/save",
                  {
                    credentials: "include",
                    headers: {
                      "User-Agent":
                        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0",
                      Accept: "application/json, text/plain, */*",
                      "Accept-Language": "pt-BR,en-US;q=0.7,en;q=0.3",
                      "Content-Type":
                        "application/x-www-form-urlencoded;charset=utf-8",
                      "X-Requested-With": "XMLHttpRequest",
                    },
                    body: videoBody,
                    method: "POST",
                    mode: "cors",
                  }
                )
                  .then((res) => {
                    if (res.ok && res.status == 200) {
                      videobtn.classList.remove("btn-progress");
                      videobtn.classList.remove("btn-progress-diagonal");
                      videobtn.disabled = "disabled";
                      GM.deleteValue(videoID);
                      location.reload();
                    } else {
                      console.log("erro", res.status);
                    }
                  })
                  .catch((err) => {
                    throw err;
                  });
              });
            }
          }
        }
      },
      false
    );
    open.apply(this, arguments);
  };
})(unsafeWindow.XMLHttpRequest.prototype.open);