Auto Mooc (Script Only)

欢迎使用Auto Mooc的内置脚本, 如需服务端运行请访问Github - skye-z/auto-mooc

目前为 2024-03-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Auto Mooc (Script Only)
  3. // @namespace Violentmonkey Scripts
  4. // @description 欢迎使用Auto Mooc的内置脚本, 如需服务端运行请访问Github - skye-z/auto-mooc
  5. // @match http://www.uooc.net.cn/home/learn/index*
  6. // @match https://www.uooc.net.cn/home/learn/index*
  7. // @match http://www.uooconline.com/home/learn/index*
  8. // @match https://www.uooconline.com/home/learn/index*
  9. // @match http://cce.org.uooconline.com/home/learn/index*
  10. // @match https://cce.org.uooconline.com/home/learn/index*
  11. // @grant none
  12. // @license GPL v3.0
  13. // @version 2.0.0
  14. // @author Skye
  15. // @description 2024/03/13 21:00:29
  16. // ==/UserScript==
  17.  
  18. (function () {
  19. 'use strict';
  20. const GT = 500;
  21. let runWork = () => {
  22. let extraTime = 0;
  23. try {
  24. let done = false;
  25. let video = document.querySelector('#player_html5_api');
  26. if (video) {
  27. video.playbackRate = 2;
  28. video.muted = true;
  29. if (!video.ended) video.play();
  30. else video.pause();
  31. if (video.ended) done = true;
  32. let quizLayer = document.querySelector('#quizLayer');
  33. if (quizLayer && quizLayer.style.display != 'none') {
  34. if (done) {
  35. setTimeout(() => {
  36. document.querySelectorAll('.layui-layer-shade').forEach(e => e.style.display = 'none');
  37. }, GT << 1);
  38. };
  39. let source = JSON.parse(document.querySelector('div[uooc-video]').getAttribute('source'));
  40. let quizList = source.quiz;
  41. let quizIndex = 0;
  42. let quizQuestion = document.querySelector('.smallTest-view .ti-q-c').innerHTML;
  43. for (let i = 0; i < quizList.length; i++) {
  44. if (quizList[i].question == quizQuestion) {
  45. quizIndex = i;
  46. break;
  47. };
  48. };
  49. let quizAnswer = eval(quizList[quizIndex].answer);
  50. let quizOptions = quizLayer.querySelector('div.ti-alist');
  51. for (let ans of quizAnswer) {
  52. let labelIndex = ans.charCodeAt() - 'A'.charCodeAt();
  53. quizOptions.children[labelIndex].click();
  54. };
  55. quizLayer.querySelector('button').click();
  56. extraTime = 1000;
  57. };
  58. if (!done) {
  59. if (video.paused) video.play();
  60. else document.querySelectorAll('.layui-layer-shade, #quizLayer').forEach(e => e.style.display = 'none');
  61. };
  62. };
  63. if (!done) setTimeout(runWork, GT + extraTime);
  64. else if (video) {
  65. let current_video = document.querySelector('.basic.active');
  66. let next_part = current_video.parentNode;
  67. let next_video = current_video;
  68. let isVideo = node => Boolean(node.querySelector('span.icon-video'));
  69. let canBack = () => {
  70. return Boolean(next_part.parentNode.parentNode.tagName === 'LI');
  71. };
  72. let toNextVideo = () => {
  73. next_video = next_video.nextElementSibling;
  74. while (next_video && !isVideo(next_video)) {
  75. next_video = next_video.nextElementSibling;
  76. };
  77. };
  78. let isExistsVideo = () => {
  79. let _video = next_part.firstElementChild;
  80. while (_video && !isVideo(_video)) {
  81. _video = _video.nextElementSibling;
  82. };
  83. return Boolean(_video && isVideo(_video));
  84. };
  85. let isExistsNextVideo = () => {
  86. let _video = current_video.nextElementSibling;
  87. while (_video && !isVideo(_video)) {
  88. _video = _video.nextElementSibling;
  89. };
  90. return Boolean(_video && isVideo(_video));
  91. };
  92. let isExistsNextListAfterFile = () => {
  93. let part = next_part.nextElementSibling;
  94. return Boolean(part && part.childElementCount > 0);
  95. };
  96. let toNextListAfterFile = () => {
  97. next_part = next_part.nextElementSibling;
  98. };
  99. let toOuterList = () => {
  100. next_part = next_part.parentNode.parentNode;
  101. };
  102. let toOuterItem = () => {
  103. next_part = next_part.parentNode;
  104. };
  105. let isExistsNextListAfterList = () => {
  106. return Boolean(next_part.nextElementSibling);
  107. };
  108. let toNextListAfterList = () => {
  109. next_part = next_part.nextElementSibling;
  110. };
  111. let expandList = () => {
  112. next_part.firstElementChild.click();
  113. };
  114. let toExpandListFirstElement = () => {
  115. next_part = next_part.firstElementChild.nextElementSibling;
  116. if (next_part.classList.contains('unfoldInfo')) {
  117. next_part = next_part.nextElementSibling;
  118. };
  119. };
  120. let isList = () => {
  121. return Boolean(next_part.tagName === 'UL');
  122. };
  123. let toInnerList = () => {
  124. next_part = next_part.firstElementChild;
  125. };
  126. let toFirstVideo = () => {
  127. next_video = next_part.firstElementChild;
  128. while (next_video && !isVideo(next_video)) {
  129. next_video = next_video.nextElementSibling;
  130. };
  131. };
  132. let mode = {
  133. FIRST_VIDEO: '1',
  134. NEXT_VIDEO: '2',
  135. LAST_LIST: '3',
  136. NEXT_LIST: '4',
  137. INNER_LIST: '5',
  138. OUTER_LIST: '6',
  139. OUTER_ITEM: '7',
  140. }
  141. let search = (_mode) => {
  142. switch (_mode) {
  143. case mode.FIRST_VIDEO:
  144. if (isExistsVideo()) {
  145. toFirstVideo();
  146. next_video.click();
  147. setTimeout(runWork, GT);
  148. } else if (isExistsNextListAfterFile()) search(mode.LAST_LIST);
  149. break;
  150. case mode.NEXT_VIDEO:
  151. if (isExistsNextVideo()) {
  152. toNextVideo();
  153. next_video.click();
  154. setTimeout(runWork, GT);
  155. } else if (isExistsNextListAfterFile()) search(mode.LAST_LIST);
  156. else search(mode.OUTER_ITEM);
  157. break;
  158. case mode.LAST_LIST:
  159. toNextListAfterFile();
  160. toInnerList();
  161. search(mode.INNER_LIST);
  162. break;
  163. case mode.NEXT_LIST:
  164. toNextListAfterList();
  165. search(mode.INNER_LIST);
  166. break;
  167. case mode.INNER_LIST:
  168. expandList();
  169. (function waitForExpand() {
  170. if (next_part.firstElementChild.nextElementSibling) {
  171. toExpandListFirstElement();
  172. if (isList()) {
  173. toInnerList();
  174. search(mode.INNER_LIST);
  175. } else search(mode.FIRST_VIDEO);
  176. } else setTimeout(waitForExpand, GT);
  177. })();
  178. break;
  179. case mode.OUTER_LIST:
  180. toOuterList();
  181. if (isExistsNextListAfterList()) search(mode.NEXT_LIST);
  182. else if (canBack()) search(mode.OUTER_LIST);
  183. break;
  184. case mode.OUTER_ITEM:
  185. toOuterItem();
  186. if (isExistsNextListAfterList()) {
  187. toNextListAfterList();
  188. search(mode.INNER_LIST);
  189. } else if (canBack()) search(mode.OUTER_LIST);
  190. break;
  191. default:
  192. break;
  193. };
  194. };
  195. try {
  196. search(mode.NEXT_VIDEO);
  197. } catch (err) {
  198. console.error(err);
  199. };
  200. };
  201. } catch (err) {
  202. console.error(err);
  203. };
  204. };
  205. runWork();
  206. console.info('Auto Mooc Init');
  207. })();
  208.  
  209. function openClass(top, dom) {
  210. if (dom == null) {
  211. let res = top.parentNode.querySelector('.resourcelist');
  212. if (res == null) return
  213. res = res.firstElementChild
  214. if (res == null) return
  215. res.click()
  216. } else {
  217. let obj = dom.querySelector('.basic.uncomplete');
  218. let part = obj.parentNode;
  219. let sub = part.querySelector('ul');
  220. if (sub == null) {
  221. obj.click();
  222. setTimeout(() => {
  223. sub = part.querySelector('ul');
  224. openClass(part, sub)
  225. }, 1000)
  226. } else {
  227. openClass(part, sub)
  228. }
  229. }
  230. }
  231.  
  232. function selectClass() {
  233. openClass(null, document)
  234. }