For each artwork on Pixiv, show the request price if available and sort artworks by price.
- // ==UserScript==
- // @name Pixiv Show Request Price
- // @author MahdeenSky
- // @namespace http://tampermonkey.net/
- // @version 1.0
- // @description For each artwork on Pixiv, show the request price if available and sort artworks by price.
- // @match https://www.pixiv.net/request/creators/works/illust
- // @match https://www.pixiv.net/request/creators/works/illust?*
- // @match https://www.pixiv.net/bookmark_new_illust.php
- // @match https://www.pixiv.net/discovery
- // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
- // @grant none
- // @license GNU GPLv3
- // ==/UserScript==
- (function () {
- "use strict";
- const button = document.createElement("button");
- button.innerText = "Show Request Price (0/0)";
- button.style.position = "fixed";
- button.style.bottom = "10px";
- button.style.left = "10px";
- button.style.zIndex = "9999";
- button.style.padding = "10px";
- button.style.backgroundColor = "blue";
- button.style.color = "white";
- button.style.border = "none";
- button.style.borderRadius = "5px";
- button.style.cursor = "pointer";
- document.body.appendChild(button);
- const sortButton = document.createElement("button");
- sortButton.innerText = "Sort by Price";
- sortButton.style.position = "fixed";
- sortButton.style.bottom = "50px";
- sortButton.style.left = "10px";
- sortButton.style.zIndex = "9999";
- sortButton.style.padding = "10px";
- sortButton.style.backgroundColor = "green";
- sortButton.style.color = "white";
- sortButton.style.border = "none";
- sortButton.style.borderRadius = "5px";
- sortButton.style.cursor = "pointer";
- document.body.appendChild(sortButton);
- const MAX_PARALLEL_IFRAMES = 2;
- let activeIframes = 0;
- let globalIndex = 0;
- let artistUrls = [];
- let artworks = [];
- let updatedCount = 0;
- function updateButtonText() {
- button.innerText = `Show Request Price (${updatedCount}/${artworks.length})`;
- }
- function waitForRequestPriceElement(wrapperDiv, iframe, artistUrl, artwork) {
- iframe.addEventListener('load', () => {
- let requestPriceElement = iframe.contentDocument.querySelector("p.sc-a5e65548-7");
- if (requestPriceElement) {
- const requestPrice = requestPriceElement.innerText;
- console.log(
- "######################## " +
- artistUrl +
- " ##############" +
- requestPrice
- );
- const priceElement = document.createElement("div");
- priceElement.classList.add("request-price");
- priceElement.innerText = `Request Price: ${requestPrice}`;
- priceElement.style.backgroundColor = "#f0f0f0";
- priceElement.style.color = "#333";
- priceElement.style.padding = "10px";
- priceElement.style.marginBottom = "10px";
- priceElement.style.border = "1px solid #ccc";
- priceElement.style.borderRadius = "5px";
- priceElement.style.fontSize = "14px";
- priceElement.style.fontWeight = "bold";
- priceElement.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.1)";
- priceElement.style.opacity = "0";
- priceElement.style.transition = "opacity 0.5s ease-in-out";
- artwork.insertBefore(priceElement, artwork.firstChild);
- requestAnimationFrame(() => {
- priceElement.style.opacity = "1";
- });
- updatedCount++;
- updateButtonText();
- } else {
- console.log("Request price element not found, skipping...");
- }
- activeIframes--;
- console.log("Active iframes after decrement: " + activeIframes);
- processArtist();
- // reload the iframe then remove the wrapper div
- iframe.src = "about:blank";
- wrapperDiv.innerHTML = "<iframe style='display: none;'></iframe>";
- setTimeout(() => {
- wrapperDiv.remove();
- }, 1000);
- });
- }
- function processArtist() {
- if (globalIndex >= artistUrls.length) {
- console.log("All artists processed");
- return; // All artists processed
- }
- if (activeIframes >= MAX_PARALLEL_IFRAMES) {
- console.log("Max parallel iframes reached, retrying...");
- setTimeout(processArtist, 100); // Retry after 100ms
- return;
- }
- activeIframes++;
- console.log("Processing " + artistUrls[globalIndex]);
- const artistUrl = artistUrls[globalIndex];
- const artwork = artworks[globalIndex];
- const wrapperDiv = document.createElement("div");
- const iframe = document.createElement("iframe");
- iframe.style.display = "none";
- iframe.src = artistUrl + "/request";
- console.log("Visiting " + iframe.src);
- globalIndex++;
- wrapperDiv.appendChild(iframe);
- document.body.appendChild(wrapperDiv);
- waitForRequestPriceElement(wrapperDiv, iframe, artistUrl, artwork);
- }
- function scrapeArtworks() {
- // do a case by case check for different kind of css selectors for artworks
- const selectors = ["li.PKpFw", "li.kFAPOq"];
- let selector = null;
- if (document.querySelector(selectors[0])) {
- selector = selectors[0];
- } else if (document.querySelector(selectors[1])) {
- selector = selectors[1];
- } else {
- console.error("No artworks found");
- return { artistUrls: [], artworks: [] };
- }
- const artworks = document.querySelectorAll(selector);
- const artistUrls = [];
- artworks.forEach((artwork) => {
- // Check if the artwork already has the price element with the class "request-price"
- const existingPriceElement = artwork.querySelector('.request-price');
- if (existingPriceElement) {
- return; // Skip this artwork if it already has the price
- }
- let selector = "a.sc-1rx6dmq-2";
- if (document.querySelector("a.pPtWa")) {
- selector = "a.pPtWa";
- }
- const artistLink = artwork.querySelector(selector);
- const artistUrl = artistLink.href;
- artistUrls.push(artistUrl);
- });
- return { artistUrls, artworks };
- }
- function getPrices() {
- let scrapedData = scrapeArtworks();
- artistUrls = scrapedData.artistUrls;
- artworks = scrapedData.artworks;
- updateButtonText(); // Update button text with initial counts
- // Start processing up to MAX_PARALLEL_IFRAMES artists initially
- for (let i = 0; i < MAX_PARALLEL_IFRAMES; i++) {
- setTimeout(processArtist, 300 * i);
- }
- }
- function sortArtworksByPrice() {
- const artworksContainer = document.querySelector("ul.sc-e6de33c8-0");
- const artworksArray = Array.from(document.querySelectorAll("li.sc-9111aad9-0"));
- const sortedArtworks = artworksArray.sort((a, b) => {
- const priceA = parseFloat(a.querySelector(".request-price").innerText.replace(/[^0-9.-]+/g, ""));
- const priceB = parseFloat(b.querySelector(".request-price").innerText.replace(/[^0-9.-]+/g, ""));
- return priceA - priceB;
- });
- sortedArtworks.forEach((artwork) => {
- artworksContainer.appendChild(artwork);
- });
- }
- button.addEventListener("click", getPrices);
- sortButton.addEventListener("click", sortArtworksByPrice);
- })();