לדלג לתוכן

משתמש:רובין בוט/הפניות כפולות.js

מתוך חב"דפדיה, אנציקלופדיה חב"דית חופשית

הערה: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
// קרדיט: המכלול (גרסה משופרת)
(() => {
    const BOT_USERS = [3987, 4025, 11975, 8589];
    const api = new mw.Api();

    const getRedirectContent = async (title) => {
        try {
            const response = await api.get({
                prop: "revisions",
                titles: title,
                rvprop: "content",
                rvslots: "*",
                formatversion: "2",
            });
            const page = response.query?.pages?.[0];
            return page?.revisions?.[0]?.slots?.main?.content ?? null;
        } catch (error) {
            console.error("שגיאה בקבלת תוכן הפניה עבור " + title + ":", error);
            return null;
        }
    };

    const getRedirectTarget = async (title) => {
        try {
            const { query } = await api.get({
                titles: title,
                redirects: true,
            });

            if (query?.pages) {
                const page = Object.values(query.pages).find((p) => !p.missing);
                return page?.title ?? null;
            }
            return null;
        } catch (error) {
            console.error("שגיאה בקבלת יעד ההפניה עבור " + title + ":", error);
            return null;
        }
    };

    const extractAnchorFromContent = (content) => {
        const match = content.match(/#הפניה\s*\[\[[^\]]+?(?:#(.+?))?\]\]/);
        return match?.[1] ? "#" + match[1] : "";
    };

    const getNamespacePrefix = async (title) => {
        try {
            const { query } = await api.get({
                titles: title,
                prop: "info",
            });

            if (query?.pages) {
                const page = Object.values(query.pages)[0];
                if (page.ns !== undefined) {
                    const namespacePrefixes = {
                        4: "חבדפדיה:",
                        6: "קובץ:",
                        10: "תבנית:",
                        12: "עזרה:",
                    };
                    return namespacePrefixes[page.ns] ?? "";
                }
            }
            return "";
        } catch (error) {
            console.error("שגיאה בקבלת קידומת מרחב שם עבור " + title + ":", error);
            return "";
        }
    };

    const createRedirect = async (title, target) => {
        try {
            await api.postWithEditToken({
                action: "edit",
                format: "json",
                tags: "doubleredirect-bot",
                bot: true,
                title: title,
                text: "#הפניה [[" + target + "]]",
                summary: "בוט: מתקן הפניה כפולה ל- [[" + target + "]]",
            });
            mw.notify(title + ": ההפניה תוקנה בהצלחה ל- " + target, { type: 'success', title: 'הצלחה' });
        } catch (error) {
            console.error("שגיאה ביצירת הפניה עבור " + title + " ל- " + target + ":", error);
            mw.notify(title + ": נכשל תיקון ההפניה. פרטים בקונסול.", { type: 'error', title: 'שגיאה' });
        }
    };

    const processRedirect = async (title) => {
        try {
            const content = await getRedirectContent(title);
            if (content === null) {
                mw.notify(title + ": לא ניתן לאחזר תוכן דף ההפניה.", { type: 'warn' });
                return;
            }

            const anchor = extractAnchorFromContent(content);
            const finalTarget = await getRedirectTarget(title);

            if (!finalTarget) {
                mw.notify(title + ": לא נמצא יעד הפניה סופי.", { type: 'warn' });
                return;
            }

            const namespace = await getNamespacePrefix(finalTarget);
            const fullTarget = namespace + finalTarget + anchor;

            if (title.replace(/_/g, " ") === finalTarget.replace(/_/g, " ") && !anchor) {
                mw.notify(title + ": ההפניה כבר תקינה. אין צורך בתיקון.", { type: 'info' });
                return;
            }

            if (title.replace(/_/g, " ") === fullTarget.replace(/_/g, " ")) {
                 mw.notify(title + ": הפניה מעגלית או תקינה. אין צורך בתיקון.", { type: 'info' });
                 return;
            }

            console.log("יוצר הפניה חדשה: " + title + " --> " + fullTarget);
            await createRedirect(title, fullTarget);

        } catch (error) {
            console.error("שגיאה בעיבוד הפניה כפולה עבור " + title + ":", error);
            mw.notify(title + ": אירעה שגיאה בעת עיבוד ההפניה. פרטים בקונסול.", { type: 'error', title: 'שגיאה' });
        }
    };

    const init = async () => {
        const userGroups = mw.config.get("wgUserGroups");
        const userId = mw.config.get("wgUserId");
        const pageName = mw.config.get("wgPageName");

        if (!userGroups.includes("bot") && !BOT_USERS.includes(userId)) {
            console.log("משתמש אינו בוט או ברשימת המשתמשים המורשים. הסקריפט לא יופעל.");
            return;
        }

        if (pageName !== "מיוחד:הפניות_כפולות") {
            console.log("הסקריפט פועל רק בדף מיוחד:הפניות_כפולות.");
            return;
        }

        const numInput = prompt("כמה הפניות כפולות להציג ולתקן? (מומלץ להתחיל עם מספר קטן, לדוגמה: 10)", "0");
        const num = parseInt(numInput, 10);

        if (isNaN(num) || num <= 0) {
            mw.notify("קלט לא חוקי. אנא הזן מספר שלם חיובי.", { type: 'error' });
            return;
        }

        try {
            mw.notify("מתחיל בדיקת " + num + " הפניות כפולות...", { type: 'info' });

            const { query } = await api.get({
                list: "querypage",
                qppage: "DoubleRedirects",
                qplimit: num,
            });

            const redirects = query.querypage.results;
            if (redirects.length === 0) {
                mw.notify("לא נמצאו הפניות כפולות לתיקון.", { type: 'info' });
                return;
            }

            for (const redirect of redirects) {
                const title = redirect.title.replace(/_/g, " ");
                await processRedirect(title);
            }
            mw.notify("סיום עיבוד ההפניות הכפולות.", { type: 'success', title: 'סיום' });

        } catch (error) {
            console.error("שגיאה באחזור הפניות כפולות:", error);
            mw.notify("אירעה שגיאה באחזור רשימת ההפניות הכפולות.", { type: 'error', title: 'שגיאה כללית' });
        }
    };

    $(init);
})();