EHMassTorrent

Mass mirror EH torrents

  1. // ==UserScript==
  2. // @name EHMassTorrent
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Mass mirror EH torrents
  6. // @author ez
  7. // @match https://e-hentai.org/?*f_search=*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. var slack = 0.9;
  13. var seedtrump = 1.5;
  14. var minseeds = 2;
  15. var maxseeds = 15;
  16. function gid(n) {
  17. return document.getElementById(n);
  18. }
  19. function gcls(n) {
  20. return document.getElementsByClassName(n);
  21. }
  22. function fget(n, def) {
  23. var v = gid(n).value || sessionStorage.getItem(n) || def;
  24. if (def !== undefined) {
  25. gid(n).value = v;
  26. }
  27. sessionStorage.setItem(n, v);
  28. return v;
  29. }
  30. function fset(n, v) {
  31. if (v === undefined) {
  32. v = fget(n);
  33. }
  34. gid(n).value = v;
  35. sessionStorage.setItem(n,v);
  36. }
  37. document.getElementById('dms').insertAdjacentHTML('afterbegin',`
  38. <table>
  39. <tr>
  40. <td>Next delay<td><input type=text id="nd" style="width: 30px;"></input>
  41. <td>Num pages<td><input type=text id="np" style="width: 30px;"></input>
  42. <td>Pos<td><input type=text id="pos" style="width: 30px;"></input>/<td id=pcnt></td>
  43. <td><button id="mstart">Start</button>
  44. <td id=stat>
  45. </table>`);
  46. fget('nd', 8000);
  47. fget('np', 0);
  48. fget('pos', 0);
  49. var isRunning = false;
  50. var startPos = 0;
  51. gid('mstart').addEventListener('click', function() {
  52. if (!isRunning) {
  53. startRunning();
  54. } else {
  55. stopRunning();
  56. }
  57. });
  58. var children = gcls('gldown');
  59. gid('pcnt').innerText = children.length;
  60. var stat = gid('stat');
  61. var pos;
  62. var prev;
  63. function startRunning() {
  64. sessionStorage.setItem('forceStart', 0);
  65. pos = fget('pos', 0);
  66. function progress() {
  67. if (prev) {
  68. prev.style.backgroundColor = '';
  69. }
  70. if (!isRunning) {
  71. return;
  72. }
  73. var dl = children[pos];
  74. var np = fget('np')|0;
  75. // we're out. browse to next page, or stop if numpages goes to 0
  76. if (np <= 0 || dl === undefined) {
  77. var newLoc = document.getElementsByClassName('ptt')[0].firstChild.firstChild.lastChild.firstChild.href;
  78. if (np <= 1 || !newLoc) {
  79. fset('np', 0);
  80. fset('pos', 0);
  81. stat.innerText = "No more pages requested, halted.";
  82. stopRunning();
  83. return;
  84. }
  85. stat.innerText = "About to jump to next next page...";
  86. setTimeout(function() {
  87. fset('np', np-1);
  88. fset('pos', 0);
  89. sessionStorage.setItem('forceStart', 1);
  90. document.location = newLoc;
  91. }, Math.random() * (fget('nd')|0) + (fget('nd')|0));
  92. return;
  93. }
  94. var parent = dl.parentNode.parentNode;
  95. prev = parent;
  96. parent.style.backgroundColor = '#886';
  97. var url = dl.firstChild.href;
  98. if (!url || localStorage.getItem(url)=="1") {
  99. console.log(url + " is already known or has no torrents; skipping");
  100. pos++;
  101. fset('pos',pos);
  102. setTimeout(progress, 0);
  103. return;
  104. }
  105.  
  106. var iframe = document.createElement('iframe');
  107. iframe.src = url;
  108. iframe.style.visibility = "hidden";
  109. iframe.style.width = 0;
  110. iframe.style.height = 0;
  111. iframe.style.border = "0 none";
  112. iframe.style.position = "absolute";
  113. iframe.onload = function() {
  114. stat.innerText = "Loaded iframe, fetching torrent";
  115. var forms = iframe.contentDocument.getElementsByTagName('form');
  116. var tuples = [];
  117. var best = -1;
  118. var bestseeds = 0;
  119. var i;
  120. for (i = 0; i < forms.length-1; i++) {
  121. var td = forms[i].getElementsByTagName('td');
  122. var dfunc = td[8].getElementsByTagName('a')[0].href;
  123. var seeds = td[3].innerText.split(':')[1].substr(1)|0;
  124. var size = eval(td[1].innerText.split(':')[1].replace('GB', '*1024*1024*1024').replace('MB', '*1024*1024').replace('KB','*1024').replace('B',''));
  125. tuples.push([dfunc,seeds,size]);
  126. // found larger torrent with some seeds
  127. if (seeds >= minseeds && (best == -1 || size > tuples[best][2])) {
  128. best = i;
  129. }
  130. if (tuples[bestseeds][1] < seeds) {
  131. bestseeds = i;
  132. }
  133. }
  134. // hm, the torrent is seed starved, so assign whatever we can have
  135. if (best == -1) {
  136. best = bestseeds;
  137. }
  138. var best2 = best;
  139. if (best != -1) {
  140. var bestt = tuples[best];
  141. // do this only if we're short on seeds
  142. if (bestt[1] < maxseeds) {
  143. // now scan tuples again. if they're smaller by 'slack' (90%), but have more seeds 'seedtrump' (150%) of best torrent, choose that one instead
  144. for (i = 0; i < tuples.length; i++) {
  145. if (tuples[i][2] > bestt[2] * slack && tuples[i][1] > bestt[1] * seedtrump) {
  146. // anything with most seeds fitting the base criteria above
  147. if (tuples[i][1] > tuples[best2][1]) {
  148. console.log("TRUMP",best2,"=>",i);
  149. best2 = i;
  150. }
  151. }
  152. }
  153. }
  154. // best2 is our final selection
  155. localStorage.setItem(url, "1");
  156. console.log("Downloading " + url + " torrent index " + best2);
  157. var durl = tuples[best2][0];
  158. document.location = durl;
  159. }
  160. document.body.removeChild(iframe);
  161. pos++;
  162. fset('pos',pos);
  163. setTimeout(progress, Math.random() * (fget('nd')|0) * 2 + 300);
  164. }
  165. stat.innerText = "Loading iframe for " + url;
  166. document.body.appendChild(iframe);
  167. };
  168. isRunning = true;
  169. gid('mstart').innerText = "Stop";
  170. progress();
  171. }
  172. function stopRunning() {
  173. sessionStorage.getItem('forceStart', 0)
  174. isRunning = false;
  175. gid('mstart').innerText = "Start";
  176. }
  177.  
  178. // Triggered by our forced 'next' click
  179. if (sessionStorage.getItem('forceStart')==1) {
  180. startRunning();
  181. }
  182. })();
  183.