查询bangumi贴中用户观看状态

查询贴中所有用户观看某部作品的状态

目前为 2023-12-27 提交的版本。查看 最新版本

// ==UserScript==
// @name         查询bangumi贴中用户观看状态
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  查询贴中所有用户观看某部作品的状态
// @author       Hirasawa Yui
// @match        https://bangumi.tv/group/topic/*
// @match        https://bangumi.tv/subject/topic/*
// @match        https://bgm.tv/group/topic/*
// @match        https://bgm.tv/subject/topic/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    let userInfoMap = new Map(); // To store results for each user ID
    let validSubjectId = false; // Flag to track if the subject ID is valid

    // Function to create or update an element with the fetched data
    function insertOrUpdateAdjacentToAnchor(anchor, siblingClass, userId, subjectId) {
        let key = `${userId}-${subjectId}`;
        let text = userInfoMap.get(key) || "No info available";

        // Find existing element or create new one
        let newElement = anchor.parentNode.querySelector('.userData');
        if (!newElement) {
            newElement = anchor.parentNode.parentNode.querySelector('.userData');
        }
        if (!newElement) {
            newElement = document.createElement('span');
            newElement.className = 'userData'; // Assign a class for easy identification
            let inserted = false;
            let nextElement = anchor.parentNode.nextSibling;
            while (nextElement) {
                if (nextElement.nodeType === 1 && nextElement.matches(siblingClass)) {
                    nextElement.parentNode.insertBefore(newElement, nextElement.nextSibling);
                    inserted = true;
                    break;
                }
                nextElement = nextElement.nextSibling;
            }
            if (!inserted) {
                anchor.parentNode.insertBefore(newElement, anchor.nextSibling);
            }
        }

        // Update text content and color
        newElement.textContent = `(${text})`;
        newElement.style.color = 'red';
        newElement.style.fontWeight = 'bold';
    }

    // Fetch collection data for a specific user ID and subject ID
    async function fetchUserInfo(userId, subjectId) {
        const url = `https://api.bgm.tv/v0/users/${userId}/collections/${subjectId}`;
        // Skip fetching if the user is already in the map with the same subjectId or subject ID is invalid
        if (!validSubjectId || userInfoMap.has(`${userId}-${subjectId}`)) return;

        try {
            const response = await fetch(url);

            if (!response.ok) {
                userInfoMap.set(`${userId}-${subjectId}`, "TA没看过这部作品");
                return;
            }

            const data = await response.json();
            let infoText = getInfoTextFromData(data);
            userInfoMap.set(`${userId}-${subjectId}`, infoText);
        } catch (error) {
            console.error('Error fetching or processing data', error);
            userInfoMap.set(`${userId}-${subjectId}`, "Error fetching data");
        }
    }

    // Convert fetched data to a user-friendly text
    function getInfoTextFromData(data) {
        if (data.type === 1) return "TA想看这部作品";
        else if (data.type === 2) return data.rate ? `TA打了${data.rate}分` : 'TA看过这部作品';
        else if (data.type === 3) return data.ep_status ? `TA看到了${data.ep_status}集` : 'TA在看这部作品';
        else if (data.type === 4) return "TA搁置了这部作品";
        else if (data.type === 5) return "TA抛弃了这部作品";
        else return "未知状态";
    }

    // Fetch subject info by subject ID
    async function fetchSubjectInfo(subjectId) {
        const url = `https://api.bgm.tv/v0/subjects/${subjectId}`;
        try {
            const response = await fetch(url);
            const div = document.querySelector('.subjectInfo');

            if (!response.ok) {
                div.textContent = "无效条目";
                validSubjectId = false; // Mark subject ID as invalid
                userInfoMap.clear(); // Clear previous info if any
                return;
            }

            const data = await response.json();
            div.textContent = `你当前正在查询所有用户观看 ${data.name} 的状态`;
            div.style.color = 'green';
            validSubjectId = true; // Mark subject ID as valid
        } catch (error) {
            console.error('Error fetching subject data', error);
        }
    }

    // Initialize input box and button, and handle click event
    function initInputAndButton() {
        const postTopicDiv = document.querySelector('.postTopic');
        if (postTopicDiv) {
            const input = document.createElement('input');
            input.type = 'text';
            input.className = 'searchInputL';
            input.placeholder = '输入条目ID';
            const button = document.createElement('button');
            button.className = 'searchBtnL';
            button.textContent = '获取信息';
            const div = document.createElement('div');
            div.className = 'subjectInfo'; // For displaying subject info

            button.onclick = async function() {
                const subjectId = input.value.trim();
                if (!subjectId) return; // Do nothing if the subject ID is empty
                await fetchSubjectInfo(subjectId);
                if (validSubjectId) { // Only process users if the subject ID is valid
                    processAllUsers(subjectId);
                }
            };

            postTopicDiv.appendChild(input);
            postTopicDiv.appendChild(button);
            postTopicDiv.appendChild(div); // Append the div for subject info
        }
    }

    // Fetch user info for all users and then process anchor tags
    async function processAllUsers(subjectId) {
        const anchorElements = document.querySelectorAll('a.l');
        let fetchPromises = [];

        anchorElements.forEach(anchor => {
            if(anchor.href.includes('/user/')) {
                const userId = anchor.href.split('/user/')[1].split('/')[0];
                if (!userInfoMap.has(`${userId}-${subjectId}`)) {
                    fetchPromises.push(fetchUserInfo(userId, subjectId));
                }
            }
        });

        await Promise.all(fetchPromises);

        anchorElements.forEach(anchor => {
            if(anchor.href.includes('/user/')) {
                const userId = anchor.href.split('/user/')[1].split('/')[0];
                insertOrUpdateAdjacentToAnchor(anchor, 'span.sign.tip_j', userId, subjectId);
            }
        });
    }

    window.addEventListener('load', function() {
        initInputAndButton(); // Initialize and append input box and button
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址