跳转到内容

MediaWiki:Gadget-abusefilter33test.js:修订间差异

来自萌娘共享
代码变动:103d1a56 - feat: rename (#594) by U:AnnAngela, co-authored-by: GH:github-actions[bot]
标签由机器人或全自动脚本执行的操作
代码变动:103d1a56 - feat: rename (#594) by U:AnnAngela, co-authored-by: GH:github-actions[bot]
标签由机器人或全自动脚本执行的操作
第8行: 第8行:
/* <pre> */
/* <pre> */


"use strict";
"use strict";$(()=>(async()=>{if(!mw.config.get("wgUserGroups").includes("sysop")&&!mw.config.get("wgUserGroups").includes("staff"))return;if("AbuseLog"!==mw.config.get("wgCanonicalSpecialPageName"))return;const getLogVar=t=>$(`.mw-abuselog-details-${t} .mw-abuselog-var-value .mw-abuselog-var-value`).text(),t=getLogVar("timestamp"),e=getLogVar("user_name"),s=getLogVar("article_prefixedtext"),r=[...document.querySelectorAll('a[href*="/Special:%E6%BB%A5%E7%94%A8%E8%BF%87%E6%BB%A4%E5%99%A8/"]')].filter(({href:t})=>/%E6%BB%A5%E7%94%A8%E8%BF%87%E6%BB%A4%E5%99%A8\/[1-9]\d*$/.test(t))?.[0]?.href?.match?.(/[1-9]\d*$/)?.[0];if(0===t.length||0===e.length||0===s.length||"string"!=typeof r)return;const symbolEnter=t=>"string"==typeof t?t.replace(/\n/g,"↵"):t,a=new mw.Api,n=$("<table/>");$("#mw-content-text > fieldset > p:first").after(n.css("width","100%").addClass("wikitable")),n.empty().append('<tbody><tr><td style="text-align: center;">加载中(<span id="abusefiltertest-progress">0</span>/2)……</td></tr></tbody>');const i=$("#abusefiltertest-progress");try{const o=(await a.post({action:"query",assertuser:mw.config.get("wgUserName"),list:"abuselog",afluser:e,afltitle:s,aflprop:"details",aflfilter:+r})).query.abuselog;if(0===o.length)throw"无法找到对应用户名和页面标题的滥用过滤器日志";i.text(1);const l=Array.from(new Map(o.filter(({details:{timestamp:e}})=>t===e).map(t=>[t.new_wikitext,t])).values());if(0===l.length)throw console.info(o),"无法找到对应时间戳的滥用过滤器日志";i.text(2);const f=(await a.post({action:"query",assertuser:mw.config.get("wgUserName"),list:"abusefilters",abfstartid:+r,abfendid:+r,abfprop:"pattern"})).query.abusefilters[0].pattern.replace(/\r/g,""),g=Array.from(f.match(/\/\* string rule start \*\/[\s\S]+?(?=\/\* string rule end \*\/)/g)||[]).map(t=>t.replace(/\/\* regex rule start \*\//g,"").split("\n")).flat().map(t=>t.replace(/^ *"?/,"").replace(/"?,? *$/,"")).filter(t=>""!==t),c=new Set(g),d=Array.from(f.match(/\/\* regex rule start \*\/[\s\S]+?(?=\/\* regex rule end \*\/)/g)||[]).map(t=>t.replace(/\/\* regex rule start \*\//g,"").split("\n")||[]).flat().map(t=>t.replace(/^ *"?/,"").replace(/"?,? *$/,"")).filter(t=>""!==t),p=new Set(d);if(c.size+p.size===0)throw"无法找到符合格式的规则";for(const{details:t}of l){const e=t.added_lines||t.new_wikitext,s=[],a=$("<table/>").css("width","100%").addClass("wikitable abusefiltertest").hide();n.after(a);for(const t of c.values())if(e.includes(t)){const r=e.split(t);r.forEach((e,a)=>{if(a===r.length-1)return;const n=r[a+1],i=Math.max(0,e.length-20),o=Math.min(n.length,20);s.push({isRegexp:!1,rule:t,before:e.substring(i,i+20),string:t,after:n.substring(0,o),start:i})})}for(const t of p.values()){const r=RegExp(`.{0,20}${t}.{0,20}`,"ig"),a=RegExp(t,"ig");if(r.test(e)){const n=e.match(r);let i=0;n.forEach(r=>{const n=r.match(a)[0],o=r.split(n),l=o[0],f=o.slice(1).join(n),g=e.indexOf(n,i);i=g+n.length,s.push({isRegex:!0,rule:t,before:l,string:n,after:f,start:g})})}}if(a.empty(),s.length>0){a.append(`<caption style="font-weight: 700;">命中防滥用过滤器${r}的内容</caption><tr><th style="text-align: right;">规则(请勿泄漏!!!)</th><th style="text-align: left;">命中字符串上下文</th></tr>`),s.sort(({start:t},{start:e})=>t-e);const t=[];s.forEach(e=>{0===t.filter(({isRegex:t,start:s})=>t===e.isRegex&&s===e.start).length&&t.push(e)}),console.info(t),t.forEach(({isRegex:t,rule:e,before:s,string:r,after:n,start:i})=>{const o=$("<tr/>"),l=$("<td/>"),f=$("<code/>");f.text(e),l.addClass("mw-label"),l.text(t?"正则表达式":"字符串"),l.append(symbolEnter(f)).append(":"),o.append(l);const g=$("<td/>");g.addClass("mw-input");const c=$("<span/>");c.text(symbolEnter(s)).css({padding:"0 .25em"});const d=$("<span/>");d.text(symbolEnter(r)).css({"font-weight":"700","text-decoration":"underline",padding:"0 .25em"});const p=$("<span/>");if(p.text(symbolEnter(n)).css({padding:"0 .25em"}),s.length>=20){const t=$("<span/>");t.text(`[${i}] ……`).css({"padding-right":".25em"}),g.append(t)}if(g.append(c).append(d).append(p),n.length>=20){const t=$("<span/>");t.text("……").css({"padding-left":".25em"}),g.append(t)}o.append(g),a.append(o)})}else a.empty().append('<tbody><tr><td style="text-align: center;">现有规则没有匹配项……</td></tr></tbody>')}n.hide(),$(".abusefiltertest").show()}catch(t){console.info("abusefiltertest",t),$(".abusefiltertest").remove(),n.empty(),33===r&&n.append(`<tbody><tr><td style="text-align: ${"string"==typeof t?"center":"left"};">发生错误:${"string"==typeof t?t:`${t} ${t.stack.split("\n")[1].trim()}`}</td></tr></tbody>`)}})());  
$(() => (async () => {
    if (!mw.config.get("wgUserGroups").includes("sysop") && !mw.config.get("wgUserGroups").includes("staff")) {
        return;
    }
    if (mw.config.get("wgCanonicalSpecialPageName") !== "AbuseLog") {
        return;
    }
    const getLogVar = (varName) => $(`.mw-abuselog-details-${varName} .mw-abuselog-var-value .mw-abuselog-var-value`).text();
    const timestampVar = getLogVar("timestamp");
    const userName = getLogVar("user_name");
    const articlePrefixedtext = getLogVar("article_prefixedtext");
    const filter = [...document.querySelectorAll('a[href*="/Special:%E6%BB%A5%E7%94%A8%E8%BF%87%E6%BB%A4%E5%99%A8/"]')].filter(({ href }) => /%E6%BB%A5%E7%94%A8%E8%BF%87%E6%BB%A4%E5%99%A8\/[1-9]\d*$/.test(href))?.[0]?.href?.match?.(/[1-9]\d*$/)?.[0];
    if (timestampVar.length === 0 || userName.length === 0 || articlePrefixedtext.length === 0 || typeof filter !== "string") {
        return;
    }
    const symbolEnter = (str) => typeof str === "string" ? str.replace(/\n/g, "↵") : str;
    const api = new mw.Api();
    const pTable = $("<table/>");
    $("#mw-content-text > fieldset > p:first").after(pTable.css("width", "100%").addClass("wikitable"));
    pTable.empty().append("<tbody><tr><td style=\"text-align: center;\">加载中(<span id=\"abusefiltertest-progress\">0</span>/2)……</td></tr></tbody>");
    const progress = $("#abusefiltertest-progress");
    try {
        const __details = (await api.post({
            action: "query",
            assertuser: mw.config.get("wgUserName"),
            list: "abuselog",
            afluser: userName,
            afltitle: articlePrefixedtext,
            aflprop: "details",
            aflfilter: +filter,
        })).query.abuselog;
        if (__details.length === 0) {
            throw "无法找到对应用户名和页面标题的滥用过滤器日志";
        }
        progress.text(1);
        const _details = Array.from(new Map(__details.filter(({ details: { timestamp } }) => timestampVar === timestamp).map((n) => [n.new_wikitext, n])).values());
        if (_details.length === 0) {
            console.info(__details);
            throw "无法找到对应时间戳的滥用过滤器日志";
        }
        progress.text(2);
        const _rules = (await api.post({
            action: "query",
            assertuser: mw.config.get("wgUserName"),
            list: "abusefilters",
            abfstartid: +filter,
            abfendid: +filter,
            abfprop: "pattern",
        })).query.abusefilters[0].pattern.replace(/\r/g, "");
        const _stringRules = Array.from(_rules.match(/\/\* string rule start \*\/[\s\S]+?(?=\/\* string rule end \*\/)/g) || []).map((r) => r.replace(/\/\* regex rule start \*\//g, "").split("\n")).flat().map((r) => r.replace(/^ *"?/, "").replace(/"?,? *$/, "")).filter((r) => r !== "");
        const stringRules = new Set(_stringRules);
        const _regexRules = Array.from(_rules.match(/\/\* regex rule start \*\/[\s\S]+?(?=\/\* regex rule end \*\/)/g) || []).map((r) => r.replace(/\/\* regex rule start \*\//g, "").split("\n") || []).flat().map((r) => r.replace(/^ *"?/, "").replace(/"?,? *$/, "")).filter((r) => r !== "");
        const regexRules = new Set(_regexRules);
        if (stringRules.size + regexRules.size === 0) {
            throw "无法找到符合格式的规则";
        }
        for (const { details } of _details) {
            const addedLines = details.added_lines || details.new_wikitext;
            const result = [];
            const table = $("<table/>").css("width", "100%").addClass("wikitable abusefiltertest").hide();
            pTable.after(table);
            for (const sr of stringRules.values()) {
                if (addedLines.includes(sr)) {
                    const splits = addedLines.split(sr);
                    splits.forEach((str, i) => {
                        if (i === splits.length - 1) {
                            return;
                        }
                        const next = splits[i + 1];
                        const start = Math.max(0, str.length - 20);
                        const end = Math.min(next.length, 20);
                        result.push({
                            isRegexp: false,
                            rule: sr,
                            before: str.substring(start, start + 20),
                            string: sr,
                            after: next.substring(0, end),
                            start,
                        });
                    });
                }
            }
            for (const rr of regexRules.values()) {
                const regex = RegExp(`.{0,20}${rr}.{0,20}`, "ig");
                const findstring = RegExp(rr, "ig");
                if (regex.test(addedLines)) {
                    const splits = addedLines.match(regex);
                    let lastFromIndex = 0;
                    splits.forEach((str) => {
                        const string = str.match(findstring)[0];
                        const split = str.split(string);
                        const before = split[0];
                        const after = split.slice(1).join(string);
                        const start = addedLines.indexOf(string, lastFromIndex);
                        lastFromIndex = start + string.length;
                        result.push({
                            isRegex: true,
                            rule: rr,
                            before,
                            string,
                            after,
                            start,
                        });
                    });
                }
            }
            table.empty();
            if (result.length > 0) {
                table.append(`<caption style="font-weight: 700;">命中防滥用过滤器${filter}的内容</caption><tr><th style="text-align: right;">规则(请勿泄漏!!!)</th><th style="text-align: left;">命中字符串上下文</th></tr>`);
                result.sort(({ start: a }, { start: b }) => a - b);
                const results = [];
                result.forEach((r) => {
                    if (results.filter(({ isRegex, start }) => isRegex === r.isRegex && start === r.start).length === 0) {
                        results.push(r);
                    }
                });
                console.info(results);
                results.forEach(({ isRegex, rule, before, string, after, start }) => {
                    const tr = $("<tr/>");
                    const label = $("<td/>");
                    const ruleCode = $("<code/>");
                    ruleCode.text(rule);
                    label.addClass("mw-label");
                    label.text(isRegex ? "正则表达式" : "字符串");
                    label.append(symbolEnter(ruleCode)).append(":");
                    tr.append(label);
                    const input = $("<td/>");
                    input.addClass("mw-input");
                    const beforeSpan = $("<span/>");
                    beforeSpan.text(symbolEnter(before)).css({
                        padding: "0 .25em",
                    });
                    const strSpan = $("<span/>");
                    strSpan.text(symbolEnter(string)).css({
                        "font-weight": "700",
                        "text-decoration": "underline",
                        padding: "0 .25em",
                    });
                    const afterSpan = $("<span/>");
                    afterSpan.text(symbolEnter(after)).css({
                        padding: "0 .25em",
                    });
                    if (before.length >= 20) {
                        const beforeDot = $("<span/>");
                        beforeDot.text(`[${start}] ……`).css({
                            "padding-right": ".25em",
                        });
                        input.append(beforeDot);
                    }
                    input.append(beforeSpan).append(strSpan).append(afterSpan);
                    if (after.length >= 20) {
                        const afterDot = $("<span/>");
                        afterDot.text("……").css({
                            "padding-left": ".25em",
                        });
                        input.append(afterDot);
                    }
                    tr.append(input);
                    table.append(tr);
                });
            }
            else {
                table.empty().append("<tbody><tr><td style=\"text-align: center;\">现有规则没有匹配项……</td></tr></tbody>");
            }
        }
        pTable.hide();
        $(".abusefiltertest").show();
    }
    catch (e) {
        console.info("abusefiltertest", e);
        $(".abusefiltertest").remove();
        pTable.empty();
        if (filter === 33) {
            pTable.append(`<tbody><tr><td style="text-align: ${typeof e === "string" ? "center" : "left"};">发生错误:${typeof e === "string" ? e : `${e} ${e.stack.split("\n")[1].trim()}`}</td></tr></tbody>`);
        }
    }
})());  


/* </pre> */
/* </pre> */

2025年7月26日 (六) 00:05的版本

/**
 * -------------------------------------------------------------------------
 * !!! DON'T MODIFY THIS PAGE MANUALLY, YOUR CHANGES WILL BE OVERWRITTEN !!!
 * -------------------------------------------------------------------------
 */
var _addText = '{{GHIACode|page=GHIA:MoegirlPediaInterfaceCodes/blob/master/src/gadgets/abusefilter33test/Gadget-abusefilter33test.js|user=[[U:AnnAngela]]|co-authors=GH:github-actions[bot]|longId=103d1a563ea4ccc8ff29fb55c9bcd88329a56eb5|shortId=103d1a56|summary=feat: rename (#594)|body=<nowiki>Co-authored-by: github-actions[bot] <41898282+github-actions[bot]📧users.noreply.github.com></nowiki>}}'; 

/* <pre> */

"use strict";$(()=>(async()=>{if(!mw.config.get("wgUserGroups").includes("sysop")&&!mw.config.get("wgUserGroups").includes("staff"))return;if("AbuseLog"!==mw.config.get("wgCanonicalSpecialPageName"))return;const getLogVar=t=>$(`.mw-abuselog-details-${t} .mw-abuselog-var-value .mw-abuselog-var-value`).text(),t=getLogVar("timestamp"),e=getLogVar("user_name"),s=getLogVar("article_prefixedtext"),r=[...document.querySelectorAll('a[href*="/Special:%E6%BB%A5%E7%94%A8%E8%BF%87%E6%BB%A4%E5%99%A8/"]')].filter(({href:t})=>/%E6%BB%A5%E7%94%A8%E8%BF%87%E6%BB%A4%E5%99%A8\/[1-9]\d*$/.test(t))?.[0]?.href?.match?.(/[1-9]\d*$/)?.[0];if(0===t.length||0===e.length||0===s.length||"string"!=typeof r)return;const symbolEnter=t=>"string"==typeof t?t.replace(/\n/g,"↵"):t,a=new mw.Api,n=$("<table/>");$("#mw-content-text > fieldset > p:first").after(n.css("width","100%").addClass("wikitable")),n.empty().append('<tbody><tr><td style="text-align: center;">加载中(<span id="abusefiltertest-progress">0</span>/2)……</td></tr></tbody>');const i=$("#abusefiltertest-progress");try{const o=(await a.post({action:"query",assertuser:mw.config.get("wgUserName"),list:"abuselog",afluser:e,afltitle:s,aflprop:"details",aflfilter:+r})).query.abuselog;if(0===o.length)throw"无法找到对应用户名和页面标题的滥用过滤器日志";i.text(1);const l=Array.from(new Map(o.filter(({details:{timestamp:e}})=>t===e).map(t=>[t.new_wikitext,t])).values());if(0===l.length)throw console.info(o),"无法找到对应时间戳的滥用过滤器日志";i.text(2);const f=(await a.post({action:"query",assertuser:mw.config.get("wgUserName"),list:"abusefilters",abfstartid:+r,abfendid:+r,abfprop:"pattern"})).query.abusefilters[0].pattern.replace(/\r/g,""),g=Array.from(f.match(/\/\* string rule start \*\/[\s\S]+?(?=\/\* string rule end \*\/)/g)||[]).map(t=>t.replace(/\/\* regex rule start \*\//g,"").split("\n")).flat().map(t=>t.replace(/^ *"?/,"").replace(/"?,? *$/,"")).filter(t=>""!==t),c=new Set(g),d=Array.from(f.match(/\/\* regex rule start \*\/[\s\S]+?(?=\/\* regex rule end \*\/)/g)||[]).map(t=>t.replace(/\/\* regex rule start \*\//g,"").split("\n")||[]).flat().map(t=>t.replace(/^ *"?/,"").replace(/"?,? *$/,"")).filter(t=>""!==t),p=new Set(d);if(c.size+p.size===0)throw"无法找到符合格式的规则";for(const{details:t}of l){const e=t.added_lines||t.new_wikitext,s=[],a=$("<table/>").css("width","100%").addClass("wikitable abusefiltertest").hide();n.after(a);for(const t of c.values())if(e.includes(t)){const r=e.split(t);r.forEach((e,a)=>{if(a===r.length-1)return;const n=r[a+1],i=Math.max(0,e.length-20),o=Math.min(n.length,20);s.push({isRegexp:!1,rule:t,before:e.substring(i,i+20),string:t,after:n.substring(0,o),start:i})})}for(const t of p.values()){const r=RegExp(`.{0,20}${t}.{0,20}`,"ig"),a=RegExp(t,"ig");if(r.test(e)){const n=e.match(r);let i=0;n.forEach(r=>{const n=r.match(a)[0],o=r.split(n),l=o[0],f=o.slice(1).join(n),g=e.indexOf(n,i);i=g+n.length,s.push({isRegex:!0,rule:t,before:l,string:n,after:f,start:g})})}}if(a.empty(),s.length>0){a.append(`<caption style="font-weight: 700;">命中防滥用过滤器${r}的内容</caption><tr><th style="text-align: right;">规则(请勿泄漏!!!)</th><th style="text-align: left;">命中字符串上下文</th></tr>`),s.sort(({start:t},{start:e})=>t-e);const t=[];s.forEach(e=>{0===t.filter(({isRegex:t,start:s})=>t===e.isRegex&&s===e.start).length&&t.push(e)}),console.info(t),t.forEach(({isRegex:t,rule:e,before:s,string:r,after:n,start:i})=>{const o=$("<tr/>"),l=$("<td/>"),f=$("<code/>");f.text(e),l.addClass("mw-label"),l.text(t?"正则表达式":"字符串"),l.append(symbolEnter(f)).append(":"),o.append(l);const g=$("<td/>");g.addClass("mw-input");const c=$("<span/>");c.text(symbolEnter(s)).css({padding:"0 .25em"});const d=$("<span/>");d.text(symbolEnter(r)).css({"font-weight":"700","text-decoration":"underline",padding:"0 .25em"});const p=$("<span/>");if(p.text(symbolEnter(n)).css({padding:"0 .25em"}),s.length>=20){const t=$("<span/>");t.text(`[${i}] ……`).css({"padding-right":".25em"}),g.append(t)}if(g.append(c).append(d).append(p),n.length>=20){const t=$("<span/>");t.text("……").css({"padding-left":".25em"}),g.append(t)}o.append(g),a.append(o)})}else a.empty().append('<tbody><tr><td style="text-align: center;">现有规则没有匹配项……</td></tr></tbody>')}n.hide(),$(".abusefiltertest").show()}catch(t){console.info("abusefiltertest",t),$(".abusefiltertest").remove(),n.empty(),33===r&&n.append(`<tbody><tr><td style="text-align: ${"string"==typeof t?"center":"left"};">发生错误:${"string"==typeof t?t:`${t} ${t.stack.split("\n")[1].trim()}`}</td></tr></tbody>`)}})()); 

/* </pre> */