Gazelle文件数统计

显示torrent文件里有几首歌曲或几个文件.

  1. // ==UserScript==
  2. // @name Gazelle : File Count
  3. // @name:zh Gazelle文件数统计
  4. // @name:zh-CN Gazelle文件数统计
  5. // @name:zh-TW Gazelle文件數統計
  6. // @namespace notwhat/ops/lztr/red/DIC
  7. // @description Shows the number of tracks and/or files in each torrent
  8. // @description:zh 显示torrent文件里有几首歌曲或几个文件.
  9. // @description:zh-CN 显示torrent文件里有几首歌曲或几个文件.
  10. // @description:zh-TW 顯示torrent文件裡有幾首歌曲或幾個文件.
  11. // @version 2.0.0
  12. // @match https://notwhat.cd/torrents.php*id=*
  13. // @match https://orpheus.network/torrents.php*id=*
  14. // @match https://lztr.me/torrents.php*id=*
  15. // @match https://redacted.ch/torrents.php*id=*
  16. // @match https://dicmusic.club/torrents.php*id=*
  17. // @grant none
  18. // ==/UserScript==
  19.  
  20.  
  21. // _____________________________________________________________
  22. // _____________ Preferences ___________________________________
  23.  
  24.  
  25. // How to display the file count:
  26.  
  27. // 1 = Total number of files in torrent (15)
  28. // 2 = Number of tracks out of total files (12/15)
  29. // 3 = Number of tracks plus extra files (12+3)
  30. // 4 = Only the number of tracks (12)
  31.  
  32. var display = 3;
  33.  
  34.  
  35.  
  36. // Highlight editions with conflicting track counts:
  37.  
  38. var checkEditions = true;
  39.  
  40.  
  41.  
  42. // Highlight torrents with extra files (usually artwork)
  43. // exceeding this size (in MB; 0 = disable):
  44.  
  45. var extraSizeLimit = 40;
  46.  
  47.  
  48.  
  49. // Always show the size of extras when hovering over a
  50. // torrent size (false = only the highlighted ones):
  51.  
  52. var tooltipAll = false;
  53.  
  54.  
  55. // _____________________________________________________________
  56. // __________ End of Preferences _______________________________
  57.  
  58.  
  59.  
  60.  
  61. function toBytes(size) {
  62. var num = parseFloat(size.replace(',', ''));
  63. var i = ' KMGT'.indexOf(size.charAt(size.length-2));
  64. return Math.round(num * Math.pow(1024, i));
  65. }
  66.  
  67.  
  68. function toSize(bytes) {
  69. if (bytes <= 0) return '0 B';
  70. var i = Math.floor(Math.log(bytes) / Math.log(1024));
  71. var num = Math.round(bytes / Math.pow(1024, i));
  72. return num + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];
  73. }
  74.  
  75.  
  76. function addStyle(css) {
  77. var s = document.createElement('style');
  78. s.type = 'text/css';
  79. s.textContent = css;
  80. document.head.appendChild(s);
  81. }
  82.  
  83.  
  84. function setTitle(elem, str) {
  85. elem.title = str;
  86. if (window.jQuery && jQuery.fn.tooltipster) {
  87. jQuery(elem).tooltipster({ delay: 500, maxWidth: 400 });
  88. }
  89. }
  90.  
  91.  
  92.  
  93. var table = document.getElementById('torrent_details');
  94. if (table) {
  95.  
  96. var isMusic = !!document.querySelector('.box_artists');
  97. extraSizeLimit = extraSizeLimit * 1048576;
  98.  
  99. addStyle(
  100. '.gmfc_files { cursor: pointer; }' +
  101. '.gmfc_extrasize { background-color: rgba(228, 169, 29, 0.12) !important; }'
  102. );
  103.  
  104.  
  105. table.rows[0].insertCell(1).innerHTML = '<strong>文件数量</strong>';
  106.  
  107. var rows = table.querySelectorAll('.edition, .torrentdetails');
  108. for (var i = rows.length; i--; ) {
  109. ++rows[i].cells[0].colSpan;
  110. }
  111.  
  112.  
  113. rows = table.getElementsByClassName('torrent_row');
  114. var editions = {};
  115.  
  116. for (var i = rows.length; i--; ) {
  117.  
  118. var fileRows = rows[i].nextElementSibling.
  119. querySelectorAll('.filelist_table tr:not(:first-child)');
  120. var numFiles = fileRows.length;
  121. var numTracks = 0;
  122.  
  123. if (isMusic) {
  124. var extraSize = 0;
  125.  
  126. for (var j = numFiles; j--; ) {
  127. if (/\.(flac|mp3|m4a|ac3|dts)\s*$/i.test(fileRows[j].cells[0].textContent)) {
  128. ++numTracks;
  129. } else if (extraSizeLimit || tooltipAll) {
  130. extraSize += toBytes(fileRows[j].cells[1].textContent);
  131. }
  132. }
  133.  
  134. if (checkEditions) {
  135. var ed = /edition_\d+/.exec(rows[i].className)[0];
  136. editions[ed] = ed in editions && editions[ed] !== numTracks ? -1 : numTracks;
  137. }
  138.  
  139. var largeExtras = extraSizeLimit && extraSize > extraSizeLimit;
  140. if (largeExtras || tooltipAll) {
  141. var sizeCell = rows[i].cells[1];
  142. setTitle(sizeCell, 'Extras: ' + toSize(extraSize));
  143. if (largeExtras) {
  144. sizeCell.classList.add('gmfc_extrasize');
  145. }
  146. }
  147.  
  148. } else {
  149. display = 0;
  150. }
  151.  
  152. var cell = rows[i].insertCell(1);
  153. cell.textContent = display < 2 ? numFiles : numTracks;
  154. cell.className = 'gmfc_files';
  155. if (display != 3) {
  156. cell.className += ' number_column';
  157. } else {
  158. var numExtras = numFiles - numTracks;
  159. if (numExtras) {
  160. var sml = document.createElement('small');
  161. sml.textContent = '+' + numExtras;
  162. cell.appendChild(sml);
  163. }
  164. }
  165. if (display == 2) {
  166. cell.textContent += '/' + numFiles;
  167. }
  168.  
  169. }
  170.  
  171.  
  172. if (checkEditions) {
  173. var sel = '';
  174. for (var ed in editions) {
  175. if (editions.hasOwnProperty(ed) && editions[ed] < 1) {
  176. sel += [sel ? ',.' : '.', ed, '>.gmfc_files'].join('');
  177. }
  178. }
  179. if (sel) addStyle(sel + '{background-color: rgba(236, 17, 0, 0.09) !important;}');
  180. }
  181.  
  182.  
  183. // Show filelist on filecount click
  184.  
  185. table.addEventListener('click', function (e) {
  186.  
  187. function get(type) {
  188. return document.getElementById([type, id].join('_'));
  189. }
  190.  
  191. var elem = e.target.nodeName != 'SMALL' ? e.target : e.target.parentNode;
  192. if (elem.classList.contains('gmfc_files')) {
  193.  
  194. var id = elem.parentNode.id.replace('torrent', '');
  195. var tEl = get('torrent');
  196. var fEl = get('files');
  197. var show = [tEl.className, fEl.className].join().indexOf('hidden') > -1;
  198.  
  199. tEl.classList[show ? 'remove' : 'add']('hidden');
  200. fEl.classList[show ? 'remove' : 'add']('hidden');
  201.  
  202. if (show) {
  203. var sections = ['peers', 'downloads', 'snatches', 'reported', 'logs'];
  204. for (var i = sections.length; i--; ) {
  205. var el = get(sections[i]);
  206. if (el) el.classList.add('hidden');
  207. }
  208. }
  209.  
  210. }
  211. }, false);
  212.  
  213. }