JAVLib tag助手

鼠标悬停在javLibrary图片上时显示该视频类型。

// ==UserScript==
// @name        JAVLib tag助手
// @namespace   JAVLib tag助手
// @description 鼠标悬停在javLibrary图片上时显示该视频类型。

// @include     http*://www.p26y.com/*
// @include     http*://www.k25m.com/*
// @include     http*://www.javlibrary.com/*
// @include     http*://www.k25m.com/*


// @version     1.14
// @run-at      document-end
// @grant       GM_xmlhttpRequest
// @grant       GM_setClipboard
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_addStyle
// @grant       GM_registerMenuCommand
// ==/UserScript==

"use strict";
let videos = document.querySelector(".videos");
let showTags = true
function removeBeforeFirstSpace(str) {
    return str.split(' ').slice(1).join(' ');
}

function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function getWithRetry(url, attempts, delayDuration) {
    for (let i = 0; i < attempts; i++) {
        try {
            // Your request logic here
            await delay(delayDuration);
            return; // Success, exit loop
        } catch (error) {
            console.error(`Attempt ${i + 1} failed:`, error);
            if (i < attempts - 1) {
                await delay(delayDuration); // Wait before retrying
            } else {
                throw error; // Max attempts reached, throw error
            }
        }
    }
}

var good = ["监禁", "轮奸", "凌辱", "轮奸", "SM", "拘束", "调教", "强奸", "肛交"]
var get_eng_title = function(url, data) {
    let en_url = (url.replace("/cn/", "/en/"))
    GM_xmlhttpRequest({
        method: "GET",
        url: en_url,
        responseType: "document",
        onload: function (result) {
            let video_page = result.response;
            data.title_en = removeBeforeFirstSpace(video_page.querySelector(".post-title.text").innerText)
            GM_xmlhttpRequest({
                method: "POST",
                url: "https://www.mingren.life/av/general",
                responseType: "json",
                headers: {
                    "Content-Type": "application/json" // Set the content type to application/json
                },
                data: JSON.stringify([data]),
                onload: function (result) {
                    console.log(result.response)
                },
            })

        },
        onerror: function (e) {
            console.error(e);
            throw "search error";
        }
    });
}



function hasCommonElement(array1, array2) {
    const set1 = new Set(array1);
    return array2.some(element => set1.has(element));
}

function applyTags(videoElement, genres) {
    // Logic to apply tags to the video element
    const tags = genres.join(', ');
    videoElement.setAttribute("data-toggle", "tooltip");
    videoElement.setAttribute("title", tags);
    if (hasCommonElement(genres, good)) {
        videoElement.style.color = "#e3a807"; // Example styling, adjust as necessary
    }
}

var get_tags = function(element, url=element.href){
    GM_xmlhttpRequest({
            method: "GET",
            url: url,
            responseType: "document",
            onload: function (result) {
                let string = "";
                let video_page = result.response;
                let genres = Array.from(video_page.querySelector("#video_genres").getElementsByClassName("genre")).map(genre => {
                    return genre.innerText
                })
                let code = video_page.querySelector("#video_id .text").innerText
                let director = video_page.querySelector("#video_director .text").innerText
                let company = video_page.querySelector("#video_maker .text").innerText
                let actors = Array.from(video_page.querySelectorAll(".cast .star")).map(star => {
                    return star.innerText
                })
                let title_jp = removeBeforeFirstSpace(video_page.querySelector(".post-title.text").innerText)
                let release_date = video_page.querySelector("#video_date .text").innerText
                let poster = video_page.querySelector("#video_jacket_img").src
                get_eng_title(url, {url, genres, code, director, company, actors, title_jp, release_date, poster})

                applyTags(element, genres)
            },
            onerror: function (e) {
                console.error(e);
                throw "search error";
            }
        });
}


const promises = [];
if (videos) {
    $('.video').each((index, video) => {
        // Extract the code as before
        const code = ($(video).find("a")[0].title.split(" ")[0]).replace(/-/g, '');
        // Create a new promise for each AJAX request and add it to the promises array
        const promise = new Promise((resolve, reject) => {
            $.ajax({
                url: `https://www.mingren.life/av/${code}`,
                success: (result) => {
                    if (!result) {
                        // Handle no result scenario
                    } else if (result.DownloadMovies && result.DownloadMovies.length > 0) {
                        if (result.DownloadMovies[0].subtitle) {
                            $(video).css("background-color", "pink");
                        } else {
                            $(video).css("background-color", "#c6eb34");
                        }
                    }
                    resolve({ result, video });
                },
                error: (error) => {
                    // Reject the promise in case of an error
                    reject(error);
                }
            });
        });

        promises.push(promise);
    });

    // Use Promise.all to handle all the promises together
    Promise.all(promises).then(async (results) => {
        // Process each movie that need to add to db
        var new_movies = results.filter(({result, video}) => !(result))
        new_movies.forEach(({result, video}) => {
            console.log(video)
        })
        var old_movies = results.filter(({result, video}) => !!(result))
        results.forEach(({result, video}) => {
            if (showTags && result && result.MovieGenres) {
                // Assuming result.genres is an array of genre tags for the movie
                applyTags($(video).find("a")[0], result.MovieGenres.map(genre => genre.Genres.name))
            }
        });
        // for new movies, we need to extract all info and eng subtitles. However, set a 3 sec limit
        for (const {video} of new_movies) {
            await delay(3000); // Wait for 3 seconds before processing each new movie
            // Assuming get_tags is properly defined to handle the video element
            get_tags($(video).find("a")[0]);
        }
        // for all movies, we need to extract tags only if when showTags is true


    }).catch(error => {
        // Handle any error that occurred during any of the ajax calls
        console.error("An error occurred: ", error);
    });
} else {
    let code = document.querySelector("#video_id .text").innerText
    let downloaded = false
    $.ajax({
        url: `https://www.mingren.life/av/${code}`,
        success: (result) => {
            if (result.DownloadMovies.length > 0) {
                let subtitle = result.DownloadMovies[0].subtitle
                let downloaded = true
                let mosic = result.DownloadMovies[0].mosic
                let dataTable = $("#video_info")[0]
                let innerHtml = `<div id="" class="item">
<table>
<tbody><tr>
	<td class="header">马赛克:</td>
	<td class="text"><span id="cast36486" class="cast"><span class="star"><a rel="tag">${mosic ? "有" : "无"}</a></span></td>
	<td class="icon"></td>
</tr>
</tbody></table>
</div>
<div id="" class="item">
<table>
<tbody><tr>
	<td class="header">字幕:</td>
	<td class="text"><span id="cast36486" class="cast"><span class="star"><a rel="tag">${subtitle ? "有" : "无"}</a></span></td>
	<td class="icon"></td>
</tr>
</tbody></table>
</div>`
                const d = document.createElement("div")
                d.innerHTML = innerHtml
                dataTable.appendChild(d)
                console.log(dataTable)
            }
        },
        error: (error) => {
            // Reject the promise in case of an error
            reject(error);
        }
    });
}