115Rename

115改名称(根据现有的文件名<番号>查询并修改文件名)

  1. // ==UserScript==
  2. // @name 115Rename
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.8
  5. // @description 115改名称(根据现有的文件名<番号>查询并修改文件名)
  6. // @author db117
  7. // @include https://115.com/*
  8. // @domain javbus.com
  9. // @domain avmoo.host
  10. // @domain avsox.host
  11. // @grant GM_notification
  12. // @grant GM_xmlhttpRequest
  13. // @license MIT
  14. // ==/UserScript==
  15. (function () {
  16. // 按钮
  17. let rename_list = `
  18. <li id="rename_list">
  19. <a id="rename_all_javbus" class="mark" href="javascript:;">改名javbus</a>
  20. <a id="rename_all_javbus_date" class="mark" href="javascript:;">改名javbus_时间</a>
  21. <a id="rename_all_avmoo" class="mark" href="javascript:;">改名avmoo</a>
  22. <a id="rename_all_avmoo_date" class="mark" href="javascript:;">改名avmoo_时间</a>
  23. </li>
  24. `;
  25. /**
  26. * 添加按钮的定时任务
  27. */
  28. let interval = setInterval(buttonInterval, 1000);
  29. // javbus
  30. let javbusBase = "https://www.javbus.com/";
  31. // 有码
  32. let javbusSearch = javbusBase + "search/";
  33. // 无码
  34. let javbusUncensoredSearch = javbusBase + "uncensored/search/";
  35. // avmoo
  36. // 有码
  37. let avmooSearch = "https://avmoo.host/cn/search/";
  38. // 无码
  39. let avmooUncensoredSearch = "https://avsox.host/cn/search/";
  40. 'use strict';
  41. /**
  42. * 添加按钮定时任务(检测到可以添加时添加按钮)
  43. */
  44. function buttonInterval() {
  45. let open_dir = $("div#js_float_content li[val='open_dir']");
  46. if (open_dir.length !== 0 && $("li#rename_list").length === 0) {
  47. open_dir.before(rename_list);
  48. $("a#rename_all_javbus").click(
  49. function () {
  50. rename(rename_javbus, false);
  51. });
  52. $("a#rename_all_javbus_date").click(
  53. function () {
  54. rename(rename_javbus, true);
  55. });
  56. $("a#rename_all_avmoo").click(
  57. function () {
  58. rename(rename_avmoo, false);
  59. });
  60. $("a#rename_all_avmoo_date").click(
  61. function () {
  62. rename(rename_avmoo, true);
  63. });
  64. console.log("添加按钮");
  65. // 结束定时任务
  66. clearInterval(interval);
  67. }
  68. }
  69. /**
  70. * 执行改名方法
  71. * @param call 回调函数
  72. * @param addDate 是否添加时间
  73. */
  74. function rename(call, addDate) {
  75. // 获取所有已选择的文件
  76. let list = $("iframe[rel='wangpan']")
  77. .contents()
  78. .find("li.selected")
  79. .each(function (index, v) {
  80. let $item = $(v);
  81. // 原文件名称
  82. let file_name = $item.attr("title");
  83. // 文件类型
  84. let file_type = $item.attr("file_type");
  85. // 文件id
  86. let fid;
  87. // 后缀名
  88. let suffix;
  89. if (file_type === "0") {
  90. // 文件夹
  91. fid = $item.attr("cate_id");
  92. } else {
  93. // 文件
  94. fid = $item.attr("file_id");
  95. // 处理后缀
  96. let lastIndexOf = file_name.lastIndexOf('.');
  97. if (lastIndexOf !== -1) {
  98. suffix = file_name.substr(lastIndexOf, file_name.length);
  99. }
  100. }
  101. if (fid && file_name) {
  102. let fh = getVideoCode(file_name);
  103. if (fh) {
  104. // 校验是否是中文字幕
  105. let chineseCaptions = checkChineseCaptions(fh, file_name);
  106. // 执行查询
  107. call(fid, fh, suffix, chineseCaptions, addDate);
  108. }
  109. }
  110. });
  111. }
  112. /**
  113. * 通过javbus进行查询
  114. */
  115. function rename_javbus(fid, fh, suffix, chineseCaptions, addDate) {
  116. requestJavbus(fid, fh, suffix, chineseCaptions, addDate, javbusSearch);
  117. }
  118. /**
  119. * 请求javbus,并请求115进行改名
  120. * @param fid 文件id
  121. * @param fh 番号
  122. * @param suffix 后缀
  123. * @param chineseCaptions 是否有中文字幕
  124. * @param url 请求地址
  125. * @param addDate 是否添加时间
  126. */
  127. function requestJavbus(fid, fh, suffix, chineseCaptions, addDate, url) {
  128. GM_xmlhttpRequest({
  129. method: "GET",
  130. url: url + fh,
  131. onload: xhr => {
  132. // 匹配标题
  133. let response = $(xhr.responseText);
  134. // 标题
  135. let title = response
  136. .find("div.photo-frame img")
  137. .attr("title");
  138. // 时间
  139. let date = response
  140. .find("div.photo-info date:last")
  141. .html();
  142. if (title) {
  143. // 构建新名称
  144. let newName = buildNewName(fh, suffix, chineseCaptions, title);
  145. // 添加时间
  146. if (addDate && date) {
  147. newName = date + "_" + newName;
  148. }
  149. if (newName) {
  150. // 修改名称
  151. send_115(fid, newName, fh);
  152. }
  153. } else if (url !== javbusUncensoredSearch) {
  154. // 进行无码重查询
  155. requestJavbus(fid, fh, suffix, chineseCaptions, addDate, javbusUncensoredSearch);
  156. }
  157. }
  158. })
  159. }
  160. /**
  161. * 通过avmoo进行查询
  162. */
  163. function rename_avmoo(fid, fh, suffix, chineseCaptions, addDate) {
  164. requestAvmoo(fid, fh, suffix, chineseCaptions, addDate, avmooSearch);
  165. }
  166. /**
  167. * 请求avmoo,并请求115进行改名
  168. * @param fid 文件id
  169. * @param fh 番号
  170. * @param suffix 后缀
  171. * @param chineseCaptions 是否有中文字幕
  172. * @param addDate 是否带时间
  173. * @param url 请求地址
  174. */
  175. function requestAvmoo(fid, fh, suffix, chineseCaptions, addDate, url) {
  176. GM_xmlhttpRequest({
  177. method: "GET",
  178. url: url + fh,
  179. onload: xhr => {
  180. // 匹配标题
  181. let response = $(xhr.responseText);
  182. if (!(response.find("div.alert").length)) {
  183. let title = response
  184. .find("div.photo-frame img")
  185. .attr("title");
  186. // 时间
  187. let date = response
  188. .find("div.photo-info date:last")
  189. .html();
  190. if (title) {
  191. // 构建新名称
  192. let newName = buildNewName(fh, suffix, chineseCaptions, title);
  193. // 添加时间
  194. if (addDate && date) {
  195. newName = date + "_" + newName;
  196. }
  197. if (newName) {
  198. // 修改名称
  199. send_115(fid, newName, fh);
  200. }
  201. }
  202. } else if (url !== avmooUncensoredSearch) {
  203. // 进行无码查询
  204. requestAvmoo(fid, fh, suffix, chineseCaptions, addDate, avmooUncensoredSearch);
  205. }
  206. }
  207. })
  208. }
  209. /**
  210. * 构建新名称
  211. * @param fh 番号
  212. * @param suffix 后缀
  213. * @param chineseCaptions 是否有中文字幕
  214. * @param title 番号标题
  215. * @returns {string} 新名称
  216. */
  217. function buildNewName(fh, suffix, chineseCaptions, title) {
  218. if (title) {
  219. let newName = String(fh);
  220. // 有中文字幕
  221. if (chineseCaptions) {
  222. newName = newName + "【中文字幕】";
  223. }
  224. // 拼接标题
  225. newName = newName + " " + title;
  226. if (suffix) {
  227. // 文件保存后缀名
  228. newName = newName + suffix;
  229. }
  230. return newName;
  231. }
  232. }
  233. /**
  234. * 请求115接口
  235. * @param id 文件id
  236. * @param name 要修改的名称
  237. * @param fh 番号
  238. */
  239. function send_115(id, name, fh) {
  240. let file_name = stringStandard(name);
  241. $.post("https://webapi.115.com/files/edit", {
  242. fid: id,
  243. file_name: file_name
  244. },
  245. function (data, status) {
  246. let result = JSON.parse(data);
  247. if (!result.state) {
  248. GM_notification(getDetails(fh, "修改失败"));
  249. console.log("请求115接口异常: " + unescape(result.error
  250. .replace(/\\(u[0-9a-fA-F]{4})/gm, '%$1')));
  251. } else {
  252. GM_notification(getDetails(fh, "修改成功"));
  253. console.log("修改文件名称,fh:" + fh, "name:" + file_name);
  254. }
  255. }
  256. );
  257. }
  258. /**
  259. * 通知参数
  260. * @param text 内容
  261. * @param title 标题
  262. * @returns {{text: *, title: *, timeout: number}}
  263. */
  264. function getDetails(text, title) {
  265. return {
  266. text: text,
  267. title: title,
  268. timeout: 1000
  269. };
  270. }
  271. /**
  272. * 115名称不接受(\/:*?\"<>|)
  273. * @param name
  274. */
  275. function stringStandard(name) {
  276. return name.replace(/\\/g, "")
  277. .replace(/\//g, " ")
  278. .replace(/:/g, " ")
  279. .replace(/\?/g, " ")
  280. .replace(/"/g, " ")
  281. .replace(/</g, " ")
  282. .replace(/>/g, " ")
  283. .replace(/\|/g, "")
  284. .replace(/\*/g, " ");
  285. }
  286. /**
  287. * 校验是否为中文字幕
  288. * @param fh 番号
  289. * @param title 标题
  290. */
  291. function checkChineseCaptions(fh, title) {
  292. if (title.indexOf("中文字幕") !== -1) {
  293. return true;
  294. }
  295. let regExp = new RegExp(fh + "[_-]C");
  296. let match = title.toUpperCase().match(regExp);
  297. if (match) {
  298. return true;
  299. }
  300. }
  301. /**
  302. * 获取番号
  303. * @param title 源标题
  304. * @returns {string} 提取的番号
  305. */
  306. function getVideoCode(title) {
  307. title = title.toUpperCase().replace("SIS001", "")
  308. .replace("1080P", "")
  309. .replace("720P", "");
  310. let t = title.match(/T28[\-_]\d{3,4}/);
  311. // 一本道
  312. if (!t) {
  313. t = title.match(/1PONDO[\-_]\d{6}[\-_]\d{2,4}/);
  314. if (t) {
  315. t = t.toString().replace("1PONDO_", "")
  316. .replace("1PONDO-", "");
  317. }
  318. }
  319. if (!t) {
  320. t = title.match(/HEYZO[\-_]?\d{4}/);
  321. }
  322. if (!t) {
  323. // 加勒比
  324. t = title.match(/CARIB[\-_]\d{6}[\-_]\d{3}/);
  325. if (t) {
  326. t = t.toString().replace("CARIB-", "")
  327. .replace("CARIB_", "");
  328. }
  329. }
  330. if (!t) {
  331. // 东京热
  332. t = title.match(/N[-_]\d{4}/);
  333. }
  334. if (!t) {
  335. // Jukujo-Club | 熟女俱乐部
  336. t = title.match(/JUKUJO[-_]\d{4}/);
  337. }
  338. // 通用
  339. if (!t) {
  340. t = title.match(/[A-Z]{2,5}[-_]\d{3,5}/);
  341. }
  342. if (!t) {
  343. t = title.match(/\d{6}[\-_]\d{2,4}/);
  344. }
  345. if (!t) {
  346. t = title.match(/[A-Z]+\d{3,5}/);
  347. }
  348. if (!t) {
  349. t = title.match(/[A-Za-z]+[-_]?\d+/);
  350. }
  351. if (!t) {
  352. t = title.match(/\d+[-_]?\d+/);
  353. }
  354. if (!t) {
  355. t = title;
  356. }
  357. if (t) {
  358. t = t.toString().replace("_", "-");
  359. console.log("找到番号:" + t);
  360. return t;
  361. }
  362. }
  363. })();