AtutorSolver

Helps to solve tests with ChatGPT

当前为 2023-09-07 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name AtutorSolver
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Helps to solve tests with ChatGPT
  6. // @author Propsi4
  7. // @include https://dl.tntu.edu.ua/mods/_standard/tests/take_test.php?*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=dl.tntu.edu.ua
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12.  
  13. const API_KEY = ""
  14. const url = " https://api.openai.com/v1/chat/completions"
  15. const xhr = new XMLHttpRequest();
  16. let hide = false
  17.  
  18. const api_fetch = (data) => {
  19. xhr.open("POST", url, true);
  20. xhr.setRequestHeader("Content-Type", "application/json");
  21. xhr.setRequestHeader("Authorization", `Bearer ${API_KEY}`);
  22. const prompt = data.question_div.children[2].value
  23. xhr.onreadystatechange = function () {
  24. if (xhr.readyState === 4 && xhr.status === 200) {
  25. try{
  26. const response = JSON.parse(xhr.responseText);
  27. const reply = response.choices[0].message.content
  28. const reply_div = document.createElement("div")
  29. reply_div.innerHTML = reply
  30. data.question_div.appendChild(reply_div)
  31. } catch (error) {
  32. console.error(error)
  33. }
  34. }
  35. else if(xhr.readyState === 4 && xhr.status === 429){
  36. alert("Ви зробили забагато запитів до нейронної мережі, спробуйте ще раз через 1 хвилину. Ліміт запитів 3 запита/хв")
  37. }
  38. }
  39. console.log(prompt)
  40. const payload = {
  41. messages: [
  42. {
  43. "role": "user",
  44. "content": prompt
  45. },
  46. ],
  47. model: "gpt-3.5-turbo",
  48. max_tokens: 50 // Adjust the parameters as needed
  49. };
  50. xhr.send(JSON.stringify(payload));
  51. }
  52. (function() {
  53. 'use strict';
  54.  
  55. // Your code here...
  56. const row_divs = document.getElementsByClassName("row")
  57. const page_wrap = document.getElementsByClassName("page-wrap")[0]
  58. const hide_button = document.createElement("button")
  59. hide_button.innerText = "X"
  60. hide_button.style.position = "fixed"
  61. hide_button.style.top = "0"
  62. hide_button.style.right = "0"
  63. hide_button.style.zIndex = "1000"
  64. hide_button.onclick = () => {
  65. hide = !hide
  66. if(hide){
  67. question_divs.forEach(question_div => {
  68. // hide children >= 2
  69. Array.from(question_div.children).forEach((child, index) => {
  70. if(index >= 2){
  71. child.style.display = "none"
  72. }
  73. })
  74. })
  75. }else{
  76. question_divs.forEach(question_div => {
  77. // hide children >= 2
  78. Array.from(question_div.children).forEach((child, index) => {
  79. if(index >= 2){
  80. child.style.display = "block"
  81. }
  82. })
  83. })
  84. }
  85. }
  86. page_wrap.appendChild(hide_button)
  87. // get only divs with children p and ul.multichoice-question
  88. // do not use children[0] and children[1] because it is not reliable
  89. // may contain input, dont skip it
  90. const question_divs = Array.from(row_divs).filter(row_div => {
  91. const children = Array.from(row_div.children)
  92. const has_p = children.some(child => child.tagName === "P")
  93. const has_ul = children.some(child => child.tagName === "UL" && (child.classList.contains("multichoice-question") || child.classList.contains("multianswer-question")))
  94. // yes if div has input tag
  95. // is multichoice-question or multianswer-question, must be string
  96. return has_p && has_ul
  97. })
  98. const question_data = question_divs.map(question_div => {
  99. const question_text = question_div.children[0].innerText
  100. // if question ul class is multichoice-question, then it is multichoice question
  101. // get ul tag
  102. const type = Array.from(question_div.children).find(child => child.tagName === "UL").classList[0]
  103. // ignore last answer, because it is "I don't know"
  104. if(type == "multichoice-question"){
  105. const answers = Array.from(question_div.children[1].children).slice(0, -1).map(answer_div => {
  106. // try to get answer input, if error then skip
  107. try{
  108. const answer_input = answer_div.children[0]
  109. const answer_text = answer_div.children[1].innerText
  110. return {
  111. answer_text,
  112. answer_input
  113. }
  114. } catch (error) {
  115. return null
  116. }})
  117. return {
  118. question_div,
  119. question_text,
  120. type,
  121. answers
  122. }
  123. }else{
  124. const answers = Array.from(question_div.children[2].children).map(answer_div => {
  125. // try to get answer input, if error then skip
  126. try{
  127. const answer_input = answer_div.children[0]
  128. const answer_text = answer_div.children[1].innerText
  129. return {
  130. answer_text,
  131. question_div,
  132. answer_input
  133. }
  134. } catch (error) {
  135. return null
  136. }})
  137. return {
  138. question_div,
  139. question_text,
  140. type,
  141. answers
  142. }
  143. }})
  144.  
  145. // add a button to every question_div
  146. question_divs.forEach((question_div, question_index) => {
  147. const button = document.createElement("button")
  148. const textarea = document.createElement("textarea")
  149. const {question_text, type, answers} = question_data[question_index]
  150.  
  151. let prompt = `Кількість правильних відповідей: ${type == "multichoice-question" ? "Одна правильна відповідь" : "Декілька правильних відповідей"}
  152. Приклад твоєї відповіді: "ТЕКСТ ВАРІАНТУ ВІДПОВІДІ", де "ТЕКСТ ВАРІАНТУ ВІДПОВІДІ" - це текст, який знаходиться біля кожного з варіанту відповіді на це запитання, вказані нижче, якщо такого варіанту немає, то напиши свій варіант відповіді, якщо їх декілька, то перелічи їх через кому. Відповідь повинна бути надана тільки в такому виді, і ніяк інакше.
  153. Запитання: ${question_text}\n${answers.map((answer, index) =>
  154. `Відповідь ${index + 1}: ${answer.answer_text}`).join("\n")}`
  155.  
  156. textarea.style.width = "100%"
  157. textarea.style.height = "100px"
  158. textarea.style.resize = "none"
  159. textarea.value = prompt
  160. textarea.placeholder = "ChatGPT Prompt"
  161.  
  162. button.innerText = "Розв'язати"
  163. button.onclick = (e) => {
  164. e.preventDefault();
  165. api_fetch(question_data[question_index])
  166. }
  167.  
  168. question_div.appendChild(textarea)
  169. question_div.appendChild(button)
  170. })
  171. })();