Koharu Artist URL Collector

Collect URLs from koharu.to artist pages and store them in GM_storage

17.08.2024 itibariyledir. En son verisyonu görün.

  1. // ==UserScript==
  2. // @name Koharu Artist URL Collector
  3. // @namespace https://koharu.to/
  4. // @version 1.7
  5. // @description Collect URLs from koharu.to artist pages and store them in GM_storage
  6. // @license MIT
  7. // @author viatana35
  8. // @match https://koharu.to/?s=artist*
  9. // @match https://koharu.to/?s=circle*
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_deleteValue
  13. // @grant GM_download
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. 'use strict';
  18.  
  19. const urlKey = 'koharuUrls';
  20. const continueKey = 'continue_treatment';
  21. const artistsLibKey = 'artists_lib';
  22. let urlList = GM_getValue(urlKey, []);
  23. let continueTreatment = GM_getValue(continueKey, false);
  24. let artistsLib = GM_getValue(artistsLibKey, []);
  25.  
  26. // Function to process the current page and store English articles
  27. function processPage() {
  28. const articles = document.querySelectorAll('article');
  29. articles.forEach(article => {
  30. const isEnglish = article.querySelector('a > header > h3 > span > svg[id="flag-icons-gb"]');
  31. if (isEnglish) {
  32. const articleUrl = article.querySelector('a').href;
  33. if (!urlList.includes(articleUrl)) {
  34. urlList.push(articleUrl);
  35. }
  36. }
  37. });
  38.  
  39. // Save the updated URL list
  40. GM_setValue(urlKey, urlList);
  41. }
  42.  
  43. // Function to navigate to the next page
  44. function goToNextPage() {
  45. const paginationList = document.querySelector('footer nav.pagination ul');
  46. if (paginationList) {
  47. const paginationItems = paginationList.children;
  48. const lastItem = paginationItems[paginationItems.length - 1]; // On prend le dernier élément de la liste
  49.  
  50. const nextPageLink = lastItem.querySelector('a');
  51. if (nextPageLink) {
  52. const currentPageNumber = parseInt(new URL(window.location.href).searchParams.get('page') || '1', 10);
  53. const nextPageNumber = parseInt(new URL(nextPageLink.href).searchParams.get('page'), 10);
  54.  
  55. if (nextPageNumber === currentPageNumber + 1) {
  56. console.log(currentPageNumber, "->", nextPageNumber);
  57. GM_setValue(continueKey, true);
  58. window.location.href = nextPageLink.href;
  59. } else {
  60. console.log("end of treatment");
  61. saveArtistData();
  62. GM_setValue(continueKey, false); // Pas de page suivante
  63. }
  64. } else {
  65. saveArtistData();
  66. GM_setValue(continueKey, false); // Pas de lien pour la page suivante
  67. }
  68. }
  69. else
  70. {
  71. console.log("end of treatment");
  72. saveArtistData();
  73. GM_setValue(continueKey, false); // Pas de page suivante
  74. }
  75. }
  76.  
  77. function treatArtist() {
  78. // If there is no pagination list, check if the URL contains "&page"
  79. const urlParams = new URLSearchParams(window.location.search);
  80. if (urlParams.has('page')) {
  81. showPopup("please go to page one to treat artist");
  82. } else {
  83. console.log("beginning of the treatment");
  84. processPage();
  85. goToNextPage();
  86. }
  87. }
  88.  
  89.  
  90.  
  91. // Function to get the artist's name
  92. function getArtistName() {
  93. const artistElement = document.querySelector('span span.ns-artist');
  94.  
  95. if (artistElement) {
  96. const artistNameElement = artistElement.parentNode.querySelector('span.val');
  97.  
  98. if (artistNameElement) {
  99. return artistNameElement.textContent.trim();
  100. }
  101. }
  102.  
  103. return null;
  104. }
  105.  
  106. function showPopup(message) {
  107. const popup = document.createElement('div');
  108. popup.id = 'popup';
  109. popup.style.position = 'fixed';
  110. popup.style.top = '50%';
  111. popup.style.left = '50%';
  112. popup.style.transform = 'translate(-50%, -50%)';
  113. popup.style.backgroundColor = '#f1f1f1';
  114. popup.style.padding = '20px';
  115. popup.style.border = '1px solid #ccc';
  116. popup.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
  117. popup.style.zIndex = '1001';
  118. popup.style.textAlign = 'center';
  119. popup.style.opacity = '0';
  120. popup.style.transition = 'opacity 0.3s ease-in-out';
  121. popup.textContent = message;
  122.  
  123. document.body.appendChild(popup);
  124.  
  125. // Fade in the popup
  126. setTimeout(() => {
  127. popup.style.opacity = '1';
  128. }, 10);
  129.  
  130. // Fade out and remove the popup after 5 seconds
  131. setTimeout(() => {
  132. popup.style.opacity = '0';
  133. setTimeout(() => {
  134. document.body.removeChild(popup);
  135. }, 300);
  136. }, 5000);
  137. }
  138.  
  139.  
  140.  
  141. // Function to save the current artist's data
  142. function saveArtistData() {
  143. const artistName = getArtistName();
  144. if (artistName && urlList.length > 0) {
  145. const artistData = {
  146. artist: artistName,
  147. lst_dl: urlList
  148. };
  149.  
  150. // Add the artist data to the artistsLib
  151. artistsLib.push(artistData);
  152.  
  153. // Save the updated artistsLib
  154. GM_setValue(artistsLibKey, artistsLib);
  155.  
  156. // Clear the URL list for the next artist
  157. GM_setValue(urlKey, []);
  158. urlList = [];
  159.  
  160. showPopup(`Artist ${artistName} has been processed.`);
  161.  
  162. clearButton.disabled = false;
  163.  
  164. }
  165. }
  166.  
  167. // Function to handle automatic processing if continue_treatment is true
  168. function handleAutoProcessing() {
  169. console.log(continueTreatment);
  170. if (continueTreatment) {
  171. processPage();
  172. goToNextPage();
  173. }
  174. }
  175.  
  176. // Function to download the artists_lib as a JSON file
  177. function downloadArtistsLib() {
  178. const artistsLibData = GM_getValue(artistsLibKey, []);
  179. const jsonContent = JSON.stringify(artistsLibData, null, 2); // Pretty print JSON with indentation
  180. const blob = new Blob([jsonContent], { type: 'application/json' });
  181. const url = URL.createObjectURL(blob);
  182.  
  183. const a = document.createElement('a');
  184. a.href = url;
  185. a.download = 'artists_lib.json';
  186. a.click();
  187.  
  188. URL.revokeObjectURL(url); // Clean up the URL object
  189. }
  190.  
  191. // Create a container for the buttons
  192. const buttonContainer = document.createElement('div');
  193. buttonContainer.style.position = 'sticky';
  194. buttonContainer.style.top = '0';
  195. buttonContainer.style.backgroundColor = '#f1f1f1';
  196. buttonContainer.style.padding = '10px';
  197. buttonContainer.style.zIndex = 1000;
  198. buttonContainer.style.display = 'flex';
  199. buttonContainer.style.justifyContent = 'center';
  200. buttonContainer.style.alignItems = 'center';
  201. document.body.prepend(buttonContainer);
  202.  
  203. // Create a button to process the artist's pages
  204. const processButton = document.createElement('button');
  205. processButton.textContent = 'Traiter l\'artiste';
  206. processButton.style.margin = '0 10px';
  207. processButton.style.padding = '10px';
  208. processButton.style.backgroundColor = '#4CAF50';
  209. processButton.style.color = 'white';
  210. processButton.style.border = 'none';
  211. processButton.style.cursor = 'pointer';
  212. processButton.onclick = () => {
  213. GM_setValue(continueKey, true);
  214. treatArtist();
  215. };
  216. buttonContainer.appendChild(processButton);
  217.  
  218. // Create a button to clear the list and artists_lib
  219. const clearButton = document.createElement('button');
  220. clearButton.textContent = 'Clear list';
  221. clearButton.style.margin = '0 10px';
  222. clearButton.style.padding = '10px';
  223. clearButton.style.backgroundColor = '#f44336';
  224. clearButton.style.color = 'white';
  225. clearButton.style.border = 'none';
  226. clearButton.style.cursor = 'pointer';
  227. clearButton.disabled = artistsLib.length === 0;
  228. clearButton.onclick = () => {
  229. if (confirm('Do you really want to clear the list ?')) {
  230. GM_deleteValue(urlKey);
  231. GM_deleteValue(artistsLibKey);
  232. urlList = [];
  233. artistsLib = [];
  234. clearButton.disabled = true;
  235. showPopup("list cleared");
  236. }
  237. };
  238. buttonContainer.appendChild(clearButton);
  239.  
  240. // Create a button to download the artists_lib JSON
  241. const downloadButton = document.createElement('button');
  242. downloadButton.textContent = 'Download the lsit';
  243. downloadButton.style.margin = '0 10px';
  244. downloadButton.style.padding = '10px';
  245. downloadButton.style.backgroundColor = '#2196F3';
  246. downloadButton.style.color = 'white';
  247. downloadButton.style.border = 'none';
  248. downloadButton.style.cursor = 'pointer';
  249. downloadButton.onclick = downloadArtistsLib;
  250. buttonContainer.appendChild(downloadButton);
  251.  
  252. // Enable the clear button if the list contains elements
  253. if (artistsLib.length > 0) {
  254. clearButton.disabled = false;
  255. }
  256.  
  257. // Wait for DOM to fully load before executing handleAutoProcessing
  258. window.onload = () => {
  259. handleAutoProcessing();
  260. };
  261.  
  262. })();