跳转到内容

User:Chatsven/AutoDataEdit.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// 维基百科用户页统计自动更新 - 纯JS版本
// 放置位置: User:Chatsven/AutoDataEdit.js
// 在 User:Chatsven/common.js 中添加: importScript('User:Chatsven/AutoDataEdit.js');

(function() {
    'use strict';

    var CONFIG = {
        userName: 'Chatsven',
        targetPage: 'User:Chatsven/test',
        storageKey: 'wiki_stats_last_date'
    };

    var LABELS = {
        total_edits: 'TOTAL_EDITS',
        ns_edits: 'NS_EDITS',
        monthly_edits: 'MONTHLY_EDITS'
    };

    var api = new mw.Api();

    function getToday() {
        return new Date().toISOString().split('T')[0];
    }

    function getLastUpdateDate() {
        try {
            return localStorage.getItem(CONFIG.storageKey) || '';
        } catch (e) {
            return '';
        }
    }

    function setLastUpdateDate(date) {
        try {
            localStorage.setItem(CONFIG.storageKey, date);
        } catch (e) {}
    }

    function shouldUpdate() {
        var lastDate = getLastUpdateDate();
        var today = getToday();
        return lastDate !== today;
    }

    function getTotalEdits(username) {
        return api.get({
            action: 'query',
            list: 'users',
            ususers: username,
            usprop: 'editcount'
        }).then(function(data) {
            return data.query.users[0].editcount || 0;
        }).catch(function(e) {
            console.error('[WikiStats] 获取总编辑数失败:', e);
            return null;
        });
    }

    function getNsEdits(username) {
        return api.get({
            action: 'query',
            list: 'usercontribs',
            ucuser: username,
            ucnamespace: 0,
            uclimit: 'max'
        }).then(function(data) {
            return (data.query && data.query.usercontribs)
                ? data.query.usercontribs.length
                : 0;
        }).catch(function(e) {
            console.error('[WikiStats] 获取主命名空间编辑数失败:', e);
            return null;
        });
    }

    function getPastMonthEdits(username) {
        var now = new Date();
        var end = now.toISOString();
        var start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString();

        return api.get({
            action: 'query',
            list: 'usercontribs',
            ucuser: username,
            ucstart: start,
            ucend: end,
            uclimit: 500
        }).then(function(data) {
            if (!data.query || !data.query.usercontribs) return 0;

            var count = 0;
            var monthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);

            data.query.usercontribs.forEach(function(item) {
                var ts = item.timestamp.replace(/T.*$/, '');
                var d = new Date(ts + 'T00:00:00Z');
                if (d >= monthAgo && d <= now) count++;
            });

            return count;
        }).catch(function(e) {
            console.error('[WikiStats] 获取本月编辑数失败:', e);
            return null;
        });
    }

    function getPageContent(title) {
        return api.get({
            action: 'query',
            prop: 'revisions',
            rvprop: 'content',
            titles: title
        }).then(function(data) {
            var pages = data.query && data.query.pages;
            if (!pages) return null;

            var pageId = Object.keys(pages)[0];

            if (pageId === '-1') {
                console.error('[WikiStats] 页面不存在: ' + title);
                return null;
            }

            var page = pages[pageId];
            var revisions = page.revisions;

            if (revisions && revisions[0]) {
                var content = revisions[0]['*'] || revisions[0].slots.main['*'];
                console.log('[WikiStats] 获取内容长度: ' + content.length + ' chars');
                return content;
            }
            return null;
        }).catch(function(e) {
            console.error('[WikiStats] 获取页面内容失败:', e);
            return null;
        });
    }

    function updateContent(content, stats) {
        var result = content;
        var hasChanges = false;

        Object.keys(LABELS).forEach(function(key) {
            var label = LABELS[key];
            var value = stats[key];
            if (value !== null && value !== undefined) {
                var pattern = new RegExp('(<!--' + label + '-->)(\\d+次)', 'g');
                var newValue = '$1' + value + '次';
                if (result.match(pattern)) {
                    result = result.replace(pattern, newValue);
                    hasChanges = true;
                    console.log('[WikiStats] 更新 ' + label + ': ' + value + '次');
                }
            }
        });

        return hasChanges ? result : null;
    }

    function savePage(title, content, summary) {
        var editData = {
            action: 'edit',
            title: title,
            text: content,
            summary: summary
        };

        return api.postWithToken('csrf', editData).then(function(data) {
            if (data.edit && data.edit.result === 'Success') {
                console.log('[WikiStats] 页面 ' + title + ' 更新成功');
                return true;
            } else {
                console.error('[WikiStats] 页面更新失败:', data);
                return false;
            }
        }).catch(function(e) {
            console.error('[WikiStats] 保存页面出错:', e);
            return false;
        });
    }

    function doUpdate() {
        console.log('[WikiStats] 开始每日自动更新...');

        Promise.all([
            getTotalEdits(CONFIG.userName),
            getNsEdits(CONFIG.userName),
            getPastMonthEdits(CONFIG.userName)
        ]).then(function(results) {
            var totalEdits = results[0];
            var nsEdits = results[1];
            var monthlyEdits = results[2];

            var stats = {
                total_edits: totalEdits,
                ns_edits: nsEdits,
                monthly_edits: monthlyEdits
            };

            console.log('[WikiStats] 统计数据:', stats);

            return getPageContent(CONFIG.targetPage).then(function(content) {
                if (!content) {
                    console.error('[WikiStats] 无法获取页面内容');
                    return;
                }

                var updatedContent = updateContent(content, stats);

                if (!updatedContent) {
                    console.log('[WikiStats] 没有需要更新的内容');
                    return;
                }

                var editSummary = '更新贡献:总编辑 ' + totalEdits + ' | 主命名空间 ' + nsEdits + ' | 本月 ' + monthlyEdits + ' (Auto)';

                return savePage(
                    CONFIG.targetPage,
                    updatedContent,
                    editSummary
                ).then(function(success) {
                    if (success) {
                        setLastUpdateDate(getToday());
                        console.log('[WikiStats] ✅ 每日更新完成!');
                        mw.notify('✅ 统计已自动更新!', { type: 'success' });
                    }
                });
            });
        }).catch(function(error) {
            console.error('[WikiStats] 运行出错:', error);
        });
    }

    function main() {
        if (typeof mw === 'undefined' || !mw.config) {
            console.warn('[WikiStats] MediaWiki 未加载');
            return;
        }

        if (!mw.config.get('wgUserName')) {
            console.log('[WikiStats] 未登录,跳过');
            return;
        }

        console.log('[WikiStats] 脚本开始运行...');
        console.log('[WikiStats] 目标页面: ' + CONFIG.targetPage);

        if (!shouldUpdate()) {
            console.log('[WikiStats] 今天已更新过,跳过');
            return;
        }

        doUpdate();
    }

    if (typeof mw !== 'undefined' && mw.hook) {
        mw.hook('wikipage.content').add(main);
    } else if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', main);
    } else {
        main();
    }

})();