Filtering "Incomplete" for PterClub

支持“非完结”种子主副标题过滤

2025-06-02 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         Filtering "Incomplete" for PterClub
// @namespace    http://tampermonkey.net/
// @version      2.47
// @description  支持“非完结”种子主副标题过滤
// @author       @Zuoans 
// @match        https://pterclub.com/torrents.php*
// @license      MIT
// @grant        GM_addStyle
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // ====================== 样式定义 ======================
    GM_addStyle(`
        /* 颜色变量定义 */
        :root {
            --blue-start: rgba(51, 160, 200, 0.6);   /* 蓝色渐变起始 */
            --blue-mid: rgba(51, 160, 200, 0.1);     /* 蓝色渐变中间 */
            --blue-end: rgba(255, 255, 255, 0);      /* 蓝色渐变结束 */

            --purple-start: rgba(147, 112, 219, 0.5); /* 紫色渐变起始 */
            --purple-mid: rgba(147, 112, 219, 0.1);   /* 紫色渐变中间 */
            --purple-end: rgba(255, 255, 255, 0);     /* 紫色渐变结束 */
        }

        /* incomplete样式 */
        table.torrentname > tbody > tr.tm-incomplete:not(.tm-group) {
            background: linear-gradient(
                to right,
                var(--blue-start) 0%,               /* 渐变起始位置 */
                var(--blue-mid) 50%,               /* 渐变中间位置 */
                var(--blue-end) 90%               /* 渐变结束位置 */
            ) !important;
        }

        /* 制作组样式 */
        table.torrentname > tbody > tr.tm-group:not(.tm-incomplete) {
            background: linear-gradient(
                to right,
                var(--purple-start) 0%,
                var(--purple-mid) 50%,
                var(--purple-end) 90%
            ) !important;
        }

        /* incomplete&制作组双重标记样式 */
        table.torrentname > tbody > tr.tm-incomplete.tm-group {
            background: linear-gradient(
                to right,
                var(--purple-start) 0%,
                var(--purple-mid) 50%,
                var(--purple-end) 90%
            ) !important;
        }

        /* 文字保护 */
        table.torrentname [class*="tm-"] td {
            text-shadow: 0 1px 1px rgba(255,255,255,0.1),
                        0 -1px 1px rgba(0,0,0,0.1) !important;
        }

        /* 悬停效果 */
        table.torrentname > tbody > tr[class*="tm-"]:hover {
            background-color: rgba(255,255,255,0.3) !important;
        }
    `);


    // 2. 原过滤逻辑(保持不变)
    const targetGroups = [
        'AdBlue', 'AREY', 'BdC', 'BMDru', 'CatEDU', 'c0kE',
        'doraemon', 'JKCT', 'KMX', 'Lislander', 'RO',
        'Telesto', 'XPcl', 'ZTR'
    ];

    function safeHighlight() {
        document.querySelectorAll('tr').forEach(tr => {
            // 先清除所有标记
            tr.classList.remove('tm-incomplete', 'tm-group');

            // 仅检查种子名区域)
            const titleEl = tr.querySelector('.torrentname, [href*="details.php"]');
            if (!titleEl) return;

            const titleText = titleEl.textContent;

            // incomplete检测
            const isIncomplete = /(^|\s)(S\d+E\d+|EP?\s?\d+|第\d+集)(\s|$)/i.test(titleText)
                              && !/\d{4}p?\.?$/.test(titleText);

            // 制作组检测(精确匹配)
            const isTargetGroup = targetGroups.some(group =>
                new RegExp(`(\$$|\\-|\\s)${group}(\$$|\\-|\\s)`).test(titleText)
            );

            // 应用标记
            if (isIncomplete) tr.classList.add('tm-incomplete');
            if (isTargetGroup) tr.classList.add('tm-group');
        });
    }

    // ====================== 执行控制 ======================
    const observer = new MutationObserver(mutations => {
        if (mutations.some(mut => mut.addedNodes.length > 0)) {
            safeHighlight();
        }
    });

    document.addEventListener('DOMContentLoaded', () => {
        safeHighlight();
        observer.observe(document.body, {
            childList: true,
            subtree: true,
            attributeFilter: ['class']
        });
    });

    // 页面卸载时清理
    window.addEventListener('unload', () => {
        document.querySelectorAll('[class*="tm-"]').forEach(el => {
            el.className = el.className.replace(/\btm-\w+\b/g, '');
        });
    });
})();