Fsm to qBittorrent

推送种子

  1. // ==UserScript==
  2. // @name Fsm to qBittorrent
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description 推送种子
  6. // @author LEIHOU
  7. // @match https://fsm.name/Torrents*
  8. // @grant GM_xmlhttpRequest
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. const qbittorrentUrl = 'http://IP:PORT';//修改替换
  15. const username = 'admin';//修改替换
  16. const password = 'adminadmin';//修改替换
  17.  
  18. // Function to add torrent to qBittorrent
  19. function addToqBittorrent(url) {
  20. // Construct the API endpoint to add torrent
  21. const apiUrl = `${qbittorrentUrl}/api/v2/torrents/add`;
  22.  
  23. // Prepare data to send
  24. const data = `urls=${encodeURIComponent(url)}`;
  25.  
  26. // Prepare authentication header
  27. const auth = btoa(`${username}:${password}`);
  28.  
  29. // Send request to qBittorrent API using GM_xmlhttpRequest
  30. GM_xmlhttpRequest({
  31. method: 'POST',
  32. url: apiUrl,
  33. headers: {
  34. 'Authorization': `Basic ${auth}`,
  35. 'Content-Type': 'application/x-www-form-urlencoded'
  36. },
  37. data: data,
  38. onload: function(response) {
  39. if (response.status >= 200 && response.status < 300) {
  40. // Show success message
  41. showMessage('Successfully added to qBittorrent!', 'green');
  42. } else {
  43. // Show error message
  44. showMessage('Failed to add to qBittorrent. Please try again.', 'red');
  45. }
  46. },
  47. onerror: function(error) {
  48. console.error('Error:', error);
  49. // Show error message
  50. showMessage('An error occurred. Please check console logs.', 'red');
  51. }
  52. });
  53. }
  54.  
  55. // Function to create push download button
  56. function createPushDownloadButton(downloadButton) {
  57. const pushDownloadButton = document.createElement('button');
  58. pushDownloadButton.setAttribute('type', 'button');
  59. pushDownloadButton.setAttribute('aria-disabled', 'false');
  60. pushDownloadButton.classList.add('el-button', 'el-button--primary', 'is-plain', 'is-circle');
  61. pushDownloadButton.style.marginRight = '10px';
  62.  
  63. const iconSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  64. iconSvg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
  65. iconSvg.setAttribute('viewBox', '0 0 1024 1024');
  66.  
  67. const iconPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  68. iconPath.setAttribute('fill', 'currentColor');
  69. iconPath.setAttribute('d', 'M104.704 685.248a64 64 0 0 0 90.496 0l316.8-316.8 316.8 316.8a64 64 0 0 0 90.496-90.496L557.248 232.704a64 64 0 0 0-90.496 0L104.704 594.752a64 64 0 0 0 0 90.496z');
  70.  
  71. iconSvg.appendChild(iconPath);
  72. pushDownloadButton.appendChild(iconSvg);
  73.  
  74. pushDownloadButton.addEventListener('click', function() {
  75. const downloadUrl = downloadButton.href;
  76. console.log('Download URL:', downloadUrl);
  77. addToqBittorrent(downloadUrl);
  78. });
  79.  
  80. // Insert the push download button before the original download button
  81. downloadButton.parentNode.insertBefore(pushDownloadButton, downloadButton);
  82. }
  83.  
  84. // Function to show message
  85. function showMessage(message, color) {
  86. const messageBox = document.createElement('div');
  87. messageBox.textContent = message;
  88. messageBox.style.position = 'fixed';
  89. messageBox.style.top = '50%';
  90. messageBox.style.left = '50%';
  91. messageBox.style.transform = 'translate(-50%, -50%)';
  92. messageBox.style.background = color;
  93. messageBox.style.color = '#fff';
  94. messageBox.style.padding = '10px 20px';
  95. messageBox.style.borderRadius = '5px';
  96. messageBox.style.zIndex = '9999';
  97. document.body.appendChild(messageBox);
  98.  
  99. // Remove message box after 1 second
  100. setTimeout(function() {
  101. messageBox.remove();
  102. }, 1000);
  103. }
  104.  
  105. // Function to handle mutation events
  106. function handleMutations(mutationsList, observer) {
  107. for (let mutation of mutationsList) {
  108. if (mutation.type === 'childList') {
  109. mutation.addedNodes.forEach(node => {
  110. if (node.nodeType === Node.ELEMENT_NODE) {
  111. const downloadButton = node.querySelector('div.el-row.is-align-middle > div.el-col.el-col-2.el-col-xs-0.is-guttered.txt-right > div > div:nth-child(1) > a');
  112. if (downloadButton) {
  113. createPushDownloadButton(downloadButton);
  114. }
  115. }
  116. });
  117. }
  118. }
  119. }
  120.  
  121. // Start observing mutations on the target node
  122. const targetNode = document.querySelector('#app > div > section > main > div > div.el-col.el-col-24.el-col-xs-24.el-col-sm-20.el-col-md-18.el-col-lg-18.el-col-xl-18');
  123. if (targetNode) {
  124. const observer = new MutationObserver(handleMutations);
  125. observer.observe(targetNode, { childList: true, subtree: true });
  126. } else {
  127. console.error('Target node not found!');
  128. }
  129. })();