fc2 show all products

show full list of products in 1 page and sort by id / show full title

As of 13.02.2021. See ბოლო ვერსია.

  1. // ==UserScript==
  2. // @name fc2 show all products
  3. // @namespace https://github.com/x94fujo6rpg/SomeTampermonkeyScripts
  4. // @version 0.2
  5. // @description show full list of products in 1 page and sort by id / show full title
  6. // @author x94fujo6
  7. // @match https://adult.contents.fc2.com/*
  8. // @grant none
  9. // ==/UserScript==
  10. /* jshint esversion: 9 */
  11.  
  12. (function () {
  13. 'use strict';
  14. let msgid = "fc2_script_message";
  15. let listener = false;
  16.  
  17. window.document.body.onload = () => {
  18. startScript();
  19. };
  20.  
  21. function dPrint(...any) {
  22. console.log(`[${msgid}]: `, ...any);
  23. }
  24.  
  25. function startScript() {
  26. if (document.visibilityState == "visible") {
  27. if (listener) {
  28. document.removeEventListener("visibilitychange", startScript);
  29. //dPrint("remove event listener");
  30. } else {
  31. //dPrint("normal start");
  32. }
  33. setReload();
  34. checkLink();
  35. } else {
  36. document.addEventListener("visibilitychange", startScript);
  37. //dPrint("document not visible, set event listener");
  38. listener = true;
  39. }
  40. }
  41.  
  42. function setReload() {
  43. let menu = document.querySelector("[data-menulist]");
  44. if (!menu) return;
  45. let links = menu.querySelectorAll("a");
  46. links.forEach(a => {
  47. if (a.getAttribute("reload")) return;
  48. a.onclick = (event) => {
  49. event.preventDefault();
  50. document.location.href = a.href;
  51. };
  52. a.setAttribute("reload", true);
  53. });
  54. }
  55.  
  56. function checkLink() {
  57. let link = document.location.href;
  58. //dPrint(`link: ${link}`);
  59. if (link.match(/users\/[^\/]+\/articles\?sort=date&order=desc/)) {
  60. let regtest = link.match(/page=(\d+)/);
  61. let page = regtest ? regtest[1] : false;
  62. if (regtest) page = (page == 1) ? true : false;
  63. if (!regtest || page) {
  64. dPrint("listview");
  65. dPrint(`script start, link: ${link}`);
  66. sortList();
  67. }
  68. } else if (link.match(/article_search.php\?id=\d+/) || link.match(/\/article\/\d+\//)) {
  69. dPrint("productpage");
  70. productpage();
  71. }
  72. }
  73.  
  74. function updateMessage(text = "") {
  75. document.getElementById(msgid).textContent = text;
  76. dPrint(text);
  77. }
  78.  
  79. function sortList() {
  80. let pos = document.querySelector("section.seller_user_articlesList");
  81. if (!pos) return;
  82.  
  83. let products = [...pos.children];
  84. let list = products.map(div => processDiv(div));
  85.  
  86. document.querySelector(".c-pager-101").remove();
  87. list.sort((a, b) => b.id - a.id);
  88.  
  89. products.forEach(e => e.remove());
  90. list.forEach(data => { pos.appendChild(data.ele); });
  91.  
  92. let message = Object.assign(document.createElement("span"), {
  93. id: msgid,
  94. textContent: "script start",
  95. style: `
  96. display: inline-block;
  97. margin: 0.5rem;
  98. color: gold;
  99. `,
  100. });
  101. document.querySelector("div.seller_user_articles_pageHeader").appendChild(message);
  102. getAllProduct();
  103.  
  104. async function getAllProduct() {
  105. let total = document.querySelector(".seller_user_articles_pageHeaderCount");
  106. if (!total) return;
  107. total = total.textContent.match(/\((\d*)\)/)[1];
  108. total = parseInt(total, 10);
  109.  
  110. let max_page = Math.ceil(total / 30);
  111. if (max_page == 1) {
  112. updateMessage(`only 1 page, abort`);
  113. } else {
  114. let user = document.location.href.match(/users\/([^\/]*)\/articles/)[1];
  115. let url = `https://adult.contents.fc2.com/users/${user}/articles?sort=date&order=desc&deal=&page=`;
  116. updateMessage(`max page = ${max_page}, start to retrieve data`);
  117.  
  118. for (let page = 2; page <= max_page; page++) {
  119. updateMessage(`processing... please wait [page: ${page}, total: ${max_page}]`);
  120. await getPage(url, page)
  121. .then(async (resolve) => {
  122. await resort(resolve, page);
  123. })
  124. .catch((reject) => {
  125. updateMessage(`somthing went wrong...script stopped`);
  126. dPrint(reject);
  127. return;
  128. });
  129. }
  130. }
  131. updateMessage(`done`);
  132.  
  133. function getPage(rq_url, page) {
  134. return new Promise((resolve, reject) => {
  135. let rq = new XMLHttpRequest();
  136. rq.open("GET", `${rq_url}${page}`);
  137. rq.onreadystatechange = function () {
  138. if (rq.readyState == 4) {
  139. return (rq.status == 200) ? setTimeout(resolve, 500, rq.responseText) : reject(rq.responseText);
  140. }
  141. };
  142. rq.send(null);
  143. });
  144. }
  145.  
  146. function resort(data) {
  147. return new Promise((resolve, reject) => {
  148. let current = getCurrentProduct();
  149. if (!current) return reject(false);
  150.  
  151. data = extractProducts(data);
  152. current.push(...data);
  153. current.sort((a, b) => b.id - a.id);
  154.  
  155. let pos = document.querySelector("section.seller_user_articlesList");
  156. [...pos.children].forEach(e => e.remove());
  157.  
  158. current.forEach(p => pos.appendChild(p.ele));
  159.  
  160. data = null;
  161. current = null;
  162. return resolve(true);
  163. });
  164.  
  165. function getCurrentProduct() {
  166. let pos = document.querySelector("section.seller_user_articlesList");
  167. if (pos) {
  168. return [...pos.children].map(ele => {
  169. return {
  170. id: ele.querySelector("a").href.match(/id=(\d*)/)[1],
  171. ele: ele.cloneNode(true),
  172. };
  173. });
  174. } else {
  175. return false;
  176. }
  177. }
  178.  
  179. function extractProducts(domtext) {
  180. let parser = new DOMParser();
  181. let new_document = parser.parseFromString(domtext, "text/html");
  182. let pos = new_document.querySelector("section.seller_user_articlesList");
  183. let products = [...pos.children];
  184. let list = products.map(div => processDiv(div));
  185. parser = null; // release memory
  186. new_document = null;
  187. return list;
  188. }
  189. }
  190. }
  191. }
  192.  
  193. function processDiv(div) {
  194. let id = div.querySelector("a").href.match(/id=(\d*)/)[1];
  195. let box = div.querySelector(".c-cntCard-110-f_indetail");
  196. let title_ele = div.querySelector(".c-cntCard-110-f_itemName");
  197. let title_span = convertToSpan(title_ele);
  198. let id_span = Object.assign(document.createElement("span"), {
  199. textContent: id,
  200. style: `font-size: 1.5rem;`,
  201. });
  202. box.insertAdjacentElement("afterbegin", title_span);
  203. box.insertAdjacentElement("afterbegin", id_span);
  204. title_ele.remove();
  205.  
  206. div.querySelector("img").setAttribute("loading", "lazy");
  207. div.querySelector(".items_article_SmapleVideo").remove(); //heavy element
  208.  
  209. div.querySelector("span.c-cntCard-110-f_thumb_type").remove();
  210. div.querySelector("button").remove();
  211. div.querySelector("section.c-tooltip-107").remove();
  212.  
  213. //div.querySelector(".detail-layout").remove();
  214. div.querySelector(".c-cntCard-110-f_seller").remove();
  215.  
  216. let all_link = div.querySelectorAll("a");
  217. if (all_link) all_link.forEach(a => { a.target = "_blank"; });
  218. return { id: id, ele: div.cloneNode(true) };
  219.  
  220. function convertToSpan(ele) {
  221. return Object.assign(document.createElement("span"), {
  222. textContent: ele.textContent,
  223. className: ele.className,
  224. style: `
  225. overflow: visible;
  226. display: inline-block;
  227. width: auto;
  228. `,
  229. });
  230. }
  231. }
  232.  
  233. function productpage() {
  234. let data = document.querySelector("[type='application/ld+json']").textContent;
  235. data = JSON.parse(data);
  236. let id = data.productID;
  237. let title = data.name;
  238. let pos = document.querySelector(".items_article_headerInfo h3");
  239. let e = newButton(`Copy [${id} ${title}]`, `${id} ${title}`);
  240. pos.insertAdjacentElement("afterend", e);
  241. }
  242.  
  243. function newButton(text, copy) {
  244. let e = document.createElement("a");
  245. e.style = "color: deeppink; font-size: 1.5rem;";
  246. e.textContent = text;
  247. e.onclick = function () {
  248. navigator.clipboard.writeText(repalceForbiddenChar(copy));
  249. };
  250. return e;
  251. }
  252.  
  253. function repalceForbiddenChar(string = "") {
  254. let forbidden = `<>:"/|?*\\`;
  255. let replacer = `<>:”/|?*\`;
  256. for (let index of forbidden) {
  257. string = string.replaceAll(forbidden[index], replacer[index]);
  258. }
  259. return string.trim();
  260. }
  261. })();