Greasy Fork is available in English.

微博抽奖小助手(非官方)

打开微博帖子页面,按L载入转发用户,按S抽奖。

  1. // ==UserScript==
  2. // @name 微博抽奖小助手(非官方)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.6
  5. // @description 打开微博帖子页面,按L载入转发用户,按S抽奖。
  6. // @author Kasei
  7. // @match https://weibo.com/*/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=weibo.com
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12. (function() {
  13. 'use strict';
  14. setTimeout(function() {
  15. // Get infromation based on URL
  16. var url_component = document.URL.split(/[#,/?]/g);
  17. document.uid = url_component[3];
  18. document.post_id = url_component[4];
  19. if (!/^[0-9]+$/.test(document.uid) || !/^[A-Za-z0-9]+$/.test(document.post_id)) {
  20. console.log("Not a post page");
  21. return;
  22. }
  23. // GUI
  24. var button_container = document.querySelector("footer>div.woo-box-flex.woo-box-alignCenter");
  25. var button_element = button_container.children[0].cloneNode(true);
  26. button_container.appendChild(button_element);
  27. var button_text = button_element.querySelector(".woo-box-alignCenter>span");
  28. button_text.innerHTML = ' 抽奖 ';
  29. // button_element.querySelector(".woo-pop-ctrl").setAttribute("id", "shuffle");
  30. // Load post information
  31. function get_post() {
  32. var requestOptions = {
  33. method: 'GET',
  34. redirect: 'follow'
  35. };
  36. return fetch(`https://weibo.com/ajax/statuses/show?id=${document.post_id}`, requestOptions);
  37. }
  38. // Load re-post page
  39. function get_next_page() {
  40. var requestOptions = {
  41. method: 'GET',
  42. redirect: 'follow'
  43. };
  44. if (document.arg_data.page == 1 || document.arg_data.page <= document.arg_data.max_page) {
  45. console.log(`Loading Page ${document.arg_data.page}`);
  46. if (button_text) {
  47. var percentage = document.arg_data.page / document.arg_data.max_page * 100;
  48. button_text.innerHTML = `${percentage > 0?percentage.toFixed(2):0}%`;
  49. }
  50. return fetch(`https://weibo.com/ajax/statuses/repostTimeline?id=${document.arg_data.id}&page=${document.arg_data.page}&moduleID=feed&count=${document.arg_data.page==1?10:20}`, requestOptions)
  51. .then((response) => {
  52. return response.json();
  53. }).then((repost_data) => {
  54. repost_data.data.forEach((dat) => {
  55. document.arg_data.users[dat.user.id] = {
  56. "name": dat.user.screen_name,
  57. "time": new Date(dat.created_at)
  58. }
  59. })
  60. document.arg_data.page = document.arg_data.page + 1;
  61. document.arg_data.max_page = repost_data.max_page;
  62. }).then(get_next_page);
  63. } else {
  64. return document.arg_data.users;
  65. }
  66. }
  67. // Load users into document.usr
  68. function load_users() {
  69. if (document.arg_data != undefined) {
  70. window.alert("正在载入转发人,请等待读条完毕");
  71. return;
  72. }
  73. window.alert("载入转发人,请稍后");
  74. return get_post().then((response) => {
  75. return response.json();
  76. }).then((post_data) => {
  77. document.arg_data = {
  78. "id": post_data.id,
  79. "reposts_count": post_data.reposts_count,
  80. "page": 1,
  81. "max_page": -1,
  82. "users": {}
  83. };
  84. }).then(get_next_page).then((usr) => {
  85. document.ready_shuffle = true;
  86. document.usr = usr;
  87. document.arg_data = undefined;
  88. }).catch((error) => {
  89. document.arg_data = undefined;
  90. window.alert("载入错误,请重试。");
  91. console.error('Error:', error);
  92. }).then(() => {
  93. var uid_list = Object.keys(document.usr);
  94. window.alert(`载入转发列表成功:总计${Object.keys(uid_list).length}个抽选者`);
  95. button_text.innerHTML = ' 开抽 ';
  96. });
  97. }
  98. // Durstenfeld shuffle
  99. function shuffleArray(array) {
  100. for (let i = array.length - 1; i > 0; i--) {
  101. const j = Math.floor(Math.random() * (i + 1));
  102. [array[i], array[j]] = [array[j], array[i]];
  103. }
  104. }
  105. // Shuffle for award winner
  106. function check_award() {
  107. // Const for text
  108. const cutoff_prompt = "请输入抽奖截止时间:";
  109. const count_prompt = "请输入中奖人个数:";
  110. // Get cut off date
  111. var cutoff_date = new Date(prompt(cutoff_prompt, "" + Date()));
  112. while (cutoff_date instanceof Date && isNaN(cutoff_date)) { // Is invalid date
  113. cutoff_date = new Date(prompt(cutoff_prompt, "" + Date()));
  114. }
  115. // Construct array for uid list
  116. var uid_list = Object.keys(document.usr);
  117. shuffleArray(uid_list);
  118. // Get count of awards
  119. var count = Number(prompt(count_prompt, "1"));
  120. while (!Number.isInteger(count) || count <= 0) { // Is invalid count
  121. count = Number(prompt(count_prompt, "1"));
  122. }
  123. // Generate Results
  124. var got = 0;
  125. for (var i=0; i<uid_list.length && got < count; ++i) {
  126. if (document.usr[uid_list[i]].time < cutoff_date) {
  127. var usr = document.usr[uid_list[i]];
  128. window.alert(`中奖人${got+1}/${count}:` +
  129. `\n 微博ID${uid_list[i]}` +
  130. `\n 微博名称:${usr.name}` +
  131. `\n 发博时间:${usr.time}` +
  132. `\n ${Date()}`);
  133. got++;
  134. }
  135. }
  136. }
  137.  
  138. // Add key listener
  139. function keydownHandler(e) {
  140. // [S]huffle users
  141. if (e.keyCode == 83 && document.ready_shuffle) {
  142. check_award();
  143. }
  144. // [L]oad user list
  145. if (e.keyCode == 76) {
  146. load_users();
  147. }
  148. // [P]rint users into console
  149. if (e.keyCode == 80 && document.ready_shuffle) {
  150. window.alert("中奖人名单已打印至控制台,请按F12点击控制台查看");
  151. console.log(document.usr);
  152. }
  153. }
  154. // register your handler method for the keydown event
  155. if (document.addEventListener) {
  156. document.addEventListener('keydown', keydownHandler, false);
  157. } else if (document.attachEvent) {
  158. document.attachEvent('onkeydown', keydownHandler);
  159. }
  160. // Load GUI handler
  161. button_element.addEventListener('click', (event) => {
  162. if (document.ready_shuffle) {
  163. check_award();
  164. } else {
  165. load_users();
  166. }
  167. });
  168. }, 1000);
  169. })();