Auto Refill Canvas Quizzes

Auto refill quizzes in canvas

安装此脚本
作者推荐脚本

您可能也喜欢ZyBooks auto

安装此脚本
  1. // ==UserScript==
  2. // @name Auto Refill Canvas Quizzes
  3. // @namespace http://tampermonkey.net/
  4. // @version v1.0.0
  5. // @description Auto refill quizzes in canvas
  6. // @author AdoreJc
  7. // @match https://*.instructure.com/courses/*/quizzes/*/take
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=instructure.com
  9. // @license MIT
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. async function fetchHighestScoreAttemptLink() {
  17. try {
  18. console.log("Getting attempts from " + window.location.pathname.replace('/take','/submission_versions'));
  19. let response = await fetch(window.location.pathname.replace('/take','/submission_versions'), {
  20. method: 'GET',
  21. headers: {
  22. 'Content-Type': 'application/x-www-form-urlencoded'
  23. }
  24. });
  25.  
  26. if (!response.ok) {
  27. throw new Error('Failed to fetch quiz attempt data');
  28. }
  29. let text = await response.text();
  30. //console.log(text);
  31. let parser = new DOMParser();
  32. let doc = parser.parseFromString(text, 'text/html');
  33.  
  34. let attempts = doc.querySelectorAll('table.ic-Table tbody tr');
  35. if(!attempts){
  36. throw new Error('No attempts found');
  37. }
  38. console.log("Attempts: " + attempts);
  39. let maxScore = -1;
  40. let highestAttemptLink = '';
  41.  
  42. attempts.forEach((attempt) => {
  43. let scoreText = attempt.querySelector('td:nth-child(3)').innerText.trim();
  44. let score = parseInt(scoreText.split(' ')[0]);
  45. console.log("Score: " + score);
  46. if (score > maxScore) {
  47. maxScore = score;
  48. let link = attempt.querySelector('a').getAttribute('href');
  49. highestAttemptLink = link;
  50. }
  51. });
  52.  
  53. if (highestAttemptLink) {
  54. console.log(`Found highest score attempt link: ${highestAttemptLink}`);
  55. return highestAttemptLink;
  56. } else {
  57. throw new Error('No attempt link found');
  58. }
  59.  
  60. } catch (error) {
  61. console.error('Error fetching highest score attempt link:', error);
  62. return null;
  63. }
  64. }
  65.  
  66. async function fetchPreviousQuizAnswers(attemptLink) {
  67. try {
  68. let response = await fetch(attemptLink, {
  69. method: 'Get',
  70. headers: {
  71. 'Content-Type': 'application/x-www-form-urlencoded'
  72. }
  73. });
  74.  
  75. if (!response.ok) {
  76. throw new Error('Failed to fetch previous quiz data');
  77. }
  78.  
  79. let text = await response.text();
  80. let parser = new DOMParser();
  81. let doc = parser.parseFromString(text, 'text/html');
  82.  
  83. let answers = {};
  84. let questions = doc.querySelectorAll('.question_holder');
  85. questions.forEach((question) => {
  86. let questionId = question.querySelector('.question').id;
  87. let selectedAnswer = question.querySelector('input[type="radio"][checked]');
  88. if (selectedAnswer) {
  89. let answerId = selectedAnswer.id.replace('-', '_');
  90. let isIncorrect = question.querySelector('.answer_arrow.incorrect');
  91. answers[questionId] = { answerId, isIncorrect};
  92. }
  93. });
  94.  
  95. console.log('Fetched answers:', answers);
  96. return answers;
  97.  
  98. } catch (error) {
  99. console.error('Error fetching quiz answers:', error);
  100. return {};
  101. }
  102. }
  103.  
  104. async function fillQuizWithAnswers() {
  105. let attemptLink = await fetchHighestScoreAttemptLink();
  106. if (!attemptLink) return;
  107.  
  108. let answers = await fetchPreviousQuizAnswers(attemptLink);
  109.  
  110. Object.keys(answers).forEach((questionId) => {
  111. let correctAnswerId = answers[questionId].answerId;
  112. console.log(`Processing question: ${questionId} with correct answer ID: ${correctAnswerId}`);
  113.  
  114. let questionNode = document.getElementById(questionId);
  115. if (questionNode) {
  116. console.log(`Found question node for ${questionId}`);
  117.  
  118. let correctAnswerInput = questionNode.querySelector(`#${questionId}_${correctAnswerId}`); // question_123_answer_456
  119. if (correctAnswerInput) {
  120. if (answers[questionId].isIncorrect) {
  121. correctAnswerInput.checked = true;
  122. // console.log(`Marked correct answer with checked for ${questionId}_${correctAnswerId}`);
  123. } else {
  124. correctAnswerInput.click();
  125. // console.log(`Selected correct answer ${questionId}_${correctAnswerId}`);
  126. }
  127. } else {
  128. console.log(`Correct answer input not found ${questionId}_${correctAnswerId}`);
  129. }
  130. } else {
  131. console.log(`Question node not found for ${questionId}`);
  132. }
  133. });
  134. }
  135.  
  136. window.addEventListener('load', fillQuizWithAnswers);
  137.  
  138. })();