BUPT GPA

Calculate GPA in URP system

当前为 2019-03-20 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name BUPT GPA
  3. // @namespace https://ssine.cc/
  4. // @version 2.0
  5. // @description Calculate GPA in URP system
  6. // @author Liu Siyao
  7. // @include *://jwxt.bupt.edu.cn/jwLoginAction.do
  8. // @include *://vpn.bupt.edu.cn/http/jwxt.bupt.edu.cn/jwLoginAction.do
  9. // @grant none
  10. // @require https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js
  11. // @require https://cdn.jsdelivr.net/npm/vue
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. window.parent.frames[1].onload = ()=>{
  17. $.get('/gradeLnAllAction.do?type=ln&oper=qbinfo').then(
  18. (res)=>{
  19.  
  20. var algoNames = ['北邮官方', '标准4.0', '改进4.0', '北大4.0', '加拿大4.3', '中科大4.3', '上海交大4.3'];
  21. var algoArea = [
  22. [59, 60, 60.5, 61, 61.5, 62, 62.5, 63, 63.5, 64, 64.5, 65, 65.5, 66, 66.5, 67, 67.5, 68, 68.5, 69, 69.5, 70, 70.5, 71, 71.5, 72, 72.5, 73, 73.5, 74, 74.5, 75, 75.5, 76, 76.5, 77, 77.5, 78, 78.5, 79, 79.5, 80, 80.5, 81, 81.5, 82, 82.5, 83, 83.5, 84, 84.5, 85, 85.5, 86, 86.5, 87, 87.5, 88, 88.5, 89, 89.5, 90, 90.5, 91, 91.5, 92, 92.5, 93, 93.5, 94, 94.5, 95, 95.5, 96, 96.5, 97, 97.5, 98, 98.5, 99, 99.5, 100],
  23. [59, 69, 79, 89, 100],
  24. [59, 69, 84, 100],
  25. [59, 63, 67, 71, 74, 77, 81, 84, 89, 100],
  26. [59, 64, 69, 74, 79, 84, 89, 100],
  27. [59, 60, 63, 64, 67, 71, 74, 77, 81, 84, 89, 94, 100],
  28. [59, 61, 64, 66, 69, 74, 79, 84, 89, 94, 100]
  29. ];
  30. var algoGp = [
  31. [0, 1.00, 1.07, 1.15, 1.22, 1.29, 1.36, 1.43, 1.50, 1.57, 1.64, 1.70, 1.77, 1.83, 1.90, 1.96, 2.02, 2.08, 2.14, 2.20, 2.26, 2.31, 2.37, 2.42, 2.48, 2.53, 2.58, 2.63, 2.68, 2.73, 2.78, 2.83, 2.87, 2.92, 2.96, 3.01, 3.05, 3.09, 3.13, 3.17, 3.21, 3.25, 3.29, 3.32, 3.36, 3.39, 3.43, 3.46, 3.49, 3.52, 3.55, 3.58, 3.61, 3.63, 3.66, 3.68, 3.71, 3.73, 3.75, 3.77, 3.79, 3.81, 3.83, 3.85, 3.86, 3.88, 3.89, 3.91, 3.92, 3.93, 3.94, 3.95, 3.96, 3.97, 3.98, 3.98, 3.99, 3.99, 4.00, 4.00, 4.00, 4.00],
  32. [0, 1, 2, 3, 4],
  33. [0, 2, 3, 4],
  34. [0, 1, 1.5, 2, 2.3, 2.7, 3, 3.3, 3.7, 4],
  35. [0, 2.3, 2.7, 3, 3.3, 3.7, 4, 4.3],
  36. [0, 1, 1.3, 1.5, 1.7, 2, 2.3, 2.7, 3, 3.3, 3.7, 4, 4.3],
  37. [0, 1, 1.7, 2, 2.3, 2.7, 3, 3.3, 3.7, 4, 4.3]
  38. ];
  39. function getGP(score, i) {
  40. var area = algoArea[i];
  41. var gp = algoGp[i];
  42. for (var idx in area) {
  43. if(score <= area[idx])
  44. return gp[idx];
  45. }
  46. return score;
  47. };
  48.  
  49. class course {
  50. constructor(no, name, semester, type, credit, grade) {
  51. this.no = no;
  52. this.name = name;
  53. this.semester = semester;
  54. this.type = type;
  55. this.credit = credit;
  56. this.grade = grade;
  57. }
  58. }
  59.  
  60. var calc_mat = [];
  61. var course_lst = [];
  62. var semesters = [];
  63. var course_types = ['必修', '选修', '任选'];
  64. var semester_name = '';
  65.  
  66. function showResult() {
  67. // console.log(course_lst);
  68. var sum = 0, total_credit = 0;
  69. var gpLst = [0, 0, 0, 0, 0, 0];
  70. for (var idx = 0; idx < course_lst.length; idx++) {
  71. var course = course_lst[idx];
  72. if (!calc_mat[semesters.indexOf(course.semester)][course_types.indexOf(course.type)])
  73. continue;
  74. total_credit += course.credit;
  75. sum += course.credit * course.grade;
  76. for (var j in gpLst) {
  77. gpLst[j] += course.credit * getGP(course.grade, j);
  78. }
  79. };
  80.  
  81.  
  82. $('#gpa-res').empty();
  83. $('#gpa-res').append($('<table>\
  84. <tr><th>算法</th><th>GPA</th></tr>\
  85. </table>'));
  86.  
  87. for (var idx in gpLst) {
  88. var newTr = "<tr><td>" + algoNames[idx] + "</td><td>" + (gpLst[idx]/total_credit).toFixed(2) + "</td></tr>";
  89. $('#gpa-res table').append($(newTr));
  90. }
  91. var contentStr = "特殊加权学分绩: " + (sum / total_credit).toFixed(2);
  92. contentStr += "<br>已修读学分: " + total_credit.toString();
  93. $('#gpa-res').append($('<p>' + contentStr + '</p>'));
  94. }
  95.  
  96. function appendResult(lst, name) {
  97. var sum = 0, total = 0;
  98. var gpLst = [0, 0, 0, 0, 0, 0];
  99.  
  100. for (var idx = 0; idx < lst.length; idx++) {
  101. var items = lst[idx].getElementsByTagName('td');
  102. if (isNaN(parseFloat(items[6].innerText)))
  103. continue;
  104. total += parseFloat(items[4].innerText);
  105. sum += parseFloat(items[4].innerText) * parseFloat(items[6].innerText);
  106. for (var j in gpLst) {
  107. gpLst[j] += parseFloat(items[4].innerText) * getGP(parseFloat(items[6].innerText), j);
  108. }
  109. };
  110.  
  111. var frame = window.parent.frames[1].document.getElementsByName('mainFrame')[0];
  112. frame = frame.contentDocument || frame.contentWindow.document;
  113. var injectEntry = $(frame).find('.hometopbg1:first');
  114. var contentStr = "特殊加权学分绩: " + (sum / total).toFixed(2);
  115. contentStr += "\\n已修读学分: " + total.toString();
  116. for (var idx in gpLst) {
  117. contentStr += "\\nGPA(" + algoNames[idx] + "): " + (gpLst[idx]/total).toFixed(2);
  118. }
  119. var newtr = $('<tr><td height="25"><a href="javascript:alert(\'' + contentStr +
  120. '\');">查看GPA(' + name + ')</a></td></tr>');
  121. injectEntry.append(newtr);
  122. }
  123.  
  124. $.get('/gradeLnAllAction.do?type=ln&oper=sxinfo&lnsxdm=001').then( (res)=>{
  125. var doc = new DOMParser().parseFromString(res, "text/html");
  126. appendResult(doc.querySelectorAll('a[name=qb_001] .odd'), "必修");
  127. appendResult(doc.querySelectorAll('a[name=qb_001] .odd, a[name=qb_02] .odd'), "必修+选修");
  128. appendResult(doc.querySelectorAll('.odd'), "必修+选修+任选");
  129. });
  130.  
  131. var parser = new DOMParser();
  132. var doc = parser.parseFromString(res, "text/html");
  133.  
  134. var body_lst = doc.getElementsByTagName('body')[0].childNodes;
  135.  
  136.  
  137.  
  138. for(var i = 0; i < body_lst.length; i++) {
  139. if (body_lst[i].tagName == 'A') {
  140. semester_name = body_lst[i].name;
  141. if (semesters.indexOf(semester_name) == -1) {
  142. semesters.push(semester_name);
  143. }
  144. } else if (body_lst[i].className == 'titleTop2') {
  145. var entry = $(body_lst[i]).find('.odd');
  146. for (var j = 0; j < entry.length; j++) {
  147. var lst = entry[j].getElementsByTagName('td');
  148. var grade = parseFloat(entry[j].getElementsByTagName('p')[0].innerText);
  149. if (isNaN(grade)) continue;
  150. course_lst.push(new course(
  151. lst[0].innerText.trim(),
  152. lst[2].innerText.trim(),
  153. semester_name,
  154. lst[5].innerText.trim(),
  155. parseFloat(lst[4].innerText),
  156. grade
  157. ));
  158. }
  159. }
  160. }
  161.  
  162. for (var i = 0; i < semesters.length; i++)
  163. calc_mat.push([true, true, false]);
  164.  
  165.  
  166. var gpa_div = $('<div id="gpa">\
  167. <div id="gpa-side">\
  168. <div id="gpa-modify">\
  169. <h2>课程属性:</h2>\
  170. <table>\
  171. <tr>\
  172. <th>课程名</th>\
  173. <th>类型</th>\
  174. <th>成绩</th>\
  175. <th>学分</th>\
  176. </tr>\
  177. <tr v-for="c in courses">\
  178. <td>{{c.name}}</td>\
  179. <td>\
  180. <select v-model="c.type">\
  181. <option>必修</option>\
  182. <option>选修</option>\
  183. <option>任选</option>\
  184. </select>\
  185. </td>\
  186. <td>{{c.grade}}</td>\
  187. <td>{{c.credit}}</td>\
  188. </tr>\
  189. </table></div>\
  190. </div>\
  191. \
  192. \
  193. <div id="gpa-main-frame">\
  194. <div id="calc-app">\
  195. <h2>要计算的课程:</h2>\
  196. <table>\
  197. <tr>\
  198. <th>学期</th>\
  199. <th>必修</th>\
  200. <th>选修</th>\
  201. <th>任选</th>\
  202. </tr>\
  203. <tr v-for="(r, idx) in mat">\
  204. <td>{{ semesters[idx] }}</td>\
  205. <td><input type="checkbox" id="checkbox" v-model="r[0]"></td>\
  206. <td><input type="checkbox" id="checkbox" v-model="r[1]"></td>\
  207. <td><input type="checkbox" id="checkbox" v-model="r[2]"></td>\
  208. </tr>\
  209. </table></div>\
  210. \
  211. \
  212. <h2>结果:</h2>\
  213. <div id="gpa-res">\
  214. </div>\
  215. <hr>\
  216. <p>程序完全基于前端,不会存储个人信息。</p>\
  217. <p>觉得好用来<a target="_blank" href="https://github.com/ssine/BUPT-GPA">仓库</a>点个star好不好ヽ(✿゚▽゚)ノ</p>\
  218. <p>欢迎把<a target="_blank" href="https://greasyfork.org/zh-CN/scripts/369550-bupt-gpa">这个脚本</a>分享给你的朋友哦(*/ω\*)</p>\
  219. </div>\
  220. </div>');
  221.  
  222. var sheet_css = $('<style>\
  223. #gpa {\
  224. position: absolute;\
  225. right: 70px;\
  226. bottom: 20px;\
  227. height: 80%;\
  228. background-color: rgba(255,255,255,0.9);\
  229. }\
  230. #gpa-side {\
  231. float: left;\
  232. margin-right: 20px;\
  233. height: 100%;\
  234. overflow: auto;\
  235. }\
  236. #gpa-main-frame {\
  237. float: left;\
  238. height: 100%;\
  239. overflow: auto;\
  240. }\
  241. #gpa-modify table tr td:first-child, #gpa-modify table tr th:first-child {\
  242. width: 200px;\
  243. }\
  244. #calc-app {\
  245. }\
  246. #res-app {\
  247. margin-top: 50px;\
  248. }\
  249. #gpa-btn {\
  250. position: absolute;\
  251. right: 20px;\
  252. bottom: 20px;\
  253. background-color: RGB(119,119,119);\
  254. color: rgb(255,255,255);\
  255. height: 50px;\
  256. width: 50px;\
  257. border-radius: 50px;\
  258. font-family: sans-serif;\
  259. }\
  260. </style>');
  261. $('head').append(sheet_css);
  262.  
  263. gpa_div.hide();
  264. $('html').append(gpa_div);
  265.  
  266. var btn = $('<button id="gpa-btn">GPA</button>');
  267. btn.click(() => {
  268. var app = $('#gpa');
  269. if (app.css('display') == 'none')
  270. app.css('display', '');
  271. else
  272. app.css('display', 'none');
  273. });
  274. $('html').append(btn);
  275.  
  276. showResult();
  277.  
  278. var gpa_modify = new Vue({
  279. el: '#gpa-modify',
  280. data: {
  281. courses: course_lst
  282. },
  283. watch: {
  284. courses: {
  285. handler(newValue, oldValue) {
  286. showResult();
  287. },
  288. deep: true
  289. }
  290. }
  291. });
  292. var calc_app = new Vue({
  293. el: '#calc-app',
  294. data: {
  295. mat: calc_mat,
  296. semesters: semesters
  297. },
  298. watch: {
  299. mat: showResult
  300. }
  301. });
  302.  
  303. }
  304. )
  305. }
  306. })();