ehAutoStar

EH画廊自动/批量评分脚本

  1. // ==UserScript==
  2. // @name ehAutoStar
  3. // @namespace moe.cangku.mengzonefire
  4. // @version 1.1.3
  5. // @description EH画廊自动/批量评分脚本
  6. // @author mengzonefire
  7. // @require https://cdn.jsdelivr.net/npm/sweetalert2@9
  8. // @require https://cdn.staticfile.org/jquery/3.6.0/jquery.min.js
  9. // @require https://cdn.jsdelivr.net/npm/jquery-migrate@3.4.0/dist/jquery-migrate.min.js
  10. // @match *://exhentai.org/g*
  11. // @match *://e-hentai.org/g*
  12. // @match *://exhentai.org/uploader/*
  13. // @match *://e-hentai.org/uploader/*
  14. // @grant GM_setValue
  15. // @grant GM_getValue
  16. // @run-at document-end
  17. // ==/UserScript==
  18. const href = window.location.href;
  19. const defRateMap = "BlossomPlus 5";
  20. !(function () {
  21. "use strict";
  22. var rating_img;
  23. var uploader;
  24. var my_apikey;
  25. var my_apiuid;
  26. var g_flag;
  27. var link_ele;
  28. var star_ele;
  29. var GaInfo;
  30. var count = 0;
  31. var fail_count = 0;
  32. var domain = href.indexOf("exhentai") != -1 ? "exhentai" : "e-hentai";
  33. var rateMapText = GM_getValue("rateMap");
  34. var rateMap = [];
  35. var icon_url =
  36. domain == "exhentai"
  37. ? "https://exhentai.org/img/mr.gif"
  38. : "https://ehgt.org/g/mr.gif";
  39. var html_btn = '<div style="float:left">&nbsp; <a id="rateSetting" href="#">';
  40. html_btn += `<img src="${icon_url}"> 自动评分设置`;
  41. html_btn += "</a></div>";
  42. var html_input =
  43. '<div style="position: absolute;margin-left: 5px;"><input type="button" value="一键评分" id="autoRate"><input type="text" id="inputRate" value="5" size="4" maxlength="3" style="width:22px"></div>';
  44. if (!rateMapText) {
  45. rateMapText = defRateMap;
  46. GM_setValue("rateMap", rateMapText);
  47. }
  48. readRateMap();
  49.  
  50. if (href.indexOf("/uploader/") != -1) {
  51. g_flag = false;
  52. let loop = setInterval(() => {
  53. var html_tag2 = $("div.searchnav:first");
  54. if (!html_tag2.length) return false;
  55. html_tag2.before(html_input);
  56. $("#autoRate").click(function () {
  57. $("#autoRate").prop("value", "正在执行").prop("disabled", true);
  58. batchRating();
  59. });
  60. clearInterval(loop);
  61. }, 500);
  62. } else if (href.indexOf("/g/") != -1) {
  63. var style;
  64. g_flag = true;
  65. my_apikey = apikey;
  66. my_apiuid = apiuid;
  67. if (domain == "exhentai") {
  68. style =
  69. "<style>.swal2-textarea{color:#ffffff;background-color:#43464e}</style>";
  70. } else {
  71. style =
  72. "<style>.swal2-textarea{color:#000000;background-color:#f3f0e0}</style>";
  73. }
  74. var ele = document.createElement("div");
  75. ele.innerHTML = style;
  76. document.getElementsByTagName("head")[0].appendChild(ele.firstElementChild);
  77.  
  78. let loop1 = setInterval(() => {
  79. var html_tag = $("#gdr");
  80. if (!html_tag.length) return false;
  81. html_tag.append(html_btn);
  82. $("#rateSetting").click(function () {
  83. rateSetting();
  84. });
  85. clearInterval(loop1);
  86. }, 500);
  87.  
  88. let loop2 = setInterval(() => {
  89. uploader = $("#gdn>a")[0].innerText;
  90. rating_img = $("#rating_image")[0];
  91. if (!uploader || !rating_img) return false;
  92. else if (
  93. rating_img.className == "ir" &&
  94. rateMap.hasOwnProperty(uploader)
  95. ) {
  96. rating(rateMap[uploader], -1);
  97. }
  98. clearInterval(loop2);
  99. }, 500);
  100.  
  101. if (apikey != GM_getValue("apikey")) {
  102. GM_setValue("apikey", apikey);
  103. }
  104. if (apiuid != GM_getValue("apiuid")) {
  105. GM_setValue("apiuid", apiuid);
  106. }
  107. }
  108.  
  109. function rating(rate, recu) {
  110. if (recu == -1) GaInfo = href.match(/\/g\/([\d]+)\/([\da-f]+)\//);
  111. else {
  112. if (recu == star_ele.length) {
  113. Swal.fire(`一键评分完成,共评分${count}个画廊,失败${fail_count}个`);
  114. $("#autoRate").prop("value", "一键评分").prop("disabled", false);
  115. return true;
  116. }
  117. if (star_ele[recu].className == "ir") {
  118. rating_img = star_ele[recu];
  119. GaInfo = link_ele[recu].href.match(/\/g\/([\d]+)\/([\da-f]+)\//);
  120. } else {
  121. rating(rate, recu + 1);
  122. return false;
  123. }
  124. }
  125. $.ajax({
  126. url: "/api.php",
  127. type: "POST",
  128. contentType: "application/json",
  129. dataType: "json",
  130. data: JSON.stringify({
  131. apikey: my_apikey,
  132. apiuid: my_apiuid,
  133. gid: Number(GaInfo[1]),
  134. method: "rategallery",
  135. rating: rate * 2,
  136. token: GaInfo[2],
  137. }),
  138. })
  139. .success(function (r) {
  140. console.log(r);
  141. if (!r["error"]) {
  142. var n1 = Math.ceil(rate - 5) * 16;
  143. var n2 = rate % 1 ? -21 : -1;
  144. rating_img.setAttribute(
  145. "style",
  146. `background-position: ${n1}px ${n2}px;`
  147. );
  148. rating_img.className = r["rating_cls"];
  149. if (recu == -1) {
  150. $("#rating_label")[0].innerText = `平均值:${r["rating_avg"]}`;
  151. $("#rating_count")[0].innerText = r["rating_cnt"];
  152. }
  153. }
  154. })
  155. .fail(function (r) {
  156. console.log(r);
  157. fail_count += 1;
  158. })
  159. .always(function () {
  160. count += 1;
  161. if (recu != -1) rating(rate, recu + 1);
  162. });
  163. }
  164.  
  165. function rateSetting() {
  166. Swal.fire({
  167. title: "输入自动评分配置\n格式:上传者 分数(0.5-5)",
  168. input: "textarea",
  169. inputValue: GM_getValue("rateMap"),
  170. showCancelButton: true,
  171. confirmButtonText: "确定",
  172. cancelButtonText: "取消",
  173. inputValidator: (value) => {
  174. rateMapText = value;
  175. var errNum = readRateMap();
  176. if (errNum != -1) {
  177. return `第{${errNum + 1}行格式错误,分数必须为0.5的整数倍`;
  178. }
  179. },
  180. }).then((result) => {
  181. if (result.dismiss) return;
  182. GM_setValue("rateMap", rateMapText);
  183. });
  184. }
  185.  
  186. function readRateMap() {
  187. var mapLine = rateMapText.split("\n");
  188. for (var line of mapLine) {
  189. var result = line.match(/([\s\S]+) ((?:[0-4].5)?[1-5]?)$/);
  190. if (result) rateMap[result[1]] = Number(result[2]);
  191. else return mapLine.indexOf(line);
  192. }
  193. return -1;
  194. }
  195.  
  196. function batchRating() {
  197. if (GM_getValue("apiuid")) {
  198. my_apikey = GM_getValue("apikey");
  199. my_apiuid = GM_getValue("apiuid");
  200. } else {
  201. Swal.fire(
  202. "api参数未记录, 请先登录并进入任意画廊, 脚本会自动记录参数, 然后再使用此功能"
  203. );
  204. $("#autoRate").prop("value", "一键评分").prop("disabled", false);
  205. return false;
  206. }
  207. if (my_apiuid != Number(getCookie("ipb_member_id"))) {
  208. Swal.fire(
  209. "api参数不匹配, 请先进入任意画廊, 脚本会自动刷新参数, 然后再使用此功能"
  210. );
  211. $("#autoRate").prop("value", "一键评分").prop("disabled", false);
  212. return false;
  213. }
  214. var select_ele = $("div.searchnav:first > div > select > option"); // 列表右上的模式选择框 (最小化...缩略图...扩展)
  215. var select_flag = getSelect(select_ele);
  216.  
  217. switch (select_flag) {
  218. case "m":
  219. case "p":
  220. star_ele = $("td.gl4m > div");
  221. link_ele = $("td.gl3m.glname > a");
  222. break;
  223. case "l":
  224. star_ele = $("td.gl2c > div:nth-child(3) > div.ir");
  225. link_ele = $("td.gl3c.glname > a");
  226. break;
  227. case "e":
  228. star_ele = $("td.gl2e > div > div > div.ir");
  229. link_ele = $("td.gl2e > div > a");
  230. break;
  231. case "t":
  232. star_ele = $("div.gl5t > div:nth-child(2) > div.ir");
  233. link_ele = $("div.itg.gld > div > a");
  234. break;
  235. default:
  236. Swal.fire("一键评分失败: select元素错误");
  237. $("#autoRate").prop("value", "一键评分").prop("disabled", false);
  238. return false;
  239. }
  240.  
  241. if (link_ele.length != star_ele.length) {
  242. Swal.fire("一键评分失败: html元素不匹配");
  243. $("#autoRate").prop("value", "一键评分").prop("disabled", false);
  244. } else {
  245. var my_rate = Number($("#inputRate")[0].value);
  246. if (my_rate > 0 && my_rate <= 5 && my_rate % 0.5 == 0) {
  247. rating(my_rate, 0);
  248. } else {
  249. Swal.fire("分数错误:数值必须在0.5-5之间且为0.5的整数倍");
  250. $("#autoRate").prop("value", "一键评分").prop("disabled", false);
  251. }
  252. }
  253. }
  254.  
  255. function getCookie(cookie_name) {
  256. var allcookies = document.cookie;
  257. var cookie_pos = allcookies.indexOf(cookie_name);
  258. if (cookie_pos != -1) {
  259. cookie_pos = cookie_pos + cookie_name.length + 1;
  260. var cookie_end = allcookies.indexOf(";", cookie_pos);
  261. if (cookie_end == -1) cookie_end = allcookies.length;
  262. var value = unescape(allcookies.substring(cookie_pos, cookie_end));
  263. }
  264. return value;
  265. }
  266.  
  267. function getSelect(select_ele) {
  268. for (var i = 0; i < select_ele.length; i++) {
  269. if (select_ele[i].getAttribute("selected")) {
  270. return select_ele[i].getAttribute("value");
  271. }
  272. }
  273. return null;
  274. }
  275. })();