Chapter Downloader

Tự động lấy nội dung từ chương hiện tại đến hết tại truyen.tangthuvien.vn

  1. // ==UserScript==
  2. // @name Chapter Downloader
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.5
  5. // @description Tự động lấy nội dung từ chương hiện tại đến hết tại truyen.tangthuvien.vn
  6. // @author You
  7. // @match https://truyen.tangthuvien.vn/doc-truyen/*
  8. // @match https://truyen.tangthuvien.vn/doc-truyen/*/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. // ================= TẠO GIAO DIỆN =================
  16. const panel = document.createElement('div');
  17. panel.id = 'reader-panel';
  18. panel.style.cssText = `
  19. position: fixed;
  20. top: 10%;
  21. right: 10px;
  22. width: 300px;
  23. background-color: #f8f8f8;
  24. border: 1px solid #ccc;
  25. border-radius: 5px;
  26. padding: 10px;
  27. z-index: 9999;
  28. box-shadow: 0 0 10px rgba(0,0,0,0.2);
  29. font-family: Arial, sans-serif;
  30. `;
  31.  
  32. const textarea = document.createElement('textarea');
  33. textarea.id = 'content-textarea';
  34. textarea.style.cssText = `
  35. width: 100%;
  36. height: 300px;
  37. margin-bottom: 10px;
  38. padding: 8px;
  39. border: 1px solid #ddd;
  40. border-radius: 4px;
  41. resize: vertical;
  42. `;
  43.  
  44. const startButton = document.createElement('button');
  45. startButton.textContent = 'Bắt đầu';
  46. startButton.style.cssText = `
  47. width: 100%;
  48. padding: 8px;
  49. margin-bottom: 10px;
  50. background-color: #4CAF50;
  51. color: white;
  52. border: none;
  53. border-radius: 4px;
  54. cursor: pointer;
  55. `;
  56.  
  57. const clearButton = document.createElement('button');
  58. clearButton.textContent = 'Xoá';
  59. clearButton.style.cssText = `
  60. width: 49%;
  61. padding: 8px;
  62. margin-right: 2%;
  63. background-color: #f44336;
  64. color: white;
  65. border: none;
  66. border-radius: 4px;
  67. cursor: pointer;
  68. `;
  69.  
  70. const copyButton = document.createElement('button');
  71. copyButton.textContent = 'Sao Chép';
  72. copyButton.style.cssText = `
  73. width: 49%;
  74. padding: 8px;
  75. background-color: #9c27b0;
  76. color: white;
  77. border: none;
  78. border-radius: 4px;
  79. cursor: pointer;
  80. `;
  81.  
  82. panel.appendChild(textarea);
  83. panel.appendChild(startButton);
  84. panel.appendChild(clearButton);
  85. panel.appendChild(copyButton);
  86. document.body.appendChild(panel);
  87.  
  88. const saved = localStorage.getItem('chapterDownloaderContent');
  89. if (saved) textarea.value = saved;
  90.  
  91. function saveContent() {
  92. localStorage.setItem('chapterDownloaderContent', textarea.value);
  93. }
  94.  
  95. textarea.addEventListener('input', saveContent);
  96.  
  97. // ========== CẬP NHẬT PHẦN XỬ LÝ NỘI DUNG ==========
  98. function extractChapterContent() {
  99. const titleElement = document.querySelector('h2');
  100. const contentElement = document.querySelector('.box-chap');
  101. if (titleElement && contentElement) {
  102. const title = titleElement.innerText.trim();
  103. const content = contentElement.innerText
  104. .split('\n')
  105. .map(line => line.trim())
  106. .filter(line => line !== '' && !/^[-=_*]{3,}$/.test(line))
  107. .join('\n');
  108.  
  109. if (textarea.value) {
  110. textarea.value += '\n\n' + title + '\n' + content;
  111. } else {
  112. textarea.value = title + '\n' + content;
  113. }
  114. saveContent();
  115. return true;
  116. }
  117. return false;
  118. }
  119.  
  120. function goToNextChapter() {
  121. const next = document.querySelector('.bot-next_chap.bot-control') ||
  122. [...document.querySelectorAll('a[href*="chuong"]')].find(a =>
  123. /tiếp|sau|next/i.test(a.textContent));
  124. if (next) {
  125. next.click();
  126. return true;
  127. }
  128. return false;
  129. }
  130.  
  131. let isAutoDownloading = false;
  132.  
  133. startButton.addEventListener('click', () => {
  134. isAutoDownloading = !isAutoDownloading;
  135. if (isAutoDownloading) {
  136. localStorage.setItem('chapterDownloaderAuto', 'true');
  137. startButton.textContent = 'Dừng';
  138. startButton.style.backgroundColor = '#f44336';
  139. extractChapterContent();
  140. setTimeout(() => goToNextChapter(), 1000);
  141. } else {
  142. localStorage.setItem('chapterDownloaderAuto', 'false');
  143. startButton.textContent = 'Bắt đầu';
  144. startButton.style.backgroundColor = '#4CAF50';
  145. }
  146. });
  147.  
  148. clearButton.addEventListener('click', () => {
  149. textarea.value = '';
  150. saveContent();
  151. });
  152.  
  153. copyButton.addEventListener('click', () => {
  154. textarea.select();
  155. document.execCommand('copy');
  156. const notification = document.createElement('div');
  157. notification.textContent = 'Đã sao chép!';
  158. notification.style.cssText = `
  159. position: fixed;
  160. bottom: 20px;
  161. left: 50%;
  162. transform: translateX(-50%);
  163. background-color: rgba(0,0,0,0.8);
  164. color: white;
  165. padding: 10px 20px;
  166. border-radius: 4px;
  167. z-index: 10000;
  168. `;
  169. document.body.appendChild(notification);
  170. setTimeout(() => notification.remove(), 2000);
  171. });
  172.  
  173. // Khôi phục trạng thái auto sau khi load trang mới
  174. window.addEventListener('load', () => {
  175. const shouldContinue = localStorage.getItem('chapterDownloaderAuto') === 'true';
  176. if (shouldContinue) {
  177. setTimeout(() => {
  178. extractChapterContent();
  179. setTimeout(() => goToNextChapter(), 1000);
  180. }, 1000);
  181. }
  182. });
  183.  
  184. console.log('✅ Chapter Downloader Auto script loaded');
  185. })();