classroom tsinghua

Exchange classroom infomation in Tsinghua University

  1. // ==UserScript==
  2. // @name classroom tsinghua
  3. // @namespace wutj.info
  4. // @description Exchange classroom infomation in Tsinghua University
  5. // @include http://portal.tsinghua.edu.cn/*render.userLayoutRootNode.uP*
  6. // @include http://info.tsinghua.edu.cn/*render.userLayoutRootNode.uP*
  7. // @version 1.4
  8. // @grant GM_xmlhttpRequest
  9. // ==/UserScript==
  10.  
  11. ////////////////////////////////////////////////////////////
  12. //
  13. // 欢迎你阅读和使用这些代码.
  14. // 这是一个只在清华校内使用的插件,意义在于方便大家共享信息
  15. // 因此,我们相信清华的同学不会故意攻击、修改、获取数据。
  16. //
  17. ////////////////////////////////////////////////////////////
  18.  
  19. var uid = '';
  20. var myclass = '';
  21. var baseurl = 'http://infobot.innovation-china.org/courseinfo/';
  22. var hwnd_Move;
  23. var fail_one = 0;
  24.  
  25. String.prototype.indexOfR = function(needle, start) {
  26. var p = this.indexOf(needle, start);
  27. return (p<0)?p:p+needle.length;
  28. };
  29.  
  30. function main()
  31. {
  32. var uid = document.getElementsByClassName('uportal-navi-user');
  33. if (uid.length) {
  34. uid = uid[3].innerHTML;
  35. if (uid != parseInt(uid)) return;
  36. } else {
  37. uid = document.getElementsByClassName('hot_nav_cont');
  38. if (!uid.length) return;
  39. var txt = uid[0].innerHTML;
  40. var p = txt.indexOfR('证件号:');
  41. var p1 = txt.indexOf('</span>', p);
  42. uid = txt.substr(p, p1-p);
  43. if (uid != parseInt(uid)) return;
  44. }
  45.  
  46. var get_head_body = function() {
  47. var a = document.getElementsByTagName('head');
  48. return a.length < 1 ? document.body : a[0];
  49. };
  50.  
  51. var add_script_head = function(src){
  52. var s = document.createElement("script");
  53. s.type = "text/javascript";
  54. s.src = src;
  55. get_head_body().appendChild(s);
  56. };
  57. var parsestudylist = function(res) {
  58. var txt = res.responseText;
  59. var p = 0, p1 = 0;
  60. var myclass_obj = [];
  61. while(1) {
  62. var prof, course, room, t;
  63. p = txt.indexOfR('strHTML1 = "";', p);
  64. if (p < 0) break;
  65. p = txt.indexOfR('strHTML1 += "', p);
  66. p1 = txt.indexOf('";', p);
  67. prof = txt.substr(p+1, p1-p-1);
  68. p = txt.indexOfR('strHTML1 += "', p1);
  69. p = txt.indexOfR('strHTML1 += "', p);
  70. p = txt.indexOfR('strHTML1 +="', p);
  71. p1 = txt.indexOf('"', p);
  72. room = txt.substr(p+1, p1-p-1);
  73. p = txt.indexOfR('onmouseout=\\"return nd();\\">', p1);
  74. p1 = txt.indexOf('</span>', p);
  75. course = txt.substr(p, p1-p);
  76. p = txt.indexOfR('getElementById(\'a', p);
  77. p1 = txt.indexOf('\')', p);
  78. t = txt.substr(p, p1-p);
  79. t = t.substr(2,1) + "-" + t.substr(0,1);
  80. myclass_obj.push({'prof':prof, 'course':course, 'room':room, 'schedule': t});
  81. }
  82. if (myclass_obj.length) {
  83. myclass = JSON.stringify(myclass_obj);
  84. GM_xmlhttpRequest({
  85. method: "GET",
  86. url: baseurl+"status.php?uid=" + uid,
  87. onload: getusercontrib
  88. });
  89. } else if (fail_one){
  90. var htm = '无法获得您当前的课表信息<br/>如果没有选课,则不能使用';
  91. document.getElementById('course_info_win_cont').innerHTML = htm;
  92. } else {
  93. fail_one = 1;
  94. }
  95. },
  96. getusercontrib = function(res) {
  97. var obj = JSON.parse(res.responseText);
  98. if (obj.r) {
  99. var htm = '<strong>出错啦</strong><br/>';
  100. htm += obj.reason;
  101. document.getElementById('course_info_win_cont').innerHTML = htm;
  102. return;
  103. }
  104. if (obj.contrib < 1) {
  105. var htm = '<strong>请你支持</strong><br/>';
  106. htm += '我们的数据都来自大家的贡献,请同意将您的课程上课地点加入数据库。我们不会收集也不关心您的个人信息。<br/>';
  107. htm += '<button id="agree_contrib">同意贡献数据</button>';
  108. document.getElementById('course_info_win_cont').innerHTML = htm;
  109. document.getElementById('agree_contrib').addEventListener("click", upload_mydata, false);
  110. } else {
  111. upload_mydata();
  112. }
  113. }, upload_mydata = function() {
  114. GM_xmlhttpRequest({
  115. method: "POST",
  116. url: baseurl+"update.php?uid=" + uid,
  117. data: "data=" + encodeURIComponent(myclass),
  118. headers: {"Content-Type": "application/x-www-form-urlencoded"},
  119. onload: updatemainui
  120. });
  121. }, updatemainui = function(res) {
  122. var obj = JSON.parse(res.responseText);
  123. var htm = '';
  124. if (obj.r == -101) {
  125. htm ='<strong style="color:red">验证码错误!</strong><br/>';
  126. } else if (obj.r) {
  127. var htm ='<strong>出错啦</strong><br/>' + obj.reason;
  128. document.getElementById('course_info_win_cont').innerHTML = htm;
  129. return;
  130. }
  131. htm += '<strong>课程查询</strong><br/>';
  132. htm += '课程名称:*<input type="text" id="courseinfo_name" size="10"/><br/>';
  133. htm += '任课教师: <input type="text" id="courseinfo_prof" size="10"/><br/>';
  134. htm += '验证码:*<span id="yzmstore_wrapper_c1"></span><br/>';
  135. htm += '<button id="courseinfo_query">查询</button><br/>';
  136. if (obj.course) {
  137. htm += '<strong>查询结果</strong><span style="color:grey">(灰色可能为旧数据)</span><br/>';
  138. if (obj.course.length) {
  139. htm += '<table cellspacing="4px"><col width="150"><col width="40"><col width="40"><col width="40">';
  140. htm += '<tr><td>课名</td><td>教师</td><td>时间</td><td>教室</td></tr>';
  141. for (var i=0; i<obj.course.length; i++) {
  142. var old = (obj.course[i].utime == null) || (parseInt(obj.course[i].utime) + 60 * 86400 < (new Date()).getTime()/1000);
  143. if (old) {
  144. htm += '<tr style="color:grey"><td>'+obj.course[i].name+'</td><td>'+obj.course[i].prof+'</td><td>'+obj.course[i].schedule+'</td><td>'+obj.course[i].room+'</td></tr>';
  145. } else {
  146. htm += '<tr><td>'+obj.course[i].name+'</td><td>'+obj.course[i].prof+'</td><td>'+obj.course[i].schedule+'</td><td>'+obj.course[i].room+'</td></tr>';
  147. }
  148. }
  149. htm += '</table>';
  150. if (i == 16) {
  151. htm += '有些结果可能没有显示,请缩小查询范围.<br/>';
  152. }
  153. } else {
  154. htm += '没有找到。请明天再试试,当更多的人使用后,数据会更丰富。<br/>';
  155. }
  156. }
  157. document.getElementById('course_info_win_cont').innerHTML = htm;
  158. document.getElementById('courseinfo_query').addEventListener("click", do_search, false);
  159. add_script_head("http://apithu.yzmstore.com/api/yzmstore-js.php?publickey=TkjmRgi5A1gHhCpOTb4Anz8UeBJwjZyqfe_faRVI&name=c1&wrapper_id=yzmstore_wrapper_c1&theme=floating");
  160. }, do_search = function() {
  161. var name = encodeURIComponent(document.getElementById('courseinfo_name').value);
  162. var prof = encodeURIComponent(document.getElementById('courseinfo_prof').value);
  163. var cu = encodeURIComponent(document.getElementById('yzmstore_user_input_c1').value);
  164. var cid = document.getElementById('yzmstore_cha_id_c1').value
  165. if (!name) {
  166. alert("请填写课程名");
  167. return;
  168. }
  169. GM_xmlhttpRequest({
  170. method: "POST",
  171. url: baseurl+"query.php?uid=" + uid,
  172. data: "course=" + name + "&prof=" + prof + "&yzmstore_user_input_c1=" + cu + "&yzmstore_cha_id_c1=" + cid,
  173. headers: {"Content-Type": "application/x-www-form-urlencoded"},
  174. onload: updatemainui
  175. });
  176. };
  177. GM_xmlhttpRequest({
  178. method: "GET",
  179. url: "http://zhjw.cic.tsinghua.edu.cn/jxmh.do?url=/jxmh.do&m=yjs_kbSearch",
  180. onload: parsestudylist
  181. });
  182.  
  183. GM_xmlhttpRequest({
  184. method: "GET",
  185. url: "http://zhjw.cic.tsinghua.edu.cn/jxmh.do?url=/jxmh.do&m=bks_yjkbSearch",
  186. onload: parsestudylist
  187. });
  188.  
  189. openEx("course_info_win");
  190. setTimeout(function () {opacityEx("course_info_win")}, 50);
  191. }
  192.  
  193. function openEx(name)
  194. {
  195. var newwin = document.createElement("div");
  196. newwin.setAttribute("id", name);
  197. newwin.style.position = "absolute";
  198. newwin.style.top = "140px";
  199. newwin.style.right = "10px";
  200. newwin.style.width = "350px";
  201. newwin.style.textAlign = "left";
  202. // newwin.style.height = "100px";
  203. newwin.style.opacity = 2;
  204.  
  205. window.addEventListener("scroll", function() {
  206. var newpos = document.body.scrollTop + 80;
  207. newwin.setAttribute("tarpos", newpos);
  208. setTimeout(function () {if (!hwnd_Move) moveEx(name)}, 50);
  209. },false);
  210. var newpos = document.body.scrollTop + 80;
  211. newwin.setAttribute("tarpos", newpos);
  212. setTimeout(function () {if (!hwnd_Move) moveEx(name)}, 50);
  213. var htm="";
  214. document.body.appendChild(newwin);
  215.  
  216. newwin.setAttribute("taropc", 0.1)
  217. newwin.addEventListener("mouseover", function() {
  218. this.style.opacity = 2;
  219. newwin.setAttribute("taropc", 2)
  220. }, false);
  221. newwin.addEventListener("mouseout", function() {
  222. this.style.opacity = 2;
  223. newwin.setAttribute("taropc", 0.1)
  224. }, false);
  225. var htm = '';
  226. htm += '<table cellspacing="10px" style="border:dashed 1px grey; background-color:#F8F8F8; width: 100%;"><tr><td>';
  227. htm += '<div style="float:right"><a href="#" id="'+name+'_close">X</a></div><div id="'+name+'_cont"></div>';
  228. htm += '</td></tr></table>'
  229. newwin.innerHTML = htm;
  230.  
  231. document.getElementById(name+'_close').addEventListener("click", function() {
  232. newwin.style.display = "none";
  233. }, false);
  234. }
  235.  
  236. function moveEx(name)
  237. {
  238. var target = document.getElementById(name);
  239. var newpos = target.getAttribute("tarpos");
  240. var curr_pos = parseInt(target.style.top);
  241. if (curr_pos < newpos) {
  242. if (curr_pos-newpos<-8)
  243. curr_pos -= (curr_pos-newpos)/4;
  244. else
  245. curr_pos +=1;
  246. target.style.top = curr_pos;
  247. hwnd_Move = setTimeout(function () {moveEx(name)}, 50);
  248. }else if (curr_pos > newpos) {
  249. if (curr_pos-newpos>8)
  250. curr_pos -= (curr_pos-newpos)/4;
  251. else
  252. curr_pos -=1;
  253. target.style.top = curr_pos;
  254. hwnd_Move = setTimeout(function () {moveEx(name)}, 50);
  255. }else
  256. hwnd_Move = 0;
  257. }
  258.  
  259. function opacityEx(name)
  260. {
  261. var target = document.getElementById(name);
  262. var newpos = target.getAttribute("taropc");
  263. var curr_pos = parseFloat(target.style.opacity);
  264. if (curr_pos < newpos) {
  265. if (curr_pos-newpos<-0.2)
  266. curr_pos += 0.2;
  267. else
  268. curr_pos = newpos;
  269. target.style.opacity = curr_pos;
  270. }else if (curr_pos > newpos) {
  271. if (curr_pos-newpos>0.02)
  272. curr_pos -= 0.02;
  273. else
  274. curr_pos = newpos;
  275. target.style.opacity = curr_pos;
  276. }
  277. hwnd_Opacity = setTimeout(function () {opacityEx(name)}, 50);
  278. }
  279.  
  280. main();