动漫花园预览增强

在动漫花园种子列表显示预览和磁力链接

  1. // ==UserScript==
  2. // @name 动漫花园预览增强
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description 在动漫花园种子列表显示预览和磁力链接
  6. // @author You
  7. // @match *://dmhy.org/*
  8. // @match *://share.dmhy.org/*
  9. // @grant GM_addStyle
  10. // @grant GM_setClipboard
  11. // @require https://code.jquery.com/jquery-3.6.0.min.js
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // 确保jQuery加载
  19. if (typeof window.jQuery === 'undefined') {
  20. console.error('jQuery未能正确加载');
  21. return;
  22. }
  23.  
  24. let $ = window.jQuery.noConflict(true);
  25.  
  26. // 添加样式
  27. GM_addStyle(`
  28. .preview-box {
  29. padding: 10px;
  30. background: #f8f8f8;
  31. margin: 5px 0;
  32. border: 1px solid #ddd;
  33. border-radius: 4px;
  34. }
  35. .magnet-container {
  36. display: flex;
  37. align-items: center;
  38. gap: 10px;
  39. background: #fff;
  40. padding: 8px;
  41. margin: 5px 0;
  42. border-radius: 4px;
  43. border: 1px solid #e0e0e0;
  44. }
  45. .magnet-link {
  46. flex-grow: 1;
  47. word-break: break-all;
  48. font-family: monospace;
  49. font-size: 12px;
  50. padding: 5px;
  51. border-radius: 4px;
  52. background: #f5f5f5;
  53. cursor: pointer;
  54. }
  55. .magnet-link:hover {
  56. background-color: #e8e8e8;
  57. }
  58. .copy-btn {
  59. padding: 5px 10px;
  60. background: #4CAF50;
  61. color: white;
  62. border: none;
  63. border-radius: 4px;
  64. cursor: pointer;
  65. font-size: 12px;
  66. }
  67. .copy-btn:hover {
  68. background: #45a049;
  69. }
  70. .copy-tooltip {
  71. position: fixed;
  72. top: 50%;
  73. left: 50%;
  74. transform: translate(-50%, -50%);
  75. background: rgba(0, 0, 0, 0.8);
  76. color: white;
  77. padding: 10px 20px;
  78. border-radius: 4px;
  79. z-index: 10000;
  80. pointer-events: none;
  81. }
  82. .file-info {
  83. margin-top: 5px;
  84. font-size: 12px;
  85. color: #666;
  86. }
  87. .preview-container {
  88. display: flex;
  89. gap: 15px;
  90. align-items: flex-start;
  91. }
  92. .preview-image {
  93. width: 200px;
  94. height: 150px;
  95. background: #f0f0f0;
  96. display: flex;
  97. align-items: center;
  98. justify-content: center;
  99. border-radius: 4px;
  100. overflow: hidden;
  101. }
  102. .preview-image img {
  103. max-width: 100%;
  104. max-height: 100%;
  105. object-fit: contain;
  106. }
  107. .preview-info {
  108. flex: 1;
  109. }
  110. .loading {
  111. color: #666;
  112. font-size: 14px;
  113. }
  114. .no-image {
  115. color: #999;
  116. font-size: 14px;
  117. }
  118. `);
  119.  
  120. // 显示提示
  121. function showTooltip(message) {
  122. const tooltip = $('<div class="copy-tooltip"></div>').text(message);
  123. $('body').append(tooltip);
  124. setTimeout(() => {
  125. tooltip.fadeOut(200, function() {
  126. tooltip.remove();
  127. });
  128. }, 1000);
  129. }
  130.  
  131. // 处理种子列表
  132. function processTable() {
  133. $('table.tablesorter tbody tr').each(function() {
  134. const row = $(this);
  135. if (row.hasClass('processed')) return;
  136.  
  137. // 获取详情页链接
  138. const detailLink = row.find('td.title a').attr('href');
  139. if (!detailLink) return;
  140.  
  141. // 获取磁力链接并提取哈��值
  142. const fullMagnetLink = row.find('a[href^="magnet:?"]').attr('href');
  143. if (!fullMagnetLink) return;
  144.  
  145. const hashMatch = fullMagnetLink.match(/magnet:\?xt=urn:btih:([A-Za-z0-9]+)/i);
  146. if (!hashMatch) return;
  147.  
  148. const shortMagnetLink = `magnet:?xt=urn:btih:${hashMatch[1]}`;
  149. const fileSize = row.find('td:nth-child(5)').text().trim();
  150.  
  151. // 创建预览框
  152. const previewBox = $(`
  153. <tr>
  154. <td colspan="6" class="preview-box">
  155. <div class="preview-container">
  156. <div class="preview-image">
  157. <span class="loading">加载中...</span>
  158. </div>
  159. <div class="preview-info">
  160. <div class="magnet-container">
  161. <div class="magnet-link" title="点击复制磁力链接">${shortMagnetLink}</div>
  162. <button class="copy-btn">复制链接</button>
  163. </div>
  164. <div class="file-info">
  165. 文件大小: ${fileSize}
  166. </div>
  167. </div>
  168. </div>
  169. </td>
  170. </tr>
  171. `);
  172.  
  173. // 获取预览图
  174. $.get(detailLink, function(response) {
  175. const html = $(response);
  176. const previewImageDiv = previewBox.find('.preview-image');
  177.  
  178. // 获取 topic-nfo box ui-corner-all 区域内的图片
  179. const topicInfo = html.find('div.topic-nfo.box.ui-corner-all');
  180. if (topicInfo.length) {
  181. // 查找所有图片,优先匹配腾讯视频的封面图
  182. const contentImages = topicInfo.find('img').filter(function() {
  183. const src = $(this).attr('src');
  184. // 匹配 puui.qpic.cn 域名的图片
  185. return src && (
  186. src.includes('puui.qpic.cn/vcover_vt_pic') ||
  187. src.includes('puui.qpic.cn/vcover') ||
  188. src.includes('qpic.cn')
  189. );
  190. });
  191.  
  192. if (contentImages.length) {
  193. const imgUrl = contentImages.first().attr('src');
  194. if (imgUrl) {
  195. const fullImgUrl = imgUrl.startsWith('http') ?
  196. imgUrl :
  197. new URL(imgUrl, window.location.origin).href;
  198.  
  199. previewImageDiv.html(`
  200. <img src="${fullImgUrl}" alt="预览图"
  201. onerror="this.parentElement.innerHTML='<span class=\'no-image\'>图片加载失败</span>'"
  202. style="cursor: pointer"
  203. onclick="window.open('${fullImgUrl}', '_blank')"
  204. >
  205. `);
  206. } else {
  207. previewImageDiv.html('<span class="no-image">无图</span>');
  208. }
  209. } else {
  210. // 如果没有找到腾讯视频封面,尝试查找其他图片
  211. const otherImages = topicInfo.find('img').filter(function() {
  212. const src = $(this).attr('src');
  213. return src && src.length > 0;
  214. }).first();
  215.  
  216. if (otherImages.length) {
  217. const imgUrl = otherImages.attr('src');
  218. if (imgUrl) {
  219. const fullImgUrl = imgUrl.startsWith('http') ?
  220. imgUrl :
  221. new URL(imgUrl, window.location.origin).href;
  222.  
  223. previewImageDiv.html(`
  224. <img src="${fullImgUrl}" alt="预览图"
  225. onerror="this.parentElement.innerHTML='<span class=\'no-image\'>图片加载失败</span>'"
  226. style="cursor: pointer"
  227. onclick="window.open('${fullImgUrl}', '_blank')"
  228. >
  229. `);
  230. } else {
  231. previewImageDiv.html('<span class="no-image">无图</span>');
  232. }
  233. } else {
  234. previewImageDiv.html('<span class="no-image">无图</span>');
  235. }
  236. }
  237. } else {
  238. previewImageDiv.html('<span class="no-image">无图</span>');
  239. }
  240. }).fail(function() {
  241. previewBox.find('.preview-image').html('<span class="no-image">加载失败</span>');
  242. });
  243.  
  244. // 添加复制功能
  245. previewBox.find('.magnet-link').click(function() {
  246. GM_setClipboard(shortMagnetLink);
  247. showTooltip('已复制磁力链接');
  248. $(this).css('background-color', '#e6ffe6');
  249. setTimeout(() => {
  250. $(this).css('background-color', '');
  251. }, 500);
  252. });
  253.  
  254. previewBox.find('.copy-btn').click(function() {
  255. GM_setClipboard(shortMagnetLink);
  256. showTooltip('已复制磁力链接');
  257. const $this = $(this);
  258. $this.text('已复制').css('background-color', '#45a049');
  259. setTimeout(() => {
  260. $this.text('复制链接').css('background-color', '#4CAF50');
  261. }, 1000);
  262. });
  263.  
  264. // 插入预览框
  265. row.after(previewBox);
  266. row.addClass('processed');
  267. });
  268. }
  269.  
  270. // 页面加载完成后执行
  271. $(document).ready(function() {
  272. setTimeout(processTable, 1000);
  273.  
  274. // 监听页面变化
  275. const observer = new MutationObserver(function(mutations) {
  276. mutations.forEach(function(mutation) {
  277. if (mutation.addedNodes.length) {
  278. processTable();
  279. }
  280. });
  281. });
  282.  
  283. const tableContainer = document.querySelector('table.tablesorter');
  284. if (tableContainer) {
  285. observer.observe(tableContainer, {
  286. childList: true,
  287. subtree: true
  288. });
  289. }
  290. });
  291. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址