Content deleted Content added
Polygnotus (talk | contribs) No edit summary |
Polygnotus (talk | contribs) No edit summary |
||
(11 intermediate revisions by the same user not shown) | |||
Line 1:
// Wikipedia User Block & Activity Checker for common.js
// Checks if users are blocked and if they've been active in the last 12 months
// Features: maxlag support, HTTP error handling, exponential backoff retry (1min, 3min, 5min), deduplication
async function checkUserBlocks() {
// Show input dialog immediately
showInputDialog();
}
// Helper function to scroll status area to bottom
function scrollStatusToBottom() {
setTimeout(() => {
const statusDiv = $('#status-text');
const statusArea = $('#status-area');
// Try scrolling the status area container instead of the text div
if (statusArea.length && statusArea[0]) {
}
// Also try the text div as backup
}
}, 10);
}
Line 21 ⟶ 39:
<textarea id="user-input" style="width: 100%; height: 200px; font-family: monospace;"
placeholder="Paste your usernames here..."></textarea>
<div id="status-area" style="margin-top: 10px; font-family: monospace; background: #f8f9fa; padding: 10px; border: 1px solid #ddd; height:
<div id="status-text"></div>
</div>
Line 55 ⟶ 73:
// Focus the textarea
setTimeout(() => $('#user-input').focus(), 100);
}
// Helper function to check if username is a vanished/renamed user
function isVanishedOrRenamed(username) {
const lowerUsername = username.toLowerCase();
return lowerUsername.startsWith('vanished user') || lowerUsername.startsWith('renamed user');
}
async function processUsers(input, dialog) {
const
const users = deduplicateUsers(allUsers);
if (users.length === 0) {
Line 68 ⟶ 93:
$('#status-area').show();
const statusDiv = $('#status-text');
statusDiv.html(`<div>Checking ${users.length} users for blocks and activity (last 12 months)...</div>`);▼
// Show deduplication info if there were duplicates
const duplicateCount = allUsers.length - users.length;
if (duplicateCount > 0) {
statusDiv.html(`<div>Found ${allUsers.length} usernames, removed ${duplicateCount} duplicates.</div><div>Checking ${users.length} unique users for blocks and activity (last 12 months)...</div>`);
console.log(`Found ${allUsers.length} usernames, removed ${duplicateCount} duplicates.`);
} else {
▲ statusDiv.html(`<div>Checking ${users.length} users for blocks and activity (last 12 months)...</div>`);
}
scrollStatusToBottom();
console.log(`Checking ${users.length} users for blocks and activity...`);
Line 75 ⟶ 109:
const blockedUsers = [];
const inactiveUsers = [];
const vanishedUsers = []; // New category for vanished/renamed users
// Disable the Check Users button during processing
Line 85 ⟶ 120:
statusDiv.append(`<div>${progress} Checking ${userInfo.username}...</div>`);
scrollStatusToBottom();
▲ statusDiv.scrollTop(statusDiv[0].scrollHeight);
console.log(`${progress} Checking user: ${userInfo.username} ...`);
// Check if this is a vanished or renamed user first
if (isVanishedOrRenamed(userInfo.username)) {
vanishedUsers.push(userInfo.original);
statusDiv.append(`<div style="color: #999;">${progress} ◯ ${userInfo.username} is a vanished/renamed user (skipped)</div>`);
scrollStatusToBottom();
console.log(`◯ ${userInfo.username} is a vanished/renamed user (skipped)`);
// Add base delay between requests
if (i < users.length - 1) {
await sleep(500); // Shorter delay since we're not making API calls
}
continue;
}
try {
Line 97 ⟶ 145:
blockedUsers.push(userInfo.original);
statusDiv.append(`<div style="color: #d33;">${progress} ✗ ${userInfo.username} is blocked</div>`);
▲ statusDiv.scrollTop(statusDiv[0].scrollHeight);
console.log(`✗ ${userInfo.username} is blocked`);
} else {
Line 107 ⟶ 154:
activeUsers.push(userInfo.original);
statusDiv.append(`<div style="color: #00af89;">${progress} ✓ ${userInfo.username} is active (not blocked + active in last 12 months)</div>`);
console.log(`✓ ${userInfo.username} is active (not blocked + active in last 12 months)`);
} else {
inactiveUsers.push(userInfo.original);
statusDiv.append(`<div style="color: #fc3;">${progress} ⚠ ${userInfo.username} is not blocked but inactive (no edits in last 12 months)</div>`);
console.log(`⚠ ${userInfo.username} is not blocked but inactive (no edits in last 12 months)`);
}
Line 123 ⟶ 168:
activeUsers.push(userInfo.original);
statusDiv.append(`<div style="color: #fc3;">${progress} ? ${userInfo.username} - check failed, assuming active</div>`);
scrollStatusToBottom();
▲ statusDiv.scrollTop(statusDiv[0].scrollHeight);
console.log(`? ${userInfo.username} - check failed, assuming active`);
}
// Add base delay between requests to avoid hammering the API
Line 138 ⟶ 180:
// Re-enable button and show completion
checkButton.prop('disabled', false).text('Check Users');
statusDiv.append(`<div style="font-weight: bold; margin-top: 10px;">✓ Completed! ${activeUsers.length} active, ${blockedUsers.length} blocked, ${inactiveUsers.length} inactive, ${vanishedUsers.length} vanished/renamed</div>`);
scrollStatusToBottom();
// Display results
Line 152 ⟶ 193:
console.log(`\nInactive users (not blocked but no edits in last 12 months) (${inactiveUsers.length}):`);
inactiveUsers.forEach(user => console.log(user));
console.log(`\nVanished/Renamed users (${vanishedUsers.length}):`);
vanishedUsers.forEach(user => console.log(user));
// Show results in a separate dialog
displayResults(activeUsers, blockedUsers, inactiveUsers, vanishedUsers);
}
Line 186 ⟶ 230:
return users;
}
function deduplicateUsers(users) {
const seen = new Set();
const uniqueUsers = [];
for (const user of users) {
// Use lowercase username for comparison to handle case variations
const normalizedUsername = user.username.toLowerCase();
if (!seen.has(normalizedUsername)) {
seen.add(normalizedUsername);
uniqueUsers.push(user);
}
}
return uniqueUsers;
}
Line 336 ⟶ 397:
}
function displayResults(activeUsers, blockedUsers, inactiveUsers, vanishedUsers) {
// Create a results dialog
const resultsHtml = `
<div style="max-height: 500px; overflow-y: auto;">
<h3>✓ Active Users (not blocked + active in last 12 months) (${activeUsers.length})</h3>
<textarea readonly style="width: 100%; height:
${activeUsers.join('\n')}</textarea>
<h3>✗ Blocked Users (${blockedUsers.length})</h3>
<textarea readonly style="width: 100%; height:
${blockedUsers.join('\n')}</textarea>
<h3>⚠ Inactive Users (not blocked but no edits in last 12 months) (${inactiveUsers.length})</h3>
<textarea readonly style="width: 100%; height:
${inactiveUsers.join('\n')}</textarea>
<h3>◯ Vanished/Renamed Users (${vanishedUsers.length})</h3>
<textarea readonly style="width: 100%; height: 100px; font-family: monospace;">
${vanishedUsers.join('\n')}</textarea>
</div>
`;
Line 358 ⟶ 423:
title: 'User Block & Activity Check Results',
width: 700,
height:
modal: false,
resizable: true,
Line 379 ⟶ 444:
navigator.clipboard.writeText(inactiveUsers.join('\n')).then(() => {
mw.notify('Inactive users copied to clipboard!', { type: 'success' });
}).catch(() => {
mw.notify('Failed to copy to clipboard', { type: 'error' });
});
},
'Copy Vanished/Renamed Users': function() {
navigator.clipboard.writeText(vanishedUsers.join('\n')).then(() => {
mw.notify('Vanished/Renamed users copied to clipboard!', { type: 'success' });
}).catch(() => {
mw.notify('Failed to copy to clipboard', { type: 'error' });
|