跳转到内容

User:Bluedeck/source/ar-admin-3.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// 本工具暂无用户界面。若要使用,可复制到console,并手动调用:
//     await bluedeck_ar_version_3_fm3osisn4diqncu28("页面名称");

async function bluedeck_ar_version_3_fm3osisn4diqncu28(pagename) {
        const WIKI_HOST = "https://zh.wikipedia.org";
        const REMOTE_HOST = "https://minigun.app";
        const X_WWW_FORM_URLENCODED = { headers: { "Content-Type": "application/x-www-form-urlencoded" } };
        const POST = { method: "POST" };
        const minigun_link = (case_number, revid) => `https://minigun.app/@bluedeck/zhwp/arview/id/${enc(case_number)}/rev.${enc(revid)}/contentplain`;
        const enc = encodeURIComponent;

        // main proc starts
        const revisions = await main_arproc_read(pagename);
        const index_page = await main_arproc_write(pagename, revisions);
        // main proc ends

        /** @template T @param {T[]} arr @param {number} number @returns {T[][]} */
        function arrgroup(arr, number) {
                const grouped = [];
                for (let i=0; i<arr.length; i++) {
                        if (i % number === 0) { grouped.push([]); }
                        grouped[grouped.length-1].push(arr[i]);
                }
                return grouped;
        }
        /** @returns {Promise<string>}  */
        async function load_token() {
                const token_obj = await (await fetch(WIKI_HOST + `/w/api.php?action=query&meta=tokens&format=json`, { ...POST, ...X_WWW_FORM_URLENCODED })).json();
                return token_obj.query.tokens.csrftoken;
        }
        /** @param {string} a @returns {string} */
        function replace_string_escape_wikitext(a){
                return a.replaceAll("<", "&lt;").replaceAll("{{", "<nowiki>{{</nowiki>").replaceAll("~~", "~<!---->~").replaceAll("[[", "[[:").replaceAll("[[::", "[[:");
        }
        /** @param {string} pgname @param {string} newcontent @param {string} summary @param {string} token @returns {Promise<void>} */
        async function asyncfetchedit(pgname, newcontent, summary, token) {
                const body = `action=edit&bot=1&format=json&title=${enc(pgname)}&text=${enc(newcontent)}&summary=${enc(summary)}&token=${enc(token)}`;
                await fetch(WIKI_HOST + `/w/api.php`, { ...POST, ...X_WWW_FORM_URLENCODED, body });
        }
        /** @param {string} pagename @returns {Promise<Array>} */
        async function main_arproc_read(pagename) {
                console.log(` ---------- Starting loading [[${pagename}]] ---------- `);
                let prerevlist = await (await fetch(WIKI_HOST + `/w/api.php?action=query&prop=deletedrevisions&format=json&drvprop=content|comment|user|userid|timestamp|size|ids&drvlimit=100&titles=${enc(pagename)}`, { ...POST, ...X_WWW_FORM_URLENCODED })).json();
                let revlist=[];
                while(prerevlist["continue"]) {
                        revlist=Object.entries(prerevlist.query.pages)[0][1].deletedrevisions.toReversed().concat(revlist);
                        prerevlist = await (await fetch(WIKI_HOST + `/w/api.php?action=query&prop=deletedrevisions&format=json&drvprop=content|comment|user|userid|timestamp|size|ids&drvlimit=100&titles=${enc(pagename)}&drvcontinue=${enc(prerevlist["continue"].drvcontinue)}`, { ...POST, ...X_WWW_FORM_URLENCODED })).json();
                }
                revlist=Object.entries(prerevlist.query.pages)[0][1].deletedrevisions.toReversed().concat(revlist);
                console.log(` ---------- Finished loading ${revlist.length} deleted revisions for [[${pagename}]] ---------- `);
                return revlist;
        }
        /** @param {Array} revisions must conform to the minigun.app shape in POST /@bluedeck/zhwp/arsession/shape.ts @returns { Promise<{ case_number: string }> } */
        async function minigun_fullupload(revisions) {
                const init = await (await fetch(`${REMOTE_HOST}/@bluedeck/zhwp/arsession/init`, {"method": "POST"})).json();
                console.log(init);
                const sessionid = init.sessionid;
                const case_number = init.case_number;
                for (const revs of arrgroup(revisions, 5)) {
                        console.log(await (await fetch(`${REMOTE_HOST}/@bluedeck/zhwp/arsession/${sessionid}/upload`, {
                                method: "POST",
                                body: revs.map(a => JSON.stringify(a)).join("\r\n"),
                        })).text());
                }
                const close = await (await fetch(`${REMOTE_HOST}/@bluedeck/zhwp/arsession/${sessionid}/close`, { method: "POST"})).json();
                console.log(close);
                return { case_number: case_number };
        }
        /**
         * @param {string} pagename 
         * @param {Array} revisions 
         * @returns {Promise<string>}
         */
        async function main_arproc_write(pagename, revisions) {
                const index_page = "Wikipedia:已删除内容查询/查询/" + pagename;
                const conforming_revisions = revisions.map(rev => ({
                        r: rev.revid.toString(), 
                        p: rev.parentid?.toString() ?? "0",
                        pc: pagename,
                        rt: rev.timestamp,
                        s: rev.comment,
                        un: rev.user,
                        u: rev.userid.toString(),
                        c: rev["*"],
                        //  r   -- string --  rev id
                        //  p   -- string --  page id
                        //  pc  -- string --  page canon name (no hant-hans transformation)
                        //  rt  -- string --  rev timestamp
                        //  s   -- string --  edit summary
                        //  un  -- string --  user name
                        //  u   -- string --  user id
                        //  c   -- string --  content
                }));

                console.log(" ---------- Uploading to minigun ---------- ");
                const { case_number } = await minigun_fullupload(conforming_revisions);

                console.log(" ---------- Creating index page ---------- ");
                const index_page_content_list = revisions.map(rev => `\n<tr><td> [${minigun_link(case_number, rev.revid)} '''查看存档'''] </td><td> ${rev.timestamp.split('T').join(' ').split('Z').join('')} </td><td> [[user talk:${rev.user}|]] </td><td> ${rev.size} </td><td> ${rev.revid} </td><td> ${replace_string_escape_wikitext(rev.comment)}</td></tr>`)

                const final_rev = await asyncfetchedit(
                        index_page, 
                        "页面[[:"+pagename+"]]共有"+revisions.length+"个已删除版本,存档如下:\n----\n<table style='white-space:nowrap'><tr><td></td><td>'''编辑时分'''</td><td>'''用户'''</td><td>'''页面大小'''</td><td>'''版本号'''</td><td>'''编辑摘要'''</td></tr>"+index_page_content_list.toReversed().join("")+"\n</table>\n----\n{"+"{subst:User:Bluedeck/infr/ar.thankyou.js}}",
                        "DRV lookup: [[:"+pagename+"]]",
                        await load_token(),
                );
                console.log("All done: ", final_rev);
                return index_page;
        }
}